aboutsummaryrefslogtreecommitdiffstats
path: root/avconv.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2014-04-05 08:48:24 +0200
committerAnton Khirnov <anton@khirnov.net>2014-06-01 08:33:21 +0200
commit383136264ef40452efd86cafb2d7221cd3830b3d (patch)
tree37b714d446bfab3e11512da62d22555b6445af6e /avconv.c
parent41776ba9c0ebbb71394cefdf7dd1b243e6c852d5 (diff)
downloadffmpeg-383136264ef40452efd86cafb2d7221cd3830b3d.tar.gz
avconv: do not use the stream codec context for encoding
Diffstat (limited to 'avconv.c')
-rw-r--r--avconv.c91
1 files changed, 49 insertions, 42 deletions
diff --git a/avconv.c b/avconv.c
index 30b85cc770..b167ff662f 100644
--- a/avconv.c
+++ b/avconv.c
@@ -191,6 +191,8 @@ static void avconv_cleanup(int ret)
av_freep(&ost->avfilter);
av_freep(&ost->logfile_prefix);
+ avcodec_free_context(&ost->enc_ctx);
+
av_freep(&output_streams[i]);
}
for (i = 0; i < nb_input_files; i++) {
@@ -316,7 +318,7 @@ static void update_sample_fmt(AVCodecContext *dec, AVCodec *dec_codec,
static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
{
AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
- AVCodecContext *avctx = ost->st->codec;
+ AVCodecContext *avctx = ost->enc_ctx;
int ret;
/*
@@ -394,7 +396,7 @@ static int check_recording_time(OutputStream *ost)
OutputFile *of = output_files[ost->file_index];
if (of->recording_time != INT64_MAX &&
- av_compare_ts(ost->sync_opts - ost->first_pts, ost->st->codec->time_base, of->recording_time,
+ av_compare_ts(ost->sync_opts - ost->first_pts, ost->enc_ctx->time_base, of->recording_time,
AV_TIME_BASE_Q) >= 0) {
ost->finished = 1;
return 0;
@@ -405,7 +407,7 @@ static int check_recording_time(OutputStream *ost)
static void do_audio_out(AVFormatContext *s, OutputStream *ost,
AVFrame *frame)
{
- AVCodecContext *enc = ost->st->codec;
+ AVCodecContext *enc = ost->enc_ctx;
AVPacket pkt;
int got_packet = 0;
@@ -456,7 +458,7 @@ static void do_subtitle_out(AVFormatContext *s,
return;
}
- enc = ost->st->codec;
+ enc = ost->enc_ctx;
if (!subtitle_out) {
subtitle_out = av_malloc(subtitle_out_max_size);
@@ -513,7 +515,7 @@ static void do_video_out(AVFormatContext *s,
{
int ret, format_video_sync;
AVPacket pkt;
- AVCodecContext *enc = ost->st->codec;
+ AVCodecContext *enc = ost->enc_ctx;
*frame_size = 0;
@@ -563,11 +565,11 @@ static void do_video_out(AVFormatContext *s,
} else {
int got_packet;
- if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME) &&
+ if (enc->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME) &&
ost->top_field_first >= 0)
in_picture->top_field_first = !!ost->top_field_first;
- in_picture->quality = ost->st->codec->global_quality;
+ in_picture->quality = enc->global_quality;
if (!enc->me_threshold)
in_picture->pict_type = 0;
if (ost->forced_kf_index < ost->forced_kf_count &&
@@ -628,7 +630,7 @@ static void do_video_stats(OutputStream *ost, int frame_size)
}
}
- enc = ost->st->codec;
+ enc = ost->enc_ctx;
if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
frame_number = ost->frame_number;
fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame->quality / (float)FF_QP2LAMBDA);
@@ -666,7 +668,7 @@ static int poll_filter(OutputStream *ost)
if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
!(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
ret = av_buffersink_get_samples(ost->filter->filter, filtered_frame,
- ost->st->codec->frame_size);
+ ost->enc_ctx->frame_size);
else
ret = av_buffersink_get_frame(ost->filter->filter, filtered_frame);
@@ -677,16 +679,16 @@ static int poll_filter(OutputStream *ost)
int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
filtered_frame->pts = av_rescale_q(filtered_frame->pts,
ost->filter->filter->inputs[0]->time_base,
- ost->st->codec->time_base) -
+ ost->enc_ctx->time_base) -
av_rescale_q(start_time,
AV_TIME_BASE_Q,
- ost->st->codec->time_base);
+ ost->enc_ctx->time_base);
}
switch (ost->filter->filter->inputs[0]->type) {
case AVMEDIA_TYPE_VIDEO:
if (!ost->frame_aspect_ratio)
- ost->st->codec->sample_aspect_ratio = filtered_frame->sample_aspect_ratio;
+ ost->enc_ctx->sample_aspect_ratio = filtered_frame->sample_aspect_ratio;
do_video_out(of->ctx, ost, filtered_frame, &frame_size);
if (vstats_filename && frame_size)
@@ -728,7 +730,7 @@ static int poll_filters(void)
if (!output_streams[i]->filter || output_streams[i]->finished)
continue;
- pts = av_rescale_q(pts, output_streams[i]->st->codec->time_base,
+ pts = av_rescale_q(pts, output_streams[i]->enc_ctx->time_base,
AV_TIME_BASE_Q);
if (pts < min_pts) {
min_pts = pts;
@@ -768,12 +770,12 @@ static void print_final_stats(int64_t total_size)
for (i = 0; i < nb_output_streams; i++) {
OutputStream *ost = output_streams[i];
- switch (ost->st->codec->codec_type) {
+ switch (ost->enc_ctx->codec_type) {
case AVMEDIA_TYPE_VIDEO: video_size += ost->data_size; break;
case AVMEDIA_TYPE_AUDIO: audio_size += ost->data_size; break;
default: other_size += ost->data_size; break;
}
- extra_size += ost->st->codec->extradata_size;
+ extra_size += ost->enc_ctx->extradata_size;
data_size += ost->data_size;
}
@@ -836,7 +838,7 @@ static void print_final_stats(int64_t total_size)
for (j = 0; j < of->ctx->nb_streams; j++) {
OutputStream *ost = output_streams[of->ost_index + j];
- enum AVMediaType type = ost->st->codec->codec_type;
+ enum AVMediaType type = ost->enc_ctx->codec_type;
total_size += ost->data_size;
total_packets += ost->packets_written;
@@ -910,7 +912,7 @@ static void print_report(int is_last_report, int64_t timer_start)
for (i = 0; i < nb_output_streams; i++) {
float q = -1;
ost = output_streams[i];
- enc = ost->st->codec;
+ enc = ost->enc_ctx;
if (!ost->stream_copy && enc->coded_frame)
q = enc->coded_frame->quality / (float)FF_QP2LAMBDA;
if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -989,23 +991,23 @@ static void flush_encoders(void)
for (i = 0; i < nb_output_streams; i++) {
OutputStream *ost = output_streams[i];
- AVCodecContext *enc = ost->st->codec;
+ AVCodecContext *enc = ost->enc_ctx;
AVFormatContext *os = output_files[ost->file_index]->ctx;
int stop_encoding = 0;
if (!ost->encoding_needed)
continue;
- if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <= 1)
+ if (enc->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <= 1)
continue;
- if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE) && enc->codec->id == AV_CODEC_ID_RAWVIDEO)
+ if (enc->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE) && enc->codec->id == AV_CODEC_ID_RAWVIDEO)
continue;
for (;;) {
int (*encode)(AVCodecContext*, AVPacket*, const AVFrame*, int*) = NULL;
const char *desc;
- switch (ost->st->codec->codec_type) {
+ switch (enc->codec_type) {
case AVMEDIA_TYPE_AUDIO:
encode = avcodec_encode_audio2;
desc = "Audio";
@@ -1100,7 +1102,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
}
/* force the input stream PTS */
- if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+ if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
ost->sync_opts++;
if (pkt->pts != AV_NOPTS_VALUE)
@@ -1118,10 +1120,10 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
opkt.flags = pkt->flags;
// FIXME remove the following 2 lines they shall be replaced by the bitstream filters
- if ( ost->st->codec->codec_id != AV_CODEC_ID_H264
- && ost->st->codec->codec_id != AV_CODEC_ID_MPEG1VIDEO
- && ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO
- && ost->st->codec->codec_id != AV_CODEC_ID_VC1
+ if ( ost->enc_ctx->codec_id != AV_CODEC_ID_H264
+ && ost->enc_ctx->codec_id != AV_CODEC_ID_MPEG1VIDEO
+ && ost->enc_ctx->codec_id != AV_CODEC_ID_MPEG2VIDEO
+ && ost->enc_ctx->codec_id != AV_CODEC_ID_VC1
) {
if (av_parser_change(ost->parser, ost->st->codec,
&opkt.data, &opkt.size,
@@ -1555,7 +1557,7 @@ static int init_input_stream(int ist_index, char *error, int error_len)
for (i = 0; i < nb_output_streams; i++) {
OutputStream *ost = output_streams[i];
if (ost->source_index == ist_index) {
- update_sample_fmt(ist->dec_ctx, codec, ost->st->codec);
+ update_sample_fmt(ist->dec_ctx, codec, ost->enc_ctx);
break;
}
}
@@ -1602,7 +1604,7 @@ static InputStream *get_input_stream(OutputStream *ost)
int i;
for (i = 0; i < fg->nb_inputs; i++)
- if (fg->inputs[i]->ist->dec_ctx->codec_type == ost->st->codec->codec_type)
+ if (fg->inputs[i]->ist->dec_ctx->codec_type == ost->enc_ctx->codec_type)
return fg->inputs[i]->ist;
}
@@ -1711,7 +1713,7 @@ static int transcode_init(void)
if (ost->attachment_filename)
continue;
- enc_ctx = ost->st->codec;
+ enc_ctx = ost->enc_ctx;
if (ist) {
dec_ctx = ist->dec_ctx;
@@ -1893,7 +1895,7 @@ static int transcode_init(void)
if (ost->forced_keyframes)
parse_forced_key_frames(ost->forced_keyframes, ost,
- ost->st->codec);
+ ost->enc_ctx);
break;
case AVMEDIA_TYPE_SUBTITLE:
enc_ctx->time_base = (AVRational){1, 1000};
@@ -1947,17 +1949,19 @@ static int transcode_init(void)
if ((ist = get_input_stream(ost)))
dec = ist->dec_ctx;
if (dec && dec->subtitle_header) {
- ost->st->codec->subtitle_header = av_malloc(dec->subtitle_header_size);
- if (!ost->st->codec->subtitle_header) {
+ ost->enc_ctx->subtitle_header = av_malloc(dec->subtitle_header_size);
+ if (!ost->enc_ctx->subtitle_header) {
ret = AVERROR(ENOMEM);
goto dump_format;
}
- memcpy(ost->st->codec->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);
- ost->st->codec->subtitle_header_size = dec->subtitle_header_size;
+ memcpy(ost->enc_ctx->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);
+ ost->enc_ctx->subtitle_header_size = dec->subtitle_header_size;
}
if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0))
av_dict_set(&ost->encoder_opts, "threads", "auto", 0);
- if ((ret = avcodec_open2(ost->st->codec, codec, &ost->encoder_opts)) < 0) {
+ av_dict_set(&ost->encoder_opts, "side_data_only_packets", "1", 0);
+
+ if ((ret = avcodec_open2(ost->enc_ctx, codec, &ost->encoder_opts)) < 0) {
if (ret == AVERROR_EXPERIMENTAL)
abort_codec_experimental(codec, 1);
snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d:%d - maybe incorrect parameters such as bit_rate, rate, width or height",
@@ -1965,11 +1969,18 @@ static int transcode_init(void)
goto dump_format;
}
assert_avoptions(ost->encoder_opts);
- if (ost->st->codec->bit_rate && ost->st->codec->bit_rate < 1000)
+ if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000)
av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
"It takes bits/s as argument, not kbits/s\n");
} else {
- av_opt_set_dict(ost->st->codec, &ost->encoder_opts);
+ av_opt_set_dict(ost->enc_ctx, &ost->encoder_opts);
+ }
+
+ ret = avcodec_copy_context(ost->st->codec, ost->enc_ctx);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_FATAL,
+ "Error initializing the output stream codec context.\n");
+ exit_program(1);
}
}
@@ -2505,8 +2516,7 @@ static int transcode(void)
for (i = 0; i < nb_output_streams; i++) {
ost = output_streams[i];
if (ost->encoding_needed) {
- av_freep(&ost->st->codec->stats_in);
- avcodec_close(ost->st->codec);
+ av_freep(&ost->enc_ctx->stats_in);
}
}
@@ -2532,13 +2542,10 @@ static int transcode(void)
for (i = 0; i < nb_output_streams; i++) {
ost = output_streams[i];
if (ost) {
- if (ost->stream_copy)
- av_freep(&ost->st->codec->extradata);
if (ost->logfile) {
fclose(ost->logfile);
ost->logfile = NULL;
}
- av_freep(&ost->st->codec->subtitle_header);
av_free(ost->forced_kf_pts);
av_dict_free(&ost->encoder_opts);
av_dict_free(&ost->resample_opts);