[FFmpeg-devel] [PATCH 3/9] lavf/ffm: store/restore private codec context
Michael Niedermayer
michaelni at gmx.at
Tue Nov 11 14:46:25 CET 2014
On Tue, Nov 11, 2014 at 08:31:25AM +0100, Lukasz Marek wrote:
> TODO: bump micro
>
> Signed-off-by: Lukasz Marek <lukasz.m.luki2 at 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20141111/541501b7/attachment.asc>
More information about the ffmpeg-devel
mailing list