mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
lavf/ffm: store/restore private codec context
Signed-off-by: Lukasz Marek <lukasz.m.luki2@gmail.com>
This commit is contained in:
parent
bee5844ddd
commit
6690d4c3f5
@ -15,6 +15,9 @@ libavutil: 2014-08-09
|
||||
|
||||
API changes, most recent first:
|
||||
|
||||
2014-11-16 - xxxxxxx - lavf 56.13.0 - avformat.h
|
||||
Add AVStream.recommended_encoder_configuration with accessors.
|
||||
|
||||
2014-11-16 - xxxxxxx - lavu 54.13.0 - opt.h
|
||||
Add av_opt_serialize().
|
||||
|
||||
|
@ -1097,11 +1097,19 @@ typedef struct AVStream {
|
||||
*/
|
||||
int inject_global_side_data;
|
||||
|
||||
/**
|
||||
* String containing paris of key and values describing recommended encoder configuration.
|
||||
* Paris are separated by ','.
|
||||
* Keys are separated from values by '='.
|
||||
*/
|
||||
char *recommended_encoder_configuration;
|
||||
} AVStream;
|
||||
|
||||
AVRational av_stream_get_r_frame_rate(const AVStream *s);
|
||||
void av_stream_set_r_frame_rate(AVStream *s, AVRational r);
|
||||
struct AVCodecParserContext *av_stream_get_parser(const AVStream *s);
|
||||
char* av_stream_get_recommended_encoder_configuration(const AVStream *s);
|
||||
void av_stream_set_recommended_encoder_configuration(AVStream *s, char *configuration);
|
||||
|
||||
/**
|
||||
* Returns the pts of the last muxed packet + its duration
|
||||
|
@ -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;
|
||||
AVCodec *enc;
|
||||
|
||||
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,10 +352,27 @@ 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;
|
||||
}
|
||||
enc = avcodec_find_encoder(codec->codec_id);
|
||||
if (enc && enc->priv_data_size && enc->priv_class) {
|
||||
st->recommended_encoder_configuration = av_malloc(size + 1);
|
||||
if (!st->recommended_encoder_configuration) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
avio_get_str(pb, size, st->recommended_encoder_configuration, size + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -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,32 @@ 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, AVCodecContext *ctx, int type)
|
||||
{
|
||||
AVIOContext *tmp;
|
||||
char *buf = NULL;
|
||||
int ret;
|
||||
const AVCodec *enc = ctx->codec ? ctx->codec : avcodec_find_encoder(ctx->codec_id);
|
||||
|
||||
if (!enc)
|
||||
return AVERROR(EINVAL);
|
||||
if (ctx->priv_data && enc->priv_class && enc->priv_data_size) {
|
||||
if ((ret = av_opt_serialize(ctx->priv_data, AV_OPT_FLAG_ENCODING_PARAM | type,
|
||||
AV_OPT_SERIALIZE_SKIP_DEFAULTS, &buf, '=', ',')) < 0)
|
||||
return ret;
|
||||
if (buf && strlen(buf)) {
|
||||
if (avio_open_dyn_buf(&tmp) < 0) {
|
||||
av_free(buf);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
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 +127,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 +224,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, 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, AV_OPT_FLAG_AUDIO_PARAM)) < 0)
|
||||
return ret;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
|
@ -103,6 +103,7 @@ static int64_t wrap_timestamp(AVStream *st, int64_t timestamp)
|
||||
}
|
||||
|
||||
MAKE_ACCESSORS(AVStream, stream, AVRational, r_frame_rate)
|
||||
MAKE_ACCESSORS(AVStream, stream, char *, recommended_encoder_configuration)
|
||||
MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, video_codec)
|
||||
MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, audio_codec)
|
||||
MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, subtitle_codec)
|
||||
@ -3537,6 +3538,7 @@ void ff_free_stream(AVFormatContext *s, AVStream *st) {
|
||||
if (st->info)
|
||||
av_freep(&st->info->duration_error);
|
||||
av_freep(&st->info);
|
||||
av_freep(&st->recommended_encoder_configuration);
|
||||
av_freep(&s->streams[ --s->nb_streams ]);
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,8 @@
|
||||
#include "libavutil/version.h"
|
||||
|
||||
#define LIBAVFORMAT_VERSION_MAJOR 56
|
||||
#define LIBAVFORMAT_VERSION_MINOR 12
|
||||
#define LIBAVFORMAT_VERSION_MICRO 103
|
||||
#define LIBAVFORMAT_VERSION_MINOR 13
|
||||
#define LIBAVFORMAT_VERSION_MICRO 100
|
||||
|
||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||
LIBAVFORMAT_VERSION_MINOR, \
|
||||
|
Loading…
Reference in New Issue
Block a user