Skip to content

Commit 6690d4c

Browse files
author
Lukasz Marek
committed
lavf/ffm: store/restore private codec context
Signed-off-by: Lukasz Marek <lukasz.m.luki2@gmail.com>
1 parent bee5844 commit 6690d4c

File tree

6 files changed

+79
-9
lines changed

6 files changed

+79
-9
lines changed

doc/APIchanges

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ libavutil: 2014-08-09
1515

1616
API changes, most recent first:
1717

18+
2014-11-16 - xxxxxxx - lavf 56.13.0 - avformat.h
19+
Add AVStream.recommended_encoder_configuration with accessors.
20+
1821
2014-11-16 - xxxxxxx - lavu 54.13.0 - opt.h
1922
Add av_opt_serialize().
2023

libavformat/avformat.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,11 +1097,19 @@ typedef struct AVStream {
10971097
*/
10981098
int inject_global_side_data;
10991099

1100+
/**
1101+
* String containing paris of key and values describing recommended encoder configuration.
1102+
* Paris are separated by ','.
1103+
* Keys are separated from values by '='.
1104+
*/
1105+
char *recommended_encoder_configuration;
11001106
} AVStream;
11011107

11021108
AVRational av_stream_get_r_frame_rate(const AVStream *s);
11031109
void av_stream_set_r_frame_rate(AVStream *s, AVRational r);
11041110
struct AVCodecParserContext *av_stream_get_parser(const AVStream *s);
1111+
char* av_stream_get_recommended_encoder_configuration(const AVStream *s);
1112+
void av_stream_set_recommended_encoder_configuration(AVStream *s, char *configuration);
11051113

11061114
/**
11071115
* Returns the pts of the last muxed packet + its duration

libavformat/ffmdec.c

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "libavutil/intreadwrite.h"
2525
#include "libavutil/intfloat.h"
26+
#include "libavutil/opt.h"
2627
#include "avformat.h"
2728
#include "internal.h"
2829
#include "ffm.h"
@@ -237,6 +238,8 @@ static int ffm2_read_header(AVFormatContext *s)
237238
AVIOContext *pb = s->pb;
238239
AVCodecContext *codec;
239240
int ret;
241+
int f_main = 0, f_cprv, f_stvi, f_stau;
242+
AVCodec *enc;
240243

241244
ffm->packet_size = avio_rb32(pb);
242245
if (ffm->packet_size != FFM_PACKET_SIZE) {
@@ -267,10 +270,15 @@ static int ffm2_read_header(AVFormatContext *s)
267270

268271
switch(id) {
269272
case MKBETAG('M', 'A', 'I', 'N'):
273+
if (f_main++) {
274+
ret = AVERROR(EINVAL);
275+
goto fail;
276+
}
270277
avio_rb32(pb); /* nb_streams */
271278
avio_rb32(pb); /* total bitrate */
272279
break;
273280
case MKBETAG('C', 'O', 'M', 'M'):
281+
f_cprv = f_stvi = f_stau = 0;
274282
st = avformat_new_stream(s, NULL);
275283
if (!st) {
276284
ret = AVERROR(ENOMEM);
@@ -291,12 +299,13 @@ static int ffm2_read_header(AVFormatContext *s)
291299
if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0)
292300
return AVERROR(ENOMEM);
293301
}
294-
avio_seek(pb, next, SEEK_SET);
295-
id = avio_rb32(pb);
296-
size = avio_rb32(pb);
297-
next = avio_tell(pb) + size;
298-
switch(id) {
302+
break;
303+
//TODO: reident
299304
case MKBETAG('S', 'T', 'V', 'I'):
305+
if (f_stvi++) {
306+
ret = AVERROR(EINVAL);
307+
goto fail;
308+
}
300309
codec->time_base.num = avio_rb32(pb);
301310
codec->time_base.den = avio_rb32(pb);
302311
codec->width = avio_rb16(pb);
@@ -343,10 +352,27 @@ static int ffm2_read_header(AVFormatContext *s)
343352
codec->refs = avio_rb32(pb);
344353
break;
345354
case MKBETAG('S', 'T', 'A', 'U'):
355+
if (f_stau++) {
356+
ret = AVERROR(EINVAL);
357+
goto fail;
358+
}
346359
codec->sample_rate = avio_rb32(pb);
347360
codec->channels = avio_rl16(pb);
348361
codec->frame_size = avio_rl16(pb);
349362
break;
363+
case MKBETAG('C', 'P', 'R', 'V'):
364+
if (f_cprv++) {
365+
ret = AVERROR(EINVAL);
366+
goto fail;
367+
}
368+
enc = avcodec_find_encoder(codec->codec_id);
369+
if (enc && enc->priv_data_size && enc->priv_class) {
370+
st->recommended_encoder_configuration = av_malloc(size + 1);
371+
if (!st->recommended_encoder_configuration) {
372+
ret = AVERROR(ENOMEM);
373+
goto fail;
374+
}
375+
avio_get_str(pb, size, st->recommended_encoder_configuration, size + 1);
350376
}
351377
break;
352378
}

libavformat/ffmenc.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "libavutil/intfloat.h"
2424
#include "libavutil/avassert.h"
2525
#include "libavutil/parseutils.h"
26+
#include "libavutil/opt.h"
2627
#include "avformat.h"
2728
#include "internal.h"
2829
#include "ffm.h"
@@ -93,17 +94,43 @@ static void write_header_chunk(AVIOContext *pb, AVIOContext *dpb, unsigned id)
9394
av_free(dyn_buf);
9495
}
9596

97+
static int ffm_write_header_codec_private_ctx(AVIOContext *pb, AVCodecContext *ctx, int type)
98+
{
99+
AVIOContext *tmp;
100+
char *buf = NULL;
101+
int ret;
102+
const AVCodec *enc = ctx->codec ? ctx->codec : avcodec_find_encoder(ctx->codec_id);
103+
104+
if (!enc)
105+
return AVERROR(EINVAL);
106+
if (ctx->priv_data && enc->priv_class && enc->priv_data_size) {
107+
if ((ret = av_opt_serialize(ctx->priv_data, AV_OPT_FLAG_ENCODING_PARAM | type,
108+
AV_OPT_SERIALIZE_SKIP_DEFAULTS, &buf, '=', ',')) < 0)
109+
return ret;
110+
if (buf && strlen(buf)) {
111+
if (avio_open_dyn_buf(&tmp) < 0) {
112+
av_free(buf);
113+
return AVERROR(ENOMEM);
114+
}
115+
avio_put_str(tmp, buf);
116+
write_header_chunk(pb, tmp, MKBETAG('C', 'P', 'R', 'V'));
117+
}
118+
av_free(buf);
119+
}
120+
return 0;
121+
}
122+
96123
static int ffm_write_header(AVFormatContext *s)
97124
{
98125
FFMContext *ffm = s->priv_data;
99126
AVDictionaryEntry *t;
100127
AVStream *st;
101128
AVIOContext *pb = s->pb;
102129
AVCodecContext *codec;
103-
int bit_rate, i;
130+
int bit_rate, i, ret;
104131

105132
if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) {
106-
int ret = av_parse_time(&ffm->start_time, t->value, 0);
133+
ret = av_parse_time(&ffm->start_time, t->value, 0);
107134
if (ret < 0)
108135
return ret;
109136
}
@@ -197,12 +224,16 @@ static int ffm_write_header(AVFormatContext *s)
197224
avio_wb32(pb, codec->max_qdiff);
198225
avio_wb32(pb, codec->refs);
199226
write_header_chunk(s->pb, pb, MKBETAG('S', 'T', 'V', 'I'));
227+
if ((ret = ffm_write_header_codec_private_ctx(s->pb, codec, AV_OPT_FLAG_VIDEO_PARAM)) < 0)
228+
return ret;
200229
break;
201230
case AVMEDIA_TYPE_AUDIO:
202231
avio_wb32(pb, codec->sample_rate);
203232
avio_wl16(pb, codec->channels);
204233
avio_wl16(pb, codec->frame_size);
205234
write_header_chunk(s->pb, pb, MKBETAG('S', 'T', 'A', 'U'));
235+
if ((ret = ffm_write_header_codec_private_ctx(s->pb, codec, AV_OPT_FLAG_AUDIO_PARAM)) < 0)
236+
return ret;
206237
break;
207238
default:
208239
return -1;

libavformat/utils.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ static int64_t wrap_timestamp(AVStream *st, int64_t timestamp)
103103
}
104104

105105
MAKE_ACCESSORS(AVStream, stream, AVRational, r_frame_rate)
106+
MAKE_ACCESSORS(AVStream, stream, char *, recommended_encoder_configuration)
106107
MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, video_codec)
107108
MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, audio_codec)
108109
MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, subtitle_codec)
@@ -3537,6 +3538,7 @@ void ff_free_stream(AVFormatContext *s, AVStream *st) {
35373538
if (st->info)
35383539
av_freep(&st->info->duration_error);
35393540
av_freep(&st->info);
3541+
av_freep(&st->recommended_encoder_configuration);
35403542
av_freep(&s->streams[ --s->nb_streams ]);
35413543
}
35423544

libavformat/version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
#include "libavutil/version.h"
3131

3232
#define LIBAVFORMAT_VERSION_MAJOR 56
33-
#define LIBAVFORMAT_VERSION_MINOR 12
34-
#define LIBAVFORMAT_VERSION_MICRO 103
33+
#define LIBAVFORMAT_VERSION_MINOR 13
34+
#define LIBAVFORMAT_VERSION_MICRO 100
3535

3636
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
3737
LIBAVFORMAT_VERSION_MINOR, \

0 commit comments

Comments
 (0)