avformat/ffmdec: replace most codec uses by codecpar
authorMichael Niedermayer <michael@niedermayer.cc>
Fri, 2 Dec 2016 23:52:55 +0000 (00:52 +0100)
committerMichael Niedermayer <michael@niedermayer.cc>
Sat, 3 Dec 2016 13:05:15 +0000 (14:05 +0100)
This is a bit messy as codecar does not support AVOptions so we need
to use AVCodecContext where AVOptions are required and copy back and forth.

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
libavformat/ffmdec.c

index 364aac8..a8c601b 100644 (file)
@@ -248,16 +248,6 @@ static void adjust_write_index(AVFormatContext *s)
 }
 
 
-static int ffm_close(AVFormatContext *s)
-{
-    int i;
-
-    for (i = 0; i < s->nb_streams; i++)
-        av_freep(&s->streams[i]->codec->rc_eq);
-
-    return 0;
-}
-
 static int ffm_append_recommended_configuration(AVStream *st, char **conf)
 {
     int ret;
@@ -281,7 +271,7 @@ static int ffm_append_recommended_configuration(AVStream *st, char **conf)
 
 #define VALIDATE_PARAMETER(parameter, name, check) {                              \
     if (check) {                                                                  \
-        av_log(codec, AV_LOG_ERROR, "Invalid " name " %d\n", codec->parameter);   \
+        av_log(codec, AV_LOG_ERROR, "Invalid " name " %d\n", codecpar->parameter);   \
         ret = AVERROR_INVALIDDATA;                                                \
         goto fail;                                                                \
     }                                                                             \
@@ -292,9 +282,10 @@ static int ffm2_read_header(AVFormatContext *s)
     FFMContext *ffm = s->priv_data;
     AVStream *st;
     AVIOContext *pb = s->pb;
-    AVCodecContext *codec;
+    AVCodecContext *codec, *dummy_codec = NULL;
+    AVCodecParameters *codecpar;
     const AVCodecDescriptor *codec_desc;
-    int ret, i;
+    int ret;
     int f_main = 0, f_cprv = -1, f_stvi = -1, f_stau = -1;
     AVCodec *enc;
     char *buffer;
@@ -316,6 +307,7 @@ static int ffm2_read_header(AVFormatContext *s)
     } else {
         ffm->file_size = (UINT64_C(1) << 63) - 1;
     }
+    dummy_codec = avcodec_alloc_context3(NULL);
 
     while(!avio_feof(pb)) {
         unsigned id = avio_rb32(pb);
@@ -346,27 +338,28 @@ static int ffm2_read_header(AVFormatContext *s)
             avpriv_set_pts_info(st, 64, 1, 1000000);
 
             codec = st->codec;
+            codecpar = st->codecpar;
             /* generic info */
-            codec->codec_id = avio_rb32(pb);
-            codec_desc = avcodec_descriptor_get(codec->codec_id);
+            codecpar->codec_id = avio_rb32(pb);
+            codec_desc = avcodec_descriptor_get(codecpar->codec_id);
             if (!codec_desc) {
-                av_log(s, AV_LOG_ERROR, "Invalid codec id: %d\n", codec->codec_id);
-                codec->codec_id = AV_CODEC_ID_NONE;
+                av_log(s, AV_LOG_ERROR, "Invalid codec id: %d\n", codecpar->codec_id);
+                codecpar->codec_id = AV_CODEC_ID_NONE;
                 ret = AVERROR_INVALIDDATA;
                 goto fail;
             }
-            codec->codec_type = avio_r8(pb);
-            if (codec->codec_type != codec_desc->type) {
+            codecpar->codec_type = avio_r8(pb);
+            if (codecpar->codec_type != codec_desc->type) {
                 av_log(s, AV_LOG_ERROR, "Codec type mismatch: expected %d, found %d\n",
-                       codec_desc->type, codec->codec_type);
-                codec->codec_id = AV_CODEC_ID_NONE;
-                codec->codec_type = AVMEDIA_TYPE_UNKNOWN;
+                       codec_desc->type, codecpar->codec_type);
+                codecpar->codec_id = AV_CODEC_ID_NONE;
+                codecpar->codec_type = AVMEDIA_TYPE_UNKNOWN;
                 ret = AVERROR_INVALIDDATA;
                 goto fail;
             }
-            codec->bit_rate = avio_rb32(pb);
-            if (codec->bit_rate < 0) {
-                av_log(codec, AV_LOG_ERROR, "Invalid bit rate %"PRId64"\n", codec->bit_rate);
+            codecpar->bit_rate = avio_rb32(pb);
+            if (codecpar->bit_rate < 0) {
+                av_log(codec, AV_LOG_ERROR, "Invalid bit rate %"PRId64"\n", codecpar->bit_rate);
                 ret = AVERROR_INVALIDDATA;
                 goto fail;
             }
@@ -380,11 +373,11 @@ static int ffm2_read_header(AVFormatContext *s)
                     ret = AVERROR_INVALIDDATA;
                     goto fail;
                 }
-                codec->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
-                if (!codec->extradata)
+                codecpar->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
+                if (!codecpar->extradata)
                     return AVERROR(ENOMEM);
-                codec->extradata_size = size;
-                avio_read(pb, codec->extradata, size);
+                codecpar->extradata_size = size;
+                avio_read(pb, codecpar->extradata, size);
             }
             break;
         case MKBETAG('S', 'T', 'V', 'I'):
@@ -400,16 +393,16 @@ static int ffm2_read_header(AVFormatContext *s)
                 ret = AVERROR_INVALIDDATA;
                 goto fail;
             }
-            codec->width = avio_rb16(pb);
-            codec->height = avio_rb16(pb);
-            ret = av_image_check_size(codec->width, codec->height, 0, s);
+            codecpar->width = avio_rb16(pb);
+            codecpar->height = avio_rb16(pb);
+            ret = av_image_check_size(codecpar->width, codecpar->height, 0, s);
             if (ret < 0)
                 goto fail;
             avio_rb16(pb); // gop_size
-            codec->pix_fmt = avio_rb32(pb);
-            if (!av_pix_fmt_desc_get(codec->pix_fmt)) {
-                av_log(s, AV_LOG_ERROR, "Invalid pix fmt id: %d\n", codec->pix_fmt);
-                codec->pix_fmt = AV_PIX_FMT_NONE;
+            codecpar->format = avio_rb32(pb);
+            if (!av_pix_fmt_desc_get(codecpar->format)) {
+                av_log(s, AV_LOG_ERROR, "Invalid pix fmt id: %d\n", codecpar->format);
+                codecpar->format = AV_PIX_FMT_NONE;
                 goto fail;
             }
             avio_r8(pb);   // qmin
@@ -437,7 +430,7 @@ static int ffm2_read_header(AVFormatContext *s)
             avio_rb32(pb); // nsse_weight
             avio_rb32(pb); // frame_skip_cmp
             avio_rb64(pb); // rc_buffer_aggressivity
-            codec->codec_tag = avio_rb32(pb);
+            codecpar->codec_tag = avio_rb32(pb);
             avio_r8(pb);   // thread_count
             avio_rb32(pb); // coder_type
             avio_rb32(pb); // me_cmp
@@ -456,19 +449,19 @@ static int ffm2_read_header(AVFormatContext *s)
                 ret = AVERROR(EINVAL);
                 goto fail;
             }
-            codec->sample_rate = avio_rb32(pb);
-            VALIDATE_PARAMETER(sample_rate, "sample rate",        codec->sample_rate < 0)
-            codec->channels = avio_rl16(pb);
-            VALIDATE_PARAMETER(channels,    "number of channels", codec->channels < 0)
-            codec->frame_size = avio_rl16(pb);
-            VALIDATE_PARAMETER(frame_size,  "frame size",         codec->frame_size < 0)
+            codecpar->sample_rate = avio_rb32(pb);
+            VALIDATE_PARAMETER(sample_rate, "sample rate",        codecpar->sample_rate < 0)
+            codecpar->channels = avio_rl16(pb);
+            VALIDATE_PARAMETER(channels,    "number of channels", codecpar->channels < 0)
+            codecpar->frame_size = avio_rl16(pb);
+            VALIDATE_PARAMETER(frame_size,  "frame size",         codecpar->frame_size < 0)
             break;
         case MKBETAG('C', 'P', 'R', 'V'):
             if (f_cprv++) {
                 ret = AVERROR(EINVAL);
                 goto fail;
             }
-            enc = avcodec_find_encoder(codec->codec_id);
+            enc = avcodec_find_encoder(codecpar->codec_id);
             if (enc && enc->priv_data_size && enc->priv_class) {
                 buffer = av_malloc(size + 1);
                 if (!buffer) {
@@ -491,7 +484,10 @@ static int ffm2_read_header(AVFormatContext *s)
                 goto fail;
             }
             avio_get_str(pb, INT_MAX, buffer, size);
-            av_set_options_string(codec, buffer, "=", ",");
+            // The lack of AVOptions support in AVCodecParameters makes this back and forth copying needed
+            avcodec_parameters_to_context(dummy_codec, codecpar);
+            av_set_options_string(dummy_codec, buffer, "=", ",");
+            avcodec_parameters_from_context(codecpar, dummy_codec);
             if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)
                 goto fail;
             break;
@@ -506,7 +502,10 @@ static int ffm2_read_header(AVFormatContext *s)
                 goto fail;
             }
             avio_get_str(pb, INT_MAX, buffer, size);
-            av_set_options_string(codec, buffer, "=", ",");
+            // The lack of AVOptions support in AVCodecParameters makes this back and forth copying needed
+            avcodec_parameters_to_context(dummy_codec, codecpar);
+            av_set_options_string(dummy_codec, buffer, "=", ",");
+            avcodec_parameters_from_context(codecpar, dummy_codec);
             if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)
                 goto fail;
             break;
@@ -514,9 +513,6 @@ static int ffm2_read_header(AVFormatContext *s)
         avio_seek(pb, next, SEEK_SET);
     }
 
-    for (i = 0; i < s->nb_streams; i++)
-        avcodec_parameters_from_context(s->streams[i]->codecpar, s->streams[i]->codec);
-
     /* get until end of block reached */
     while ((avio_tell(pb) % ffm->packet_size) != 0 && !pb->eof_reached)
         avio_r8(pb);
@@ -528,9 +524,10 @@ static int ffm2_read_header(AVFormatContext *s)
     ffm->dts = 0;
     ffm->read_state = READ_HEADER;
     ffm->first_packet = 1;
+    avcodec_free_context(&dummy_codec);
     return 0;
  fail:
-    ffm_close(s);
+    avcodec_free_context(&dummy_codec);
     return ret;
 }
 
@@ -539,7 +536,8 @@ static int ffm_read_header(AVFormatContext *s)
     FFMContext *ffm = s->priv_data;
     AVStream *st;
     AVIOContext *pb = s->pb;
-    AVCodecContext *codec;
+    AVCodecContext *codec, *dummy_codec = NULL;
+    AVCodecParameters *codecpar;
     const AVCodecDescriptor *codec_desc;
     int i, nb_streams, ret;
     uint32_t tag;
@@ -562,6 +560,7 @@ static int ffm_read_header(AVFormatContext *s)
     } else {
         ffm->file_size = (UINT64_C(1) << 63) - 1;
     }
+    dummy_codec = avcodec_alloc_context3(NULL);
 
     nb_streams = avio_rb32(pb);
     avio_rb32(pb); /* total bitrate */
@@ -576,32 +575,33 @@ static int ffm_read_header(AVFormatContext *s)
         avpriv_set_pts_info(st, 64, 1, 1000000);
 
         codec = st->codec;
+        codecpar = st->codecpar;
         /* generic info */
-        codec->codec_id = avio_rb32(pb);
-        codec_desc = avcodec_descriptor_get(codec->codec_id);
+        codecpar->codec_id = avio_rb32(pb);
+        codec_desc = avcodec_descriptor_get(codecpar->codec_id);
         if (!codec_desc) {
-            av_log(s, AV_LOG_ERROR, "Invalid codec id: %d\n", codec->codec_id);
-            codec->codec_id = AV_CODEC_ID_NONE;
+            av_log(s, AV_LOG_ERROR, "Invalid codec id: %d\n", codecpar->codec_id);
+            codecpar->codec_id = AV_CODEC_ID_NONE;
             goto fail;
         }
-        codec->codec_type = avio_r8(pb); /* codec_type */
-        if (codec->codec_type != codec_desc->type) {
+        codecpar->codec_type = avio_r8(pb); /* codec_type */
+        if (codecpar->codec_type != codec_desc->type) {
             av_log(s, AV_LOG_ERROR, "Codec type mismatch: expected %d, found %d\n",
-                   codec_desc->type, codec->codec_type);
-            codec->codec_id = AV_CODEC_ID_NONE;
-            codec->codec_type = AVMEDIA_TYPE_UNKNOWN;
+                   codec_desc->type, codecpar->codec_type);
+            codecpar->codec_id = AV_CODEC_ID_NONE;
+            codecpar->codec_type = AVMEDIA_TYPE_UNKNOWN;
             goto fail;
         }
-        codec->bit_rate = avio_rb32(pb);
-        if (codec->bit_rate < 0) {
-            av_log(codec, AV_LOG_WARNING, "Invalid bit rate %"PRId64"\n", codec->bit_rate);
+        codecpar->bit_rate = avio_rb32(pb);
+        if (codecpar->bit_rate < 0) {
+            av_log(codec, AV_LOG_WARNING, "Invalid bit rate %"PRId64"\n", codecpar->bit_rate);
             goto fail;
         }
         codec->flags = avio_rb32(pb);
         codec->flags2 = avio_rb32(pb);
         codec->debug = avio_rb32(pb);
         /* specific info */
-        switch(codec->codec_type) {
+        switch(codecpar->codec_type) {
         case AVMEDIA_TYPE_VIDEO:
             codec->time_base.num = avio_rb32(pb);
             codec->time_base.den = avio_rb32(pb);
@@ -610,15 +610,15 @@ static int ffm_read_header(AVFormatContext *s)
                        codec->time_base.num, codec->time_base.den);
                 goto fail;
             }
-            codec->width = avio_rb16(pb);
-            codec->height = avio_rb16(pb);
-            if (av_image_check_size(codec->width, codec->height, 0, s) < 0)
+            codecpar->width = avio_rb16(pb);
+            codecpar->height = avio_rb16(pb);
+            if (av_image_check_size(codecpar->width, codecpar->height, 0, s) < 0)
                 goto fail;
             avio_rb16(pb); // gop_size
-            codec->pix_fmt = avio_rb32(pb);
-            if (!av_pix_fmt_desc_get(codec->pix_fmt)) {
-                av_log(s, AV_LOG_ERROR, "Invalid pix fmt id: %d\n", codec->pix_fmt);
-                codec->pix_fmt = AV_PIX_FMT_NONE;
+            codecpar->format = avio_rb32(pb);
+            if (!av_pix_fmt_desc_get(codecpar->format)) {
+                av_log(s, AV_LOG_ERROR, "Invalid pix fmt id: %d\n", codecpar->format);
+                codecpar->format = AV_PIX_FMT_NONE;
                 goto fail;
             }
             avio_r8(pb);   // qmin
@@ -646,7 +646,7 @@ static int ffm_read_header(AVFormatContext *s)
             avio_rb32(pb); // nsse_weight
             avio_rb32(pb); // frame_skip_cmp
             avio_rb64(pb); // rc_buffer_aggressivity
-            codec->codec_tag = avio_rb32(pb);
+            codecpar->codec_tag = avio_rb32(pb);
             avio_r8(pb);   // thread_count
             avio_rb32(pb); // coder_type
             avio_rb32(pb); // me_cmp
@@ -661,12 +661,12 @@ static int ffm_read_header(AVFormatContext *s)
             avio_rb32(pb); // refs
             break;
         case AVMEDIA_TYPE_AUDIO:
-            codec->sample_rate = avio_rb32(pb);
-            VALIDATE_PARAMETER(sample_rate, "sample rate",        codec->sample_rate < 0)
-            codec->channels = avio_rl16(pb);
-            VALIDATE_PARAMETER(channels,    "number of channels", codec->channels < 0)
-            codec->frame_size = avio_rl16(pb);
-            VALIDATE_PARAMETER(frame_size,  "frame size",         codec->frame_size < 0)
+            codecpar->sample_rate = avio_rb32(pb);
+            VALIDATE_PARAMETER(sample_rate, "sample rate",        codecpar->sample_rate < 0)
+            codecpar->channels = avio_rl16(pb);
+            VALIDATE_PARAMETER(channels,    "number of channels", codecpar->channels < 0)
+            codecpar->frame_size = avio_rl16(pb);
+            VALIDATE_PARAMETER(frame_size,  "frame size",         codecpar->frame_size < 0)
             break;
         default:
             goto fail;
@@ -677,14 +677,12 @@ static int ffm_read_header(AVFormatContext *s)
                 av_log(s, AV_LOG_ERROR, "Invalid extradata size %d\n", size);
                 goto fail;
             }
-            codec->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
-            if (!codec->extradata)
+            codecpar->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
+            if (!codecpar->extradata)
                 return AVERROR(ENOMEM);
-            codec->extradata_size = size;
-            avio_read(pb, codec->extradata, size);
+            codecpar->extradata_size = size;
+            avio_read(pb, codecpar->extradata, size);
         }
-
-        avcodec_parameters_from_context(st->codecpar, codec);
     }
 
     /* get until end of block reached */
@@ -698,9 +696,10 @@ static int ffm_read_header(AVFormatContext *s)
     ffm->dts = 0;
     ffm->read_state = READ_HEADER;
     ffm->first_packet = 1;
+    avcodec_free_context(&dummy_codec);
     return 0;
  fail:
-    ffm_close(s);
+    avcodec_free_context(&dummy_codec);
     return -1;
 }
 
@@ -858,7 +857,6 @@ AVInputFormat ff_ffm_demuxer = {
     .read_probe     = ffm_probe,
     .read_header    = ffm_read_header,
     .read_packet    = ffm_read_packet,
-    .read_close     = ffm_close,
     .read_seek      = ffm_seek,
     .priv_class     = &ffm_class,
 };