]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/avpacket.c
Merge commit '6151e9128ce2a84a443c82b78f5b5cb364ba2ab4'
[ffmpeg] / libavcodec / avpacket.c
index 4bf830bb8a5daaf55ceade1fd50ab8e92cdea42a..a04cdaf5304e8f20a3f18dcb889c2b5906794943 100644 (file)
@@ -296,9 +296,20 @@ int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
                             uint8_t *data, size_t size)
 {
     AVPacketSideData *tmp;
-    int elems = pkt->side_data_elems;
+    int i, elems = pkt->side_data_elems;
 
-    if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data))
+    for (i = 0; i < elems; i++) {
+        AVPacketSideData *sd = &pkt->side_data[i];
+
+        if (sd->type == type) {
+            av_free(sd->data);
+            sd->data = data;
+            sd->size = size;
+            return 0;
+        }
+    }
+
+    if ((unsigned)elems + 1 > AV_PKT_DATA_NB)
         return AVERROR(ERANGE);
 
     tmp = av_realloc(pkt->side_data, (elems + 1) * sizeof(*tmp));
@@ -437,6 +448,9 @@ int av_packet_split_side_data(AVPacket *pkt){
             p-= size+5;
         }
 
+        if (i > AV_PKT_DATA_NB)
+            return AVERROR(ERANGE);
+
         pkt->side_data = av_malloc_array(i, sizeof(*pkt->side_data));
         if (!pkt->side_data)
             return AVERROR(ENOMEM);
@@ -462,7 +476,32 @@ int av_packet_split_side_data(AVPacket *pkt){
     }
     return 0;
 }
+#endif
 
+#if FF_API_MERGE_SD
+int ff_packet_split_and_drop_side_data(AVPacket *pkt){
+    if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
+        int i;
+        unsigned int size;
+        uint8_t *p;
+
+        p = pkt->data + pkt->size - 8 - 5;
+        for (i=1; ; i++){
+            size = AV_RB32(p);
+            if (size>INT_MAX - 5 || p - pkt->data < size)
+                return 0;
+            if (p[4]&128)
+                break;
+            if (p - pkt->data < size + 5)
+                return 0;
+            p-= size+5;
+        }
+        pkt->size = p - pkt->data - size;
+        av_assert0(pkt->size >= 0);
+        return 1;
+    }
+    return 0;
+}
 #endif
 
 uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size)