]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/asfdec.c
rtspenc: Check the return value from ffio_open_dyn_packet_buf
[ffmpeg] / libavformat / asfdec.c
index 51422ea13706f9763d9286a0989cfd92421fb232..f3978f08a49e1235149e1fa342de0c665a6801d3 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define DEBUG
-
 #include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bswap.h"
 #include "libavutil/common.h"
 #include "libavutil/dict.h"
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
@@ -151,12 +151,6 @@ static void print_guid(ff_asf_guid *g)
 #define print_guid(g)
 #endif
 
-void ff_get_guid(AVIOContext *s, ff_asf_guid *g)
-{
-    assert(sizeof(*g) == 16);
-    avio_read(s, *g, sizeof(*g));
-}
-
 static int asf_probe(AVProbeData *pd)
 {
     /* check file header */
@@ -193,7 +187,6 @@ static int asf_read_picture(AVFormatContext *s, int len)
     enum  AVCodecID id    = AV_CODEC_ID_NONE;
     char mimetype[64];
     uint8_t  *desc = NULL;
-    ASFStream *ast = NULL;
     AVStream   *st = NULL;
     int ret, type, picsize, desc_len;
 
@@ -248,12 +241,10 @@ static int asf_read_picture(AVFormatContext *s, int len)
         goto fail;
 
     st  = avformat_new_stream(s, NULL);
-    ast = av_mallocz(sizeof(*ast));
-    if (!st || !ast) {
+    if (!st) {
         ret = AVERROR(ENOMEM);
         goto fail;
     }
-    st->priv_data                 = ast;
     st->disposition              |= AV_DISPOSITION_ATTACHED_PIC;
     st->codec->codec_type         = AVMEDIA_TYPE_VIDEO;
     st->codec->codec_id           = id;
@@ -271,12 +262,21 @@ static int asf_read_picture(AVFormatContext *s, int len)
     return 0;
 
 fail:
-    av_freep(&ast);
     av_freep(&desc);
     av_free_packet(&pkt);
     return ret;
 }
 
+static void get_id3_tag(AVFormatContext *s, int len)
+{
+    ID3v2ExtraMeta *id3v2_extra_meta = NULL;
+
+    ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
+    if (id3v2_extra_meta)
+        ff_id3v2_parse_apic(s, &id3v2_extra_meta);
+    ff_id3v2_free_extra_meta(&id3v2_extra_meta);
+}
+
 static void get_tag(AVFormatContext *s, const char *key, int type, int len, int type2_size)
 {
     char *value;
@@ -291,12 +291,18 @@ static void get_tag(AVFormatContext *s, const char *key, int type, int len, int
 
     if (type == 0) {         // UTF16-LE
         avio_get_str16le(s->pb, len, value, 2 * len + 1);
+    } else if (type == 1) {  // byte array
+        if (!strcmp(key, "WM/Picture")) { // handle cover art
+            asf_read_picture(s, len);
+        } else if (!strcmp(key, "ID3")) { // handle ID3 tag
+            get_id3_tag(s, len);
+        } else {
+            av_log(s, AV_LOG_VERBOSE, "Unsupported byte array in tag %s.\n", key);
+        }
+        goto finish;
     } else if (type > 1 && type <= 5) {  // boolean or DWORD or QWORD or WORD
         uint64_t num = get_value(s->pb, type, type2_size);
         snprintf(value, len, "%"PRIu64, num);
-    } else if (type == 1 && !strcmp(key, "WM/Picture")) { // handle cover art
-        asf_read_picture(s, len);
-        goto finish;
     } else if (type == 6) { // (don't) handle GUID
         av_log(s, AV_LOG_DEBUG, "Unsupported GUID value in tag %s.\n", key);
         goto finish;
@@ -854,7 +860,7 @@ static int asf_read_header(AVFormatContext *s)
  * @param pb context to read data from
  * @return 0 on success, <0 on error
  */
-static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
+static int asf_get_packet(AVFormatContext *s, AVIOContext *pb)
 {
     ASFContext *asf = s->priv_data;
     uint32_t packet_length, padsize;
@@ -1046,7 +1052,7 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb)
  * @return 0 if data was stored in pkt, <0 on error or 1 if more ASF
  *          packets need to be loaded (through asf_get_packet())
  */
-static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
+static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
 {
     ASFContext *asf   = s->priv_data;
     ASFStream *asf_st = 0;
@@ -1091,6 +1097,7 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
             asf->asf_st = s->streams[asf->stream_index]->priv_data;
         }
         asf_st = asf->asf_st;
+        av_assert0(asf_st);
 
         if (asf->packet_replic_size == 1) {
             // frag_offset is here used as the beginning timestamp
@@ -1218,9 +1225,10 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
                            asf_st->ds_span);
                 } else {
                     /* packet descrambling */
-                    uint8_t *newdata = av_malloc(asf_st->pkt.size +
-                                                 FF_INPUT_BUFFER_PADDING_SIZE);
-                    if (newdata) {
+                    AVBufferRef *buf = av_buffer_alloc(asf_st->pkt.size +
+                                                       FF_INPUT_BUFFER_PADDING_SIZE);
+                    if (buf) {
+                        uint8_t *newdata = buf->data;
                         int offset = 0;
                         memset(newdata + asf_st->pkt.size, 0,
                                FF_INPUT_BUFFER_PADDING_SIZE);
@@ -1236,13 +1244,20 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
                                    asf_st->ds_chunk_size);
                             offset += asf_st->ds_chunk_size;
                         }
-                        av_free(asf_st->pkt.data);
-                        asf_st->pkt.data = newdata;
+                        av_buffer_unref(&asf_st->pkt.buf);
+                        asf_st->pkt.buf  = buf;
+                        asf_st->pkt.data = buf->data;
                     }
                 }
             }
             asf_st->frag_offset         = 0;
             *pkt                        = asf_st->pkt;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+            asf_st->pkt.destruct        = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+            asf_st->pkt.buf             = 0;
             asf_st->pkt.size            = 0;
             asf_st->pkt.data            = 0;
             asf_st->pkt.side_data_elems = 0;
@@ -1261,9 +1276,9 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
         int ret;
 
         /* parse cached packets, if any */
-        if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0)
+        if ((ret = asf_parse_packet(s, s->pb, pkt)) <= 0)
             return ret;
-        if ((ret = ff_asf_get_packet(s, s->pb)) < 0)
+        if ((ret = asf_get_packet(s, s->pb)) < 0)
             assert(asf->packet_size_left < FRAME_HEADER_SIZE ||
                    asf->packet_segments < 1);
         asf->packet_time_start = 0;
@@ -1300,6 +1315,8 @@ static void asf_reset_header(AVFormatContext *s)
 
     for (i = 0; i < s->nb_streams; i++) {
         asf_st = s->streams[i]->priv_data;
+        if (!asf_st)
+            continue;
         av_free_packet(&asf_st->pkt);
         asf_st->frag_offset = 0;
         asf_st->seq         = 0;
@@ -1348,6 +1365,7 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index,
             i = pkt->stream_index;
 
             asf_st = s->streams[i]->priv_data;
+            av_assert0(asf_st);
 
 //            assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0);
             pos = asf_st->packet_pos;