Browse code

introduce side information for AVPacket

Signed-off-by: Luca Barbato <lu_zero@gentoo.org>

Kostya Shishkov authored on 2011/04/09 22:31:39
Showing 3 changed files
... ...
@@ -1035,6 +1035,10 @@ typedef struct AVPanScan{
1035 1035
 #define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content.
1036 1036
 #define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update).
1037 1037
 
1038
+enum AVPacketSideDataType {
1039
+    AV_PKT_DATA_PALETTE,
1040
+};
1041
+
1038 1042
 typedef struct AVPacket {
1039 1043
     /**
1040 1044
      * Presentation timestamp in AVStream->time_base units; the time at which
... ...
@@ -1057,6 +1061,17 @@ typedef struct AVPacket {
1057 1057
     int   stream_index;
1058 1058
     int   flags;
1059 1059
     /**
1060
+     * Additional packet data that can be provided by the container.
1061
+     * Packet can contain several types of side information.
1062
+     */
1063
+    struct {
1064
+        uint8_t *data;
1065
+        int      size;
1066
+        enum AVPacketSideDataType type;
1067
+    } *side_data;
1068
+    int side_data_elems;
1069
+
1070
+    /**
1060 1071
      * Duration of this packet in AVStream->time_base units, 0 if unknown.
1061 1072
      * Equals next_pts - this_pts in presentation order.
1062 1073
      */
... ...
@@ -3202,6 +3217,28 @@ int av_dup_packet(AVPacket *pkt);
3202 3202
  */
3203 3203
 void av_free_packet(AVPacket *pkt);
3204 3204
 
3205
+/**
3206
+ * Allocate new information of a packet.
3207
+ *
3208
+ * @param pkt packet
3209
+ * @param type side information type
3210
+ * @param size side information size
3211
+ * @return pointer to fresh allocated data or NULL otherwise
3212
+ */
3213
+uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
3214
+                                 int size);
3215
+
3216
+/**
3217
+ * Get side information from packet.
3218
+ *
3219
+ * @param pkt packet
3220
+ * @param type desired side information type
3221
+ * @param size pointer for side information size to store (optional)
3222
+ * @return pointer to data if present or NULL otherwise
3223
+ */
3224
+uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
3225
+                                 int *size);
3226
+
3205 3227
 /* resample.c */
3206 3228
 
3207 3229
 struct ReSampleContext;
... ...
@@ -26,12 +26,21 @@
26 26
 void av_destruct_packet_nofree(AVPacket *pkt)
27 27
 {
28 28
     pkt->data = NULL; pkt->size = 0;
29
+    pkt->side_data       = NULL;
30
+    pkt->side_data_elems = 0;
29 31
 }
30 32
 
31 33
 void av_destruct_packet(AVPacket *pkt)
32 34
 {
35
+    int i;
36
+
33 37
     av_free(pkt->data);
34 38
     pkt->data = NULL; pkt->size = 0;
39
+
40
+    for (i = 0; i < pkt->side_data_elems; i++)
41
+        av_free(pkt->side_data[i].data);
42
+    av_freep(&pkt->side_data);
43
+    pkt->side_data_elems = 0;
35 44
 }
36 45
 
37 46
 void av_init_packet(AVPacket *pkt)
... ...
@@ -44,6 +53,8 @@ void av_init_packet(AVPacket *pkt)
44 44
     pkt->flags = 0;
45 45
     pkt->stream_index = 0;
46 46
     pkt->destruct= NULL;
47
+    pkt->side_data       = NULL;
48
+    pkt->side_data_elems = 0;
47 49
 }
48 50
 
49 51
 int av_new_packet(AVPacket *pkt, int size)
... ...
@@ -89,21 +100,38 @@ int av_grow_packet(AVPacket *pkt, int grow_by)
89 89
     return 0;
90 90
 }
91 91
 
92
+#define DUP_DATA(dst, size, padding) \
93
+    do { \
94
+        void *data; \
95
+        if (padding) { \
96
+            if ((unsigned)(size) > (unsigned)(size) + FF_INPUT_BUFFER_PADDING_SIZE) \
97
+                return AVERROR(ENOMEM); \
98
+            data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); \
99
+        } else { \
100
+            data = av_malloc(size); \
101
+        } \
102
+        if (!data) \
103
+            return AVERROR(ENOMEM); \
104
+        memcpy(data, dst, size); \
105
+        if (padding) \
106
+            memset((uint8_t*)data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); \
107
+        dst = data; \
108
+    } while(0)
109
+
92 110
 int av_dup_packet(AVPacket *pkt)
93 111
 {
94 112
     if (((pkt->destruct == av_destruct_packet_nofree) || (pkt->destruct == NULL)) && pkt->data) {
95
-        uint8_t *data;
96
-        /* We duplicate the packet and don't forget to add the padding again. */
97
-        if((unsigned)pkt->size > (unsigned)pkt->size + FF_INPUT_BUFFER_PADDING_SIZE)
98
-            return AVERROR(ENOMEM);
99
-        data = av_malloc(pkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
100
-        if (!data) {
101
-            return AVERROR(ENOMEM);
102
-        }
103
-        memcpy(data, pkt->data, pkt->size);
104
-        memset(data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
105
-        pkt->data = data;
113
+        DUP_DATA(pkt->data, pkt->size, 1);
106 114
         pkt->destruct = av_destruct_packet;
115
+
116
+        if (pkt->side_data_elems) {
117
+            int i;
118
+
119
+            DUP_DATA(pkt->side_data, pkt->side_data_elems * sizeof(*pkt->side_data), 0);
120
+            for (i = 0; i < pkt->side_data_elems; i++) {
121
+                DUP_DATA(pkt->side_data[i].data, pkt->side_data[i].size, 1);
122
+            }
123
+        }
107 124
     }
108 125
     return 0;
109 126
 }
... ...
@@ -113,5 +141,46 @@ void av_free_packet(AVPacket *pkt)
113 113
     if (pkt) {
114 114
         if (pkt->destruct) pkt->destruct(pkt);
115 115
         pkt->data = NULL; pkt->size = 0;
116
+        pkt->side_data       = NULL;
117
+        pkt->side_data_elems = 0;
118
+    }
119
+}
120
+
121
+uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
122
+                                 int size)
123
+{
124
+    int elems = pkt->side_data_elems;
125
+
126
+    if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data))
127
+        return NULL;
128
+    if ((unsigned)size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
129
+        return NULL;
130
+
131
+    pkt->side_data = av_realloc(pkt->side_data, (elems + 1) * sizeof(*pkt->side_data));
132
+    if (!pkt->side_data)
133
+        return NULL;
134
+
135
+    pkt->side_data[elems].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
136
+    if (!pkt->side_data[elems].data)
137
+        return NULL;
138
+    pkt->side_data[elems].size = size;
139
+    pkt->side_data[elems].type = type;
140
+    pkt->side_data_elems++;
141
+
142
+    return pkt->side_data[elems].data;
143
+}
144
+
145
+uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
146
+                                 int *size)
147
+{
148
+    int i;
149
+
150
+    for (i = 0; i < pkt->side_data_elems; i++) {
151
+        if (pkt->side_data[i].type == type) {
152
+            if (size)
153
+                *size = pkt->side_data[i].size;
154
+            return pkt->side_data[i].data;
155
+        }
116 156
     }
157
+    return NULL;
117 158
 }
... ...
@@ -21,8 +21,8 @@
21 21
 #define AVCODEC_VERSION_H
22 22
 
23 23
 #define LIBAVCODEC_VERSION_MAJOR 52
24
-#define LIBAVCODEC_VERSION_MINOR 119
25
-#define LIBAVCODEC_VERSION_MICRO  1
24
+#define LIBAVCODEC_VERSION_MINOR 120
25
+#define LIBAVCODEC_VERSION_MICRO  0
26 26
 
27 27
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
28 28
                                                LIBAVCODEC_VERSION_MINOR, \