On Tue, Nov 11, 2014 at 08:31:25AM +0100, Lukasz Marek wrote: > TODO: bump micro > > Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com> > --- > libavformat/ffmdec.c | 41 ++++++++++++++++++++++++++++++++++++----- > libavformat/ffmenc.c | 27 +++++++++++++++++++++++++-- > 2 files changed, 61 insertions(+), 7 deletions(-) > > diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c > index 448762b..bba3b36 100644 > --- a/libavformat/ffmdec.c > +++ b/libavformat/ffmdec.c > @@ -23,6 +23,7 @@ > > #include "libavutil/intreadwrite.h" > #include "libavutil/intfloat.h" > +#include "libavutil/opt.h" > #include "avformat.h" > #include "internal.h" > #include "ffm.h" > @@ -237,6 +238,8 @@ static int ffm2_read_header(AVFormatContext *s) > AVIOContext *pb = s->pb; > AVCodecContext *codec; > int ret; > + int f_main = 0, f_cprv, f_stvi, f_stau; > + char *buffer; > > ffm->packet_size = avio_rb32(pb); > if (ffm->packet_size != FFM_PACKET_SIZE) { > @@ -267,10 +270,15 @@ static int ffm2_read_header(AVFormatContext *s) > > switch(id) { > case MKBETAG('M', 'A', 'I', 'N'): > + if (f_main++) { > + ret = AVERROR(EINVAL); > + goto fail; > + } > avio_rb32(pb); /* nb_streams */ > avio_rb32(pb); /* total bitrate */ > break; > case MKBETAG('C', 'O', 'M', 'M'): > + f_cprv = f_stvi = f_stau = 0; > st = avformat_new_stream(s, NULL); > if (!st) { > ret = AVERROR(ENOMEM); > @@ -291,12 +299,13 @@ static int ffm2_read_header(AVFormatContext *s) > if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0) > return AVERROR(ENOMEM); > } > - avio_seek(pb, next, SEEK_SET); > - id = avio_rb32(pb); > - size = avio_rb32(pb); > - next = avio_tell(pb) + size; > - switch(id) { > + break; > + //TODO: reident > case MKBETAG('S', 'T', 'V', 'I'): > + if (f_stvi++) { > + ret = AVERROR(EINVAL); > + goto fail; > + } > codec->time_base.num = avio_rb32(pb); > codec->time_base.den = avio_rb32(pb); > codec->width = avio_rb16(pb); > @@ -343,11 +352,33 @@ static int ffm2_read_header(AVFormatContext *s) > codec->refs = avio_rb32(pb); > break; > case MKBETAG('S', 'T', 'A', 'U'): > + if (f_stau++) { > + ret = AVERROR(EINVAL); > + goto fail; > + } > codec->sample_rate = avio_rb32(pb); > codec->channels = avio_rl16(pb); > codec->frame_size = avio_rl16(pb); > break; > + case MKBETAG('C', 'P', 'R', 'V'): > + if (f_cprv++) { > + ret = AVERROR(EINVAL); > + goto fail; > + } > + codec->codec = avcodec_find_encoder(codec->codec_id); > + buffer = av_malloc(size + 1); > + codec->priv_data = av_mallocz(codec->codec->priv_data_size); > + if (!buffer || !codec->priv_data) { > + av_free(buffer); > + av_freep(&codec->priv_data); > + ret = AVERROR(ENOMEM); > + goto fail; > } > + *(const AVClass**)codec->priv_data = codec->codec->priv_class; > + av_opt_set_defaults(codec->priv_data); > + avio_get_str(pb, size, buffer, size + 1); > + av_set_options_string(codec->priv_data, buffer, "=", ","); > + av_freep(&buffer); > break; > } > avio_seek(pb, next, SEEK_SET); > diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c > index eb809eb..f307f8f 100644 > --- a/libavformat/ffmenc.c > +++ b/libavformat/ffmenc.c > @@ -23,6 +23,7 @@ > #include "libavutil/intfloat.h" > #include "libavutil/avassert.h" > #include "libavutil/parseutils.h" > +#include "libavutil/opt.h" > #include "avformat.h" > #include "internal.h" > #include "ffm.h" > @@ -93,6 +94,24 @@ static void write_header_chunk(AVIOContext *pb, > AVIOContext *dpb, unsigned id) > av_free(dyn_buf); > } > > +static int ffm_write_header_codec_private_ctx(AVIOContext *pb, void > *priv_data, int type) > +{ > + AVIOContext *tmp; > + char *buf = NULL; > + > + if (priv_data) { > + if (avio_open_dyn_buf(&tmp) < 0) > + return AVERROR(ENOMEM); > + av_opt_serialize(priv_data, AV_OPT_FLAG_ENCODING_PARAM | type, 1, > &buf, '=', ','); > + if (buf && strlen(buf)) { > + avio_put_str(tmp, buf); > + write_header_chunk(pb, tmp, MKBETAG('C', 'P', 'R', 'V')); > + } > + av_free(buf); > + } > + return 0; > +} > + > static int ffm_write_header(AVFormatContext *s) > { > FFMContext *ffm = s->priv_data; > @@ -100,10 +119,10 @@ static int ffm_write_header(AVFormatContext *s) > AVStream *st; > AVIOContext *pb = s->pb; > AVCodecContext *codec; > - int bit_rate, i; > + int bit_rate, i, ret; > > if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) { > - int ret = av_parse_time(&ffm->start_time, t->value, 0); > + ret = av_parse_time(&ffm->start_time, t->value, 0); > if (ret < 0) > return ret; > } > @@ -197,12 +216,16 @@ static int ffm_write_header(AVFormatContext *s) > avio_wb32(pb, codec->max_qdiff); > avio_wb32(pb, codec->refs); > write_header_chunk(s->pb, pb, MKBETAG('S', 'T', 'V', 'I')); > + if ((ret = ffm_write_header_codec_private_ctx(s->pb, > codec->priv_data, AV_OPT_FLAG_VIDEO_PARAM)) < 0) > + return ret; > break; > case AVMEDIA_TYPE_AUDIO: > avio_wb32(pb, codec->sample_rate); > avio_wl16(pb, codec->channels); > avio_wl16(pb, codec->frame_size); > write_header_chunk(s->pb, pb, MKBETAG('S', 'T', 'A', 'U')); > + if ((ret = ffm_write_header_codec_private_ctx(s->pb, > codec->priv_data, AV_OPT_FLAG_AUDIO_PARAM)) < 0) > + return ret;
the muxer might run in a seperate thread from the encoder, priv_data could change while its being accessed, iam not sure if that would cause some race here or not Also i dont think its guranteed that priv_data starts with a AVClass [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Those who are too smart to engage in politics are punished by being governed by those who are dumber. -- Plato
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel