[FFmpeg-devel] [PATCH 3/9] lavf/ffm: store/restore private codec context
Lukasz Marek
lukasz.m.luki2 at gmail.com
Tue Nov 11 08:31:25 CET 2014
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;
break;
default:
return -1;
--
1.9.1
More information about the ffmpeg-devel
mailing list