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 <mich...@niedermayer.cc> --- libavformat/ffmdec.c | 159 ++++++++++++++++++++++++++------------------------- 1 file changed, 82 insertions(+), 77 deletions(-) diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c index 9192bff507..25edeebb7e 100644 --- a/libavformat/ffmdec.c +++ b/libavformat/ffmdec.c @@ -250,11 +250,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; } @@ -281,7 +276,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,7 +287,8 @@ 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 f_main = 0, f_cprv = -1, f_stvi = -1, f_stau = -1; @@ -316,6 +312,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 +343,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 +378,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 +398,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); - 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); @@ -437,7 +435,7 @@ static int ffm2_read_header(AVFormatContext *s) avio_rb32(pb); avio_rb32(pb); avio_rb64(pb); - codec->codec_tag = avio_rb32(pb); + codecpar->codec_tag = avio_rb32(pb); avio_r8(pb); avio_rb32(pb); avio_rb32(pb); @@ -456,19 +454,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 +489,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 +507,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 +518,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,8 +529,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: + avcodec_free_context(&dummy_codec); ffm_close(s); return ret; } @@ -539,7 +542,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 +566,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 */ @@ -577,31 +582,31 @@ static int ffm_read_header(AVFormatContext *s) codec = st->codec; /* 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 +615,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); - 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); @@ -646,7 +651,7 @@ static int ffm_read_header(AVFormatContext *s) avio_rb32(pb); avio_rb32(pb); avio_rb64(pb); - codec->codec_tag = avio_rb32(pb); + codecpar->codec_tag = avio_rb32(pb); avio_r8(pb); avio_rb32(pb); avio_rb32(pb); @@ -661,12 +666,12 @@ static int ffm_read_header(AVFormatContext *s) avio_rb32(pb); 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 +682,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,8 +701,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: + avcodec_free_context(&dummy_codec); ffm_close(s); return -1; } -- 2.11.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel