Commit 4de339e2 authored by Kostya Shishkov's avatar Kostya Shishkov Committed by Luca Barbato

introduce side information for AVPacket

Signed-off-by: 's avatarLuca Barbato <lu_zero@gentoo.org>
parent 4d012eb5
...@@ -1035,6 +1035,10 @@ typedef struct AVPanScan{ ...@@ -1035,6 +1035,10 @@ typedef struct AVPanScan{
#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content. #define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content.
#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update). #define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update).
enum AVPacketSideDataType {
AV_PKT_DATA_PALETTE,
};
typedef struct AVPacket { typedef struct AVPacket {
/** /**
* Presentation timestamp in AVStream->time_base units; the time at which * Presentation timestamp in AVStream->time_base units; the time at which
...@@ -1056,6 +1060,17 @@ typedef struct AVPacket { ...@@ -1056,6 +1060,17 @@ typedef struct AVPacket {
int size; int size;
int stream_index; int stream_index;
int flags; int flags;
/**
* Additional packet data that can be provided by the container.
* Packet can contain several types of side information.
*/
struct {
uint8_t *data;
int size;
enum AVPacketSideDataType type;
} *side_data;
int side_data_elems;
/** /**
* Duration of this packet in AVStream->time_base units, 0 if unknown. * Duration of this packet in AVStream->time_base units, 0 if unknown.
* Equals next_pts - this_pts in presentation order. * Equals next_pts - this_pts in presentation order.
...@@ -3202,6 +3217,28 @@ int av_dup_packet(AVPacket *pkt); ...@@ -3202,6 +3217,28 @@ int av_dup_packet(AVPacket *pkt);
*/ */
void av_free_packet(AVPacket *pkt); void av_free_packet(AVPacket *pkt);
/**
* Allocate new information of a packet.
*
* @param pkt packet
* @param type side information type
* @param size side information size
* @return pointer to fresh allocated data or NULL otherwise
*/
uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
int size);
/**
* Get side information from packet.
*
* @param pkt packet
* @param type desired side information type
* @param size pointer for side information size to store (optional)
* @return pointer to data if present or NULL otherwise
*/
uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
int *size);
/* resample.c */ /* resample.c */
struct ReSampleContext; struct ReSampleContext;
......
...@@ -26,12 +26,21 @@ ...@@ -26,12 +26,21 @@
void av_destruct_packet_nofree(AVPacket *pkt) void av_destruct_packet_nofree(AVPacket *pkt)
{ {
pkt->data = NULL; pkt->size = 0; pkt->data = NULL; pkt->size = 0;
pkt->side_data = NULL;
pkt->side_data_elems = 0;
} }
void av_destruct_packet(AVPacket *pkt) void av_destruct_packet(AVPacket *pkt)
{ {
int i;
av_free(pkt->data); av_free(pkt->data);
pkt->data = NULL; pkt->size = 0; pkt->data = NULL; pkt->size = 0;
for (i = 0; i < pkt->side_data_elems; i++)
av_free(pkt->side_data[i].data);
av_freep(&pkt->side_data);
pkt->side_data_elems = 0;
} }
void av_init_packet(AVPacket *pkt) void av_init_packet(AVPacket *pkt)
...@@ -44,6 +53,8 @@ void av_init_packet(AVPacket *pkt) ...@@ -44,6 +53,8 @@ void av_init_packet(AVPacket *pkt)
pkt->flags = 0; pkt->flags = 0;
pkt->stream_index = 0; pkt->stream_index = 0;
pkt->destruct= NULL; pkt->destruct= NULL;
pkt->side_data = NULL;
pkt->side_data_elems = 0;
} }
int av_new_packet(AVPacket *pkt, int size) int av_new_packet(AVPacket *pkt, int size)
...@@ -89,21 +100,38 @@ int av_grow_packet(AVPacket *pkt, int grow_by) ...@@ -89,21 +100,38 @@ int av_grow_packet(AVPacket *pkt, int grow_by)
return 0; return 0;
} }
#define DUP_DATA(dst, size, padding) \
do { \
void *data; \
if (padding) { \
if ((unsigned)(size) > (unsigned)(size) + FF_INPUT_BUFFER_PADDING_SIZE) \
return AVERROR(ENOMEM); \
data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); \
} else { \
data = av_malloc(size); \
} \
if (!data) \
return AVERROR(ENOMEM); \
memcpy(data, dst, size); \
if (padding) \
memset((uint8_t*)data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); \
dst = data; \
} while(0)
int av_dup_packet(AVPacket *pkt) int av_dup_packet(AVPacket *pkt)
{ {
if (((pkt->destruct == av_destruct_packet_nofree) || (pkt->destruct == NULL)) && pkt->data) { if (((pkt->destruct == av_destruct_packet_nofree) || (pkt->destruct == NULL)) && pkt->data) {
uint8_t *data; DUP_DATA(pkt->data, pkt->size, 1);
/* We duplicate the packet and don't forget to add the padding again. */
if((unsigned)pkt->size > (unsigned)pkt->size + FF_INPUT_BUFFER_PADDING_SIZE)
return AVERROR(ENOMEM);
data = av_malloc(pkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!data) {
return AVERROR(ENOMEM);
}
memcpy(data, pkt->data, pkt->size);
memset(data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
pkt->data = data;
pkt->destruct = av_destruct_packet; pkt->destruct = av_destruct_packet;
if (pkt->side_data_elems) {
int i;
DUP_DATA(pkt->side_data, pkt->side_data_elems * sizeof(*pkt->side_data), 0);
for (i = 0; i < pkt->side_data_elems; i++) {
DUP_DATA(pkt->side_data[i].data, pkt->side_data[i].size, 1);
}
}
} }
return 0; return 0;
} }
...@@ -113,5 +141,46 @@ void av_free_packet(AVPacket *pkt) ...@@ -113,5 +141,46 @@ void av_free_packet(AVPacket *pkt)
if (pkt) { if (pkt) {
if (pkt->destruct) pkt->destruct(pkt); if (pkt->destruct) pkt->destruct(pkt);
pkt->data = NULL; pkt->size = 0; pkt->data = NULL; pkt->size = 0;
pkt->side_data = NULL;
pkt->side_data_elems = 0;
}
}
uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
int size)
{
int elems = pkt->side_data_elems;
if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data))
return NULL;
if ((unsigned)size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
return NULL;
pkt->side_data = av_realloc(pkt->side_data, (elems + 1) * sizeof(*pkt->side_data));
if (!pkt->side_data)
return NULL;
pkt->side_data[elems].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!pkt->side_data[elems].data)
return NULL;
pkt->side_data[elems].size = size;
pkt->side_data[elems].type = type;
pkt->side_data_elems++;
return pkt->side_data[elems].data;
}
uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
int *size)
{
int i;
for (i = 0; i < pkt->side_data_elems; i++) {
if (pkt->side_data[i].type == type) {
if (size)
*size = pkt->side_data[i].size;
return pkt->side_data[i].data;
}
} }
return NULL;
} }
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
#define AVCODEC_VERSION_H #define AVCODEC_VERSION_H
#define LIBAVCODEC_VERSION_MAJOR 52 #define LIBAVCODEC_VERSION_MAJOR 52
#define LIBAVCODEC_VERSION_MINOR 119 #define LIBAVCODEC_VERSION_MINOR 120
#define LIBAVCODEC_VERSION_MICRO 1 #define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \ LIBAVCODEC_VERSION_MINOR, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment