ffmpeg_opt: use codec private context in ffserver streams
Signed-off-by: Lukasz Marek <lukasz.m.luki2@gmail.com>
This commit is contained in:
parent
6690d4c3f5
commit
2657f00d3f
48
ffmpeg_opt.c
48
ffmpeg_opt.c
@ -1617,6 +1617,31 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ffserver_streams_copy_context(AVCodecContext *dest, const AVCodecContext *src,
|
||||
const char *configuration)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = avcodec_copy_context(dest, src)) < 0)
|
||||
return ret;
|
||||
dest->codec = avcodec_find_encoder(src->codec_id);
|
||||
if (!dest->codec)
|
||||
return AVERROR(EINVAL);
|
||||
if (!dest->codec->priv_class || !dest->codec->priv_data_size)
|
||||
return 0;
|
||||
if (!dest->priv_data) {
|
||||
dest->priv_data = av_mallocz(dest->codec->priv_data_size);
|
||||
if (!dest->priv_data)
|
||||
return AVERROR(ENOMEM);
|
||||
*(const AVClass**)dest->priv_data = dest->codec->priv_class;
|
||||
}
|
||||
av_opt_set_defaults(dest->priv_data);
|
||||
if (av_set_options_string(dest->priv_data, configuration, "=", ",") < 0) {
|
||||
av_log(dest, AV_LOG_WARNING, "Cannot copy private codec options. Using defaults.\n");
|
||||
av_opt_set_defaults(dest->priv_data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
|
||||
{
|
||||
int i, err;
|
||||
@ -1631,35 +1656,28 @@ static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch
|
||||
AVStream *st;
|
||||
OutputStream *ost;
|
||||
AVCodec *codec;
|
||||
AVCodecContext *avctx;
|
||||
|
||||
codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
|
||||
if (!codec) {
|
||||
av_log(s, AV_LOG_ERROR, "no encoder found for codec id %i\n", ic->streams[i]->codec->codec_id);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (codec->type == AVMEDIA_TYPE_AUDIO)
|
||||
opt_audio_codec(o, "c:a", codec->name);
|
||||
else if (codec->type == AVMEDIA_TYPE_VIDEO)
|
||||
opt_video_codec(o, "c:v", codec->name);
|
||||
ost = new_output_stream(o, s, codec->type, -1);
|
||||
st = ost->st;
|
||||
avctx = st->codec;
|
||||
ost->enc = codec;
|
||||
|
||||
// FIXME: a more elegant solution is needed
|
||||
memcpy(st, ic->streams[i], sizeof(AVStream));
|
||||
st->cur_dts = 0;
|
||||
st->info = av_malloc(sizeof(*st->info));
|
||||
memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
|
||||
st->codec= avctx;
|
||||
avcodec_copy_context(st->codec, ic->streams[i]->codec);
|
||||
ffserver_streams_copy_context(st->codec, ic->streams[i]->codec,
|
||||
av_stream_get_recommended_encoder_configuration(ic->streams[i]));
|
||||
|
||||
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !ost->stream_copy)
|
||||
choose_sample_fmt(st, codec);
|
||||
else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !ost->stream_copy)
|
||||
choose_pixel_fmt(st, st->codec, codec, st->codec->pix_fmt);
|
||||
avcodec_copy_context(ost->enc_ctx, st->codec);
|
||||
if (ost->enc_ctx->priv_data) {
|
||||
av_opt_free(ost->enc_ctx->priv_data);
|
||||
av_freep(&ost->enc_ctx->priv_data);
|
||||
}
|
||||
ffserver_streams_copy_context(ost->enc_ctx, st->codec,
|
||||
av_stream_get_recommended_encoder_configuration(ic->streams[i]));
|
||||
}
|
||||
|
||||
avformat_close_input(&ic);
|
||||
|
Loading…
x
Reference in New Issue
Block a user