}
for (i = 0; i < nb_output_streams; i++) {
OutputStream *ost = output_streams[i];
- AVBitStreamFilterContext *bsfc;
if (!ost)
continue;
- bsfc = ost->bitstream_filters;
- while (bsfc) {
- AVBitStreamFilterContext *next = bsfc->next;
- av_bitstream_filter_close(bsfc);
- bsfc = next;
- }
- ost->bitstream_filters = NULL;
+ for (j = 0; j < ost->nb_bitstream_filters; j++)
+ av_bsf_free(&ost->bsf_ctx[j]);
+ av_freep(&ost->bsf_ctx);
+ av_freep(&ost->bsf_extradata_updated);
+
av_frame_free(&ost->filtered_frame);
av_frame_free(&ost->last_frame);
av_dict_free(&ost->sws_dict);
avcodec_free_context(&ost->enc_ctx);
+ avcodec_parameters_free(&ost->ref_par);
av_freep(&output_streams[i]);
}
}
}
-static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
+static void write_packet(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
{
- AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
- AVCodecContext *avctx = ost->encoding_needed ? ost->enc_ctx : ost->st->codec;
+ AVStream *st = ost->st;
int ret;
- if (!ost->st->codec->extradata_size && ost->enc_ctx->extradata_size) {
- ost->st->codec->extradata = av_mallocz(ost->enc_ctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (ost->st->codec->extradata) {
- memcpy(ost->st->codec->extradata, ost->enc_ctx->extradata, ost->enc_ctx->extradata_size);
- ost->st->codec->extradata_size = ost->enc_ctx->extradata_size;
- }
- }
-
- if ((avctx->codec_type == AVMEDIA_TYPE_VIDEO && video_sync_method == VSYNC_DROP) ||
- (avctx->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
+ if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && video_sync_method == VSYNC_DROP) ||
+ (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
pkt->pts = pkt->dts = AV_NOPTS_VALUE;
/*
* Counting encoded video frames needs to be done separately because of
* reordering, see do_video_out()
*/
- if (!(avctx->codec_type == AVMEDIA_TYPE_VIDEO && avctx->codec)) {
+ if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed)) {
if (ost->frame_number >= ost->max_frames) {
av_packet_unref(pkt);
return;
}
ost->frame_number++;
}
- if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
int i;
uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
NULL);
}
}
- if (bsfc)
- av_packet_split_side_data(pkt);
-
- if ((ret = av_apply_bitstream_filters(avctx, pkt, bsfc)) < 0) {
- print_error("", ret);
- if (exit_on_error)
- exit_program(1);
- }
- if (pkt->size == 0 && pkt->side_data_elems == 0)
- return;
- if (!ost->st->codecpar->extradata && avctx->extradata) {
- ost->st->codecpar->extradata = av_malloc(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
- if (!ost->st->codecpar->extradata) {
- av_log(NULL, AV_LOG_ERROR, "Could not allocate extradata buffer to copy parser data.\n");
- exit_program(1);
- }
- ost->st->codecpar->extradata_size = avctx->extradata_size;
- memcpy(ost->st->codecpar->extradata, avctx->extradata, avctx->extradata_size);
- }
-
if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
if (pkt->dts != AV_NOPTS_VALUE &&
pkt->pts != AV_NOPTS_VALUE &&
- FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1)
- FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1);
}
- if(
- (avctx->codec_type == AVMEDIA_TYPE_AUDIO || avctx->codec_type == AVMEDIA_TYPE_VIDEO) &&
- pkt->dts != AV_NOPTS_VALUE &&
- !(avctx->codec_id == AV_CODEC_ID_VP9 && ost->stream_copy) &&
- ost->last_mux_dts != AV_NOPTS_VALUE) {
- int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
- if (pkt->dts < max) {
- int loglevel = max - pkt->dts > 2 || avctx->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
- av_log(s, loglevel, "Non-monotonous DTS in output stream "
- "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
- ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts);
- if (exit_on_error) {
- av_log(NULL, AV_LOG_FATAL, "aborting.\n");
- exit_program(1);
+ if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
+ pkt->dts != AV_NOPTS_VALUE &&
+ !(st->codecpar->codec_id == AV_CODEC_ID_VP9 && ost->stream_copy) &&
+ ost->last_mux_dts != AV_NOPTS_VALUE) {
+ int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
+ if (pkt->dts < max) {
+ int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
+ av_log(s, loglevel, "Non-monotonous DTS in output stream "
+ "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
+ ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts);
+ if (exit_on_error) {
+ av_log(NULL, AV_LOG_FATAL, "aborting.\n");
+ exit_program(1);
+ }
+ av_log(s, loglevel, "changing to %"PRId64". This may result "
+ "in incorrect timestamps in the output file.\n",
+ max);
+ if (pkt->pts >= pkt->dts)
+ pkt->pts = FFMAX(pkt->pts, max);
+ pkt->dts = max;
+ }
}
- av_log(s, loglevel, "changing to %"PRId64". This may result "
- "in incorrect timestamps in the output file.\n",
- max);
- if(pkt->pts >= pkt->dts)
- pkt->pts = FFMAX(pkt->pts, max);
- pkt->dts = max;
- }
- }
}
ost->last_mux_dts = pkt->dts;
}
}
+static void output_packet(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
+{
+ int ret = 0;
+
+ /* apply the output bitstream filters, if any */
+ if (ost->nb_bitstream_filters) {
+ int idx;
+
+ ret = av_bsf_send_packet(ost->bsf_ctx[0], pkt);
+ if (ret < 0)
+ goto finish;
+
+ idx = 1;
+ while (idx) {
+ /* get a packet from the previous filter up the chain */
+ ret = av_bsf_receive_packet(ost->bsf_ctx[idx - 1], pkt);
+ /* HACK! - aac_adtstoasc updates extradata after filtering the first frame when
+ * the api states this shouldn't happen after init(). Propagate it here to the
+ * muxer and to the next filters in the chain to workaround this.
+ * TODO/FIXME - Make aac_adtstoasc use new packet side data instead of changing
+ * par_out->extradata and adapt muxers accordingly to get rid of this. */
+ if (!(ost->bsf_extradata_updated[idx - 1] & 1)) {
+ ret = avcodec_parameters_copy(ost->st->codecpar, ost->bsf_ctx[idx - 1]->par_out);
+ if (ret < 0)
+ goto finish;
+ ost->bsf_extradata_updated[idx - 1] |= 1;
+ }
+ if (ret == AVERROR(EAGAIN)) {
+ ret = 0;
+ idx--;
+ continue;
+ } else if (ret < 0)
+ goto finish;
+
+ /* send it to the next filter down the chain or to the muxer */
+ if (idx < ost->nb_bitstream_filters) {
+ /* HACK/FIXME! - See above */
+ if (!(ost->bsf_extradata_updated[idx] & 2)) {
+ ret = avcodec_parameters_copy(ost->bsf_ctx[idx]->par_out, ost->bsf_ctx[idx - 1]->par_out);
+ if (ret < 0)
+ goto finish;
+ ost->bsf_extradata_updated[idx] |= 2;
+ }
+ ret = av_bsf_send_packet(ost->bsf_ctx[idx], pkt);
+ if (ret < 0)
+ goto finish;
+ idx++;
+ } else
+ write_packet(s, pkt, ost);
+ }
+ } else
+ write_packet(s, pkt, ost);
+
+finish:
+ if (ret < 0 && ret != AVERROR_EOF) {
+ av_log(NULL, AV_LOG_ERROR, "Error applying bitstream filters to an output "
+ "packet for stream #%d:%d.\n", ost->file_index, ost->index);
+ if(exit_on_error)
+ exit_program(1);
+ }
+}
+
static int check_recording_time(OutputStream *ost)
{
OutputFile *of = output_files[ost->file_index];
av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base));
}
- write_frame(s, &pkt, ost);
+ output_packet(s, &pkt, ost);
}
}
pkt.pts += 90 * sub->end_display_time;
}
pkt.dts = pkt.pts;
- write_frame(s, &pkt, ost);
+ output_packet(s, &pkt, ost);
}
}
int ret, format_video_sync;
AVPacket pkt;
AVCodecContext *enc = ost->enc_ctx;
- AVCodecContext *mux_enc = ost->st->codec;
+ AVCodecParameters *mux_par = ost->st->codecpar;
int nb_frames, nb0_frames, i;
double delta, delta0;
double duration = 0;
avoid any copies. We support temporarily the older
method. */
if (in_picture->interlaced_frame)
- mux_enc->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
+ mux_par->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
else
- mux_enc->field_order = AV_FIELD_PROGRESSIVE;
+ mux_par->field_order = AV_FIELD_PROGRESSIVE;
pkt.data = (uint8_t *)in_picture;
pkt.size = sizeof(AVPicture);
pkt.pts = av_rescale_q(in_picture->pts, enc->time_base, ost->st->time_base);
pkt.flags |= AV_PKT_FLAG_KEY;
- write_frame(s, &pkt, ost);
+ output_packet(s, &pkt, ost);
} else
#endif
{
if (in_picture->interlaced_frame) {
if (enc->codec->id == AV_CODEC_ID_MJPEG)
- mux_enc->field_order = in_picture->top_field_first ? AV_FIELD_TT:AV_FIELD_BB;
+ mux_par->field_order = in_picture->top_field_first ? AV_FIELD_TT:AV_FIELD_BB;
else
- mux_enc->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
+ mux_par->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
} else
- mux_enc->field_order = AV_FIELD_PROGRESSIVE;
+ mux_par->field_order = AV_FIELD_PROGRESSIVE;
in_picture->quality = enc->global_quality;
in_picture->pict_type = 0;
}
frame_size = pkt.size;
- write_frame(s, &pkt, ost);
+ output_packet(s, &pkt, ost);
/* if two pass, output log */
if (ost->logfile && enc->stats_out) {
}
av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
pkt_size = pkt.size;
- write_frame(os, &pkt, ost);
+ output_packet(os, &pkt, ost);
if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) {
do_video_stats(ost, pkt_size);
}
opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base);
opkt.dts -= ost_tb_start_time;
- if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->dts != AV_NOPTS_VALUE) {
+ if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && pkt->dts != AV_NOPTS_VALUE) {
int duration = av_get_audio_frame_duration(ist->dec_ctx, pkt->size);
if(!duration)
duration = ist->dec_ctx->frame_size;
opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);
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->st->codecpar->codec_id != AV_CODEC_ID_H264
+ && ost->st->codecpar->codec_id != AV_CODEC_ID_MPEG1VIDEO
+ && ost->st->codecpar->codec_id != AV_CODEC_ID_MPEG2VIDEO
+ && ost->st->codecpar->codec_id != AV_CODEC_ID_VC1
) {
int ret = av_parser_change(ost->parser, ost->st->codec,
&opkt.data, &opkt.size,
av_copy_packet_side_data(&opkt, pkt);
#if FF_API_LAVF_FMT_RAWPICTURE
- if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
- ost->st->codec->codec_id == AV_CODEC_ID_RAWVIDEO &&
+ if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
+ ost->st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO &&
(of->ctx->oformat->flags & AVFMT_RAWPICTURE)) {
/* store AVPicture in AVPacket, as expected by the output format */
- int ret = avpicture_fill(&pict, opkt.data, ost->st->codec->pix_fmt, ost->st->codec->width, ost->st->codec->height);
+ int ret = avpicture_fill(&pict, opkt.data, ost->st->codecpar->format, ost->st->codecpar->width, ost->st->codecpar->height);
if (ret < 0) {
av_log(NULL, AV_LOG_FATAL, "avpicture_fill failed: %s\n",
av_err2str(ret));
}
#endif
- write_frame(of->ctx, &opkt, ost);
+ output_packet(of->ctx, &opkt, ost);
}
int guess_input_channel_layout(InputStream *ist)
// The following line may be required in some cases where there is no parser
// or the parser does not has_b_frames correctly
- if (ist->st->codec->has_b_frames < ist->dec_ctx->has_b_frames) {
+ if (ist->st->codecpar->video_delay < ist->dec_ctx->has_b_frames) {
if (ist->dec_ctx->codec_id == AV_CODEC_ID_H264) {
- ist->st->codec->has_b_frames = ist->dec_ctx->has_b_frames;
+ ist->st->codecpar->video_delay = ist->dec_ctx->has_b_frames;
} else
av_log(ist->dec_ctx, AV_LOG_WARNING,
- "has_b_frames is larger in decoder than demuxer %d > %d.\n"
+ "video_delay is larger in decoder than demuxer %d > %d.\n"
"If you want to help, upload a sample "
"of this file to ftp://upload.ffmpeg.org/incoming/ "
"and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)",
ist->dec_ctx->has_b_frames,
- ist->st->codec->has_b_frames);
+ ist->st->codecpar->video_delay);
}
check_decode_result(ist, got_output, ret);
av_dict_set(&ist->decoder_opts, "sub_text_format", "ass", AV_DICT_DONT_OVERWRITE);
+ /* Useful for subtitles retiming by lavf (FIXME), skipping samples in
+ * audio, and video decoders such as cuvid or mediacodec */
+ av_codec_set_pkt_timebase(ist->dec_ctx, ist->st->time_base);
+
if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0))
av_dict_set(&ist->decoder_opts, "threads", "auto", 0);
if ((ret = avcodec_open2(ist->dec_ctx, codec, &ist->decoder_opts)) < 0) {
return FFDIFFSIGN(*(const int64_t *)a, *(const int64_t *)b);
}
+static int init_output_bsfs(OutputStream *ost)
+{
+ AVBSFContext *ctx;
+ int i, ret;
+
+ if (!ost->nb_bitstream_filters)
+ return 0;
+
+ for (i = 0; i < ost->nb_bitstream_filters; i++) {
+ ctx = ost->bsf_ctx[i];
+
+ ret = avcodec_parameters_copy(ctx->par_in,
+ i ? ost->bsf_ctx[i - 1]->par_out : ost->st->codecpar);
+ if (ret < 0)
+ return ret;
+
+ ctx->time_base_in = i ? ost->bsf_ctx[i - 1]->time_base_out : ost->st->time_base;
+
+ ret = av_bsf_init(ctx);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
+ ost->bsf_ctx[i]->filter->name);
+ return ret;
+ }
+ }
+
+ ctx = ost->bsf_ctx[ost->nb_bitstream_filters - 1];
+ ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out);
+ if (ret < 0)
+ return ret;
+
+ ost->st->time_base = ctx->time_base_out;
+
+ return 0;
+}
+
static int init_output_stream(OutputStream *ost, char *error, int error_len)
{
int ret = 0;
av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
" It takes bits/s as argument, not kbits/s\n");
- ret = avcodec_copy_context(ost->st->codec, ost->enc_ctx);
+ ret = avcodec_parameters_from_context(ost->st->codecpar, ost->enc_ctx);
if (ret < 0) {
av_log(NULL, AV_LOG_FATAL,
"Error initializing the output stream codec context.\n");
exit_program(1);
}
+ /*
+ * FIXME: this is only so that the bitstream filters and parsers (that still
+ * work with a codec context) get the parameter values.
+ * This should go away with the new BSF/parser API.
+ */
+ ret = avcodec_copy_context(ost->st->codec, ost->enc_ctx);
+ if (ret < 0)
+ return ret;
if (ost->enc_ctx->nb_coded_side_data) {
int i;
// copy timebase while removing common factors
ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1});
ost->st->codec->codec= ost->enc_ctx->codec;
- } else {
- ret = av_opt_set_dict(ost->st->codec, &ost->encoder_opts);
- if (ret < 0) {
- av_log(NULL, AV_LOG_FATAL,
- "Error setting up codec context options.\n");
- return ret;
- }
+ } else if (ost->stream_copy) {
// copy timebase while removing common factors
ost->st->time_base = av_add_q(ost->st->codec->time_base, (AVRational){0, 1});
+
+ /*
+ * FIXME: this is only so that the bitstream filters and parsers (that still
+ * work with a codec context) get the parameter values.
+ * This should go away with the new BSF/parser API.
+ */
+ ret = avcodec_parameters_to_context(ost->st->codec, ost->st->codecpar);
+ if (ret < 0)
+ return ret;
}
+ /* initialize bitstream filters for the output stream
+ * needs to be done here, because the codec id for streamcopy is not
+ * known until now */
+ ret = init_output_bsfs(ost);
+ if (ret < 0)
+ return ret;
+
return ret;
}
return;
av_log(file->ctx, AV_LOG_WARNING,
"New %s stream %d:%d at pos:%"PRId64" and DTS:%ss\n",
- av_get_media_type_string(st->codec->codec_type),
+ av_get_media_type_string(st->codecpar->codec_type),
input_index, pkt->stream_index,
pkt->pos, av_ts2timestr(pkt->dts, &st->time_base));
file->nb_streams_warn = pkt->stream_index + 1;
/* for each output stream, we compute the right encoding parameters */
for (i = 0; i < nb_output_streams; i++) {
- AVCodecContext *enc_ctx;
- AVCodecContext *dec_ctx = NULL;
ost = output_streams[i];
oc = output_files[ost->file_index]->ctx;
ist = get_input_stream(ost);
if (ost->attachment_filename)
continue;
- enc_ctx = ost->stream_copy ? ost->st->codec : ost->enc_ctx;
-
if (ist) {
- dec_ctx = ist->dec_ctx;
-
ost->st->disposition = ist->st->disposition;
- enc_ctx->bits_per_raw_sample = dec_ctx->bits_per_raw_sample;
- enc_ctx->chroma_sample_location = dec_ctx->chroma_sample_location;
} else {
for (j=0; j<oc->nb_streams; j++) {
AVStream *st = oc->streams[j];
- if (st != ost->st && st->codec->codec_type == enc_ctx->codec_type)
+ if (st != ost->st && st->codecpar->codec_type == ost->st->codecpar->codec_type)
break;
}
if (j == oc->nb_streams)
- if (enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO || enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
+ if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO ||
+ ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
ost->st->disposition = AV_DISPOSITION_DEFAULT;
}
if (ost->stream_copy) {
+ AVCodecParameters *par_dst = ost->st->codecpar;
+ AVCodecParameters *par_src = ost->ref_par;
AVRational sar;
uint64_t extra_size;
av_assert0(ist && !ost->filter);
- extra_size = (uint64_t)dec_ctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE;
+ avcodec_parameters_to_context(ost->enc_ctx, ist->st->codecpar);
+ ret = av_opt_set_dict(ost->enc_ctx, &ost->encoder_opts);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_FATAL,
+ "Error setting up codec context options.\n");
+ return ret;
+ }
+ avcodec_parameters_from_context(par_src, ost->enc_ctx);
+
+ extra_size = (uint64_t)par_src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE;
if (extra_size > INT_MAX) {
return AVERROR(EINVAL);
}
/* if stream_copy is selected, no need to decode or encode */
- enc_ctx->codec_id = dec_ctx->codec_id;
- enc_ctx->codec_type = dec_ctx->codec_type;
+ par_dst->codec_id = par_src->codec_id;
+ par_dst->codec_type = par_src->codec_type;
- if (!enc_ctx->codec_tag) {
+ if (!par_dst->codec_tag) {
unsigned int codec_tag;
if (!oc->oformat->codec_tag ||
- av_codec_get_id (oc->oformat->codec_tag, dec_ctx->codec_tag) == enc_ctx->codec_id ||
- !av_codec_get_tag2(oc->oformat->codec_tag, dec_ctx->codec_id, &codec_tag))
- enc_ctx->codec_tag = dec_ctx->codec_tag;
+ av_codec_get_id (oc->oformat->codec_tag, par_src->codec_tag) == par_dst->codec_id ||
+ !av_codec_get_tag2(oc->oformat->codec_tag, par_src->codec_id, &codec_tag))
+ par_dst->codec_tag = par_src->codec_tag;
}
- enc_ctx->bit_rate = dec_ctx->bit_rate;
- enc_ctx->rc_max_rate = dec_ctx->rc_max_rate;
- enc_ctx->rc_buffer_size = dec_ctx->rc_buffer_size;
- enc_ctx->field_order = dec_ctx->field_order;
- if (dec_ctx->extradata_size) {
- enc_ctx->extradata = av_mallocz(extra_size);
- if (!enc_ctx->extradata) {
+ par_dst->bit_rate = par_src->bit_rate;
+ par_dst->field_order = par_src->field_order;
+ par_dst->chroma_location = par_src->chroma_location;
+ if (par_src->extradata_size) {
+ par_dst->extradata = av_mallocz(extra_size);
+ if (!par_dst->extradata) {
return AVERROR(ENOMEM);
}
- memcpy(enc_ctx->extradata, dec_ctx->extradata, dec_ctx->extradata_size);
- }
- enc_ctx->extradata_size= dec_ctx->extradata_size;
- enc_ctx->bits_per_coded_sample = dec_ctx->bits_per_coded_sample;
-
- enc_ctx->time_base = ist->st->time_base;
- /*
- * Avi is a special case here because it supports variable fps but
- * having the fps and timebase differe significantly adds quite some
- * overhead
- */
- if(!strcmp(oc->oformat->name, "avi")) {
- if ( copy_tb<0 && ist->st->r_frame_rate.num
- && av_q2d(ist->st->r_frame_rate) >= av_q2d(ist->st->avg_frame_rate)
- && 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(ist->st->time_base)
- && 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(dec_ctx->time_base)
- && av_q2d(ist->st->time_base) < 1.0/500 && av_q2d(dec_ctx->time_base) < 1.0/500
- || copy_tb==2){
- enc_ctx->time_base.num = ist->st->r_frame_rate.den;
- enc_ctx->time_base.den = 2*ist->st->r_frame_rate.num;
- enc_ctx->ticks_per_frame = 2;
- } else if ( copy_tb<0 && av_q2d(dec_ctx->time_base)*dec_ctx->ticks_per_frame > 2*av_q2d(ist->st->time_base)
- && av_q2d(ist->st->time_base) < 1.0/500
- || copy_tb==0){
- enc_ctx->time_base = dec_ctx->time_base;
- enc_ctx->time_base.num *= dec_ctx->ticks_per_frame;
- enc_ctx->time_base.den *= 2;
- enc_ctx->ticks_per_frame = 2;
- }
- } else if(!(oc->oformat->flags & AVFMT_VARIABLE_FPS)
- && strcmp(oc->oformat->name, "mov") && strcmp(oc->oformat->name, "mp4") && strcmp(oc->oformat->name, "3gp")
- && strcmp(oc->oformat->name, "3g2") && strcmp(oc->oformat->name, "psp") && strcmp(oc->oformat->name, "ipod")
- && strcmp(oc->oformat->name, "f4v")
- ) {
- if( copy_tb<0 && dec_ctx->time_base.den
- && av_q2d(dec_ctx->time_base)*dec_ctx->ticks_per_frame > av_q2d(ist->st->time_base)
- && av_q2d(ist->st->time_base) < 1.0/500
- || copy_tb==0){
- enc_ctx->time_base = dec_ctx->time_base;
- enc_ctx->time_base.num *= dec_ctx->ticks_per_frame;
- }
- }
- if ( enc_ctx->codec_tag == AV_RL32("tmcd")
- && dec_ctx->time_base.num < dec_ctx->time_base.den
- && dec_ctx->time_base.num > 0
- && 121LL*dec_ctx->time_base.num > dec_ctx->time_base.den) {
- enc_ctx->time_base = dec_ctx->time_base;
+ memcpy(par_dst->extradata, par_src->extradata, par_src->extradata_size);
}
+ par_dst->extradata_size= par_src->extradata_size;
+ par_dst->bits_per_coded_sample = par_src->bits_per_coded_sample;
+ par_dst->bits_per_raw_sample = par_src->bits_per_raw_sample;
if (!ost->frame_rate.num)
ost->frame_rate = ist->framerate;
- if(ost->frame_rate.num)
- enc_ctx->time_base = av_inv_q(ost->frame_rate);
+ ost->st->avg_frame_rate = ost->frame_rate;
+
+ ost->st->time_base = ist->st->time_base;
- av_reduce(&enc_ctx->time_base.num, &enc_ctx->time_base.den,
- enc_ctx->time_base.num, enc_ctx->time_base.den, INT_MAX);
+ ret = avformat_transfer_internal_stream_timing_info(oc->oformat, ost->st, ist->st, copy_tb);
+ if (ret < 0)
+ return ret;
if (ist->st->nb_side_data) {
ost->st->side_data = av_realloc_array(NULL, ist->st->nb_side_data,
}
}
- ost->parser = av_parser_init(enc_ctx->codec_id);
+ ost->parser = av_parser_init(par_dst->codec_id);
- switch (enc_ctx->codec_type) {
+ switch (par_dst->codec_type) {
case AVMEDIA_TYPE_AUDIO:
if (audio_volume != 256) {
av_log(NULL, AV_LOG_FATAL, "-acodec copy and -vol are incompatible (frames are not decoded)\n");
exit_program(1);
}
- enc_ctx->channel_layout = dec_ctx->channel_layout;
- enc_ctx->sample_rate = dec_ctx->sample_rate;
- enc_ctx->channels = dec_ctx->channels;
- enc_ctx->frame_size = dec_ctx->frame_size;
- enc_ctx->audio_service_type = dec_ctx->audio_service_type;
- enc_ctx->block_align = dec_ctx->block_align;
- enc_ctx->initial_padding = dec_ctx->delay;
- enc_ctx->profile = dec_ctx->profile;
-#if FF_API_AUDIOENC_DELAY
- enc_ctx->delay = dec_ctx->delay;
-#endif
- if((enc_ctx->block_align == 1 || enc_ctx->block_align == 1152 || enc_ctx->block_align == 576) && enc_ctx->codec_id == AV_CODEC_ID_MP3)
- enc_ctx->block_align= 0;
- if(enc_ctx->codec_id == AV_CODEC_ID_AC3)
- enc_ctx->block_align= 0;
+ par_dst->channel_layout = par_src->channel_layout;
+ par_dst->sample_rate = par_src->sample_rate;
+ par_dst->channels = par_src->channels;
+ par_dst->frame_size = par_src->frame_size;
+ par_dst->block_align = par_src->block_align;
+ par_dst->initial_padding = par_src->initial_padding;
+ par_dst->trailing_padding = par_src->trailing_padding;
+ par_dst->profile = par_src->profile;
+ if((par_dst->block_align == 1 || par_dst->block_align == 1152 || par_dst->block_align == 576) && par_dst->codec_id == AV_CODEC_ID_MP3)
+ par_dst->block_align= 0;
+ if(par_dst->codec_id == AV_CODEC_ID_AC3)
+ par_dst->block_align= 0;
break;
case AVMEDIA_TYPE_VIDEO:
- enc_ctx->pix_fmt = dec_ctx->pix_fmt;
- enc_ctx->colorspace = dec_ctx->colorspace;
- enc_ctx->color_range = dec_ctx->color_range;
- enc_ctx->color_primaries = dec_ctx->color_primaries;
- enc_ctx->color_trc = dec_ctx->color_trc;
- enc_ctx->width = dec_ctx->width;
- enc_ctx->height = dec_ctx->height;
- enc_ctx->has_b_frames = dec_ctx->has_b_frames;
+ par_dst->format = par_src->format;
+ par_dst->color_space = par_src->color_space;
+ par_dst->color_range = par_src->color_range;
+ par_dst->color_primaries = par_src->color_primaries;
+ par_dst->color_trc = par_src->color_trc;
+ par_dst->width = par_src->width;
+ par_dst->height = par_src->height;
+ par_dst->video_delay = par_src->video_delay;
+ par_dst->profile = par_src->profile;
if (ost->frame_aspect_ratio.num) { // overridden by the -aspect cli option
sar =
av_mul_q(ost->frame_aspect_ratio,
- (AVRational){ enc_ctx->height, enc_ctx->width });
+ (AVRational){ par_dst->height, par_dst->width });
av_log(NULL, AV_LOG_WARNING, "Overriding aspect ratio "
"with stream copy may produce invalid files\n");
}
else if (ist->st->sample_aspect_ratio.num)
sar = ist->st->sample_aspect_ratio;
else
- sar = dec_ctx->sample_aspect_ratio;
- ost->st->sample_aspect_ratio = enc_ctx->sample_aspect_ratio = sar;
+ sar = par_src->sample_aspect_ratio;
+ ost->st->sample_aspect_ratio = par_dst->sample_aspect_ratio = sar;
ost->st->avg_frame_rate = ist->st->avg_frame_rate;
ost->st->r_frame_rate = ist->st->r_frame_rate;
break;
case AVMEDIA_TYPE_SUBTITLE:
- enc_ctx->width = dec_ctx->width;
- enc_ctx->height = dec_ctx->height;
+ par_dst->width = par_src->width;
+ par_dst->height = par_src->height;
break;
case AVMEDIA_TYPE_UNKNOWN:
case AVMEDIA_TYPE_DATA:
abort();
}
} else {
- if (!ost->enc)
- ost->enc = avcodec_find_encoder(enc_ctx->codec_id);
- if (!ost->enc) {
- /* should only happen when a default codec is not present. */
- snprintf(error, sizeof(error), "Encoder (codec %s) not found for output stream #%d:%d",
- avcodec_get_name(ost->st->codec->codec_id), ost->file_index, ost->index);
- ret = AVERROR(EINVAL);
- goto dump_format;
- }
+ AVCodecContext *enc_ctx = ost->enc_ctx;
+ AVCodecContext *dec_ctx = NULL;
set_encoder_id(output_files[ost->file_index], ost);
+ if (ist) {
+ dec_ctx = ist->dec_ctx;
+
+ enc_ctx->chroma_sample_location = dec_ctx->chroma_sample_location;
+ }
+
#if CONFIG_LIBMFX
if (qsv_transcode_init(ost))
exit_program(1);
exit_program(1);
#endif
- if (!ost->filter &&
- (enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
- enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO)) {
- FilterGraph *fg;
- fg = init_simple_filtergraph(ist, ost);
+ if ((enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
+ enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
+ filtergraph_is_simple(ost->filter->graph)) {
+ FilterGraph *fg = ost->filter->graph;
if (configure_filtergraph(fg)) {
av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n");
exit_program(1);
switch (enc_ctx->codec_type) {
case AVMEDIA_TYPE_AUDIO:
enc_ctx->sample_fmt = ost->filter->filter->inputs[0]->format;
+ if (dec_ctx)
+ enc_ctx->bits_per_raw_sample = FFMIN(dec_ctx->bits_per_raw_sample,
+ av_get_bytes_per_sample(enc_ctx->sample_fmt) << 3);
enc_ctx->sample_rate = ost->filter->filter->inputs[0]->sample_rate;
enc_ctx->channel_layout = ost->filter->filter->inputs[0]->channel_layout;
enc_ctx->channels = avfilter_link_get_channels(ost->filter->filter->inputs[0]);
"Use -pix_fmt yuv420p for compatibility with outdated media players.\n",
av_get_pix_fmt_name(ost->filter->filter->inputs[0]->format));
enc_ctx->pix_fmt = ost->filter->filter->inputs[0]->format;
+ if (dec_ctx)
+ enc_ctx->bits_per_raw_sample = FFMIN(dec_ctx->bits_per_raw_sample,
+ av_pix_fmt_desc_get(enc_ctx->pix_fmt)->comp[0].depth);
ost->st->avg_frame_rate = ost->frame_rate;
case AVMEDIA_TYPE_SUBTITLE:
enc_ctx->time_base = (AVRational){1, 1000};
if (!enc_ctx->width) {
- enc_ctx->width = input_streams[ost->source_index]->st->codec->width;
- enc_ctx->height = input_streams[ost->source_index]->st->codec->height;
+ enc_ctx->width = input_streams[ost->source_index]->st->codecpar->width;
+ enc_ctx->height = input_streams[ost->source_index]->st->codecpar->height;
}
break;
case AVMEDIA_TYPE_DATA:
ist = input_streams[i];
for (j = 0; j < ist->nb_filters; j++) {
- if (ist->filters[j]->graph->graph_desc) {
+ if (!filtergraph_is_simple(ist->filters[j]->graph)) {
av_log(NULL, AV_LOG_INFO, " Stream #%d:%d (%s) -> %s",
ist->file_index, ist->st->index, ist->dec ? ist->dec->name : "?",
ist->filters[j]->name);
continue;
}
- if (ost->filter && ost->filter->graph->graph_desc) {
+ if (ost->filter && !filtergraph_is_simple(ost->filter->graph)) {
/* output from a complex graph */
av_log(NULL, AV_LOG_INFO, " %s", ost->filter->name);
if (nb_filtergraphs > 1)
key == 'c' ? AVFILTER_CMD_FLAG_ONE : 0);
fprintf(stderr, "Command reply for stream %d: ret:%d res:\n%s", i, ret, buf);
} else if (key == 'c') {
- fprintf(stderr, "Queing commands only on filters supporting the specific command is unsupported\n");
+ fprintf(stderr, "Queuing commands only on filters supporting the specific command is unsupported\n");
ret = AVERROR_PATCHWELCOME;
} else {
ret = avfilter_graph_queue_command(fg->graph, target, command, arg, 0, time);
if (ret < 0)
- fprintf(stderr, "Queing command failed with error %s\n", av_err2str(ret));
+ fprintf(stderr, "Queuing command failed with error %s\n", av_err2str(ret));
}
}
}
if ((ret = seek_to_start(ifile, is)) < 0)
return ret;
ret = get_input_packet(ifile, &pkt);
+ if (ret == AVERROR(EAGAIN)) {
+ ifile->eagain = 1;
+ return ret;
+ }
}
if (ret < 0) {
if (ret != AVERROR_EOF) {
int ret;
int64_t ti;
+ init_dynload();
+
register_exit(ffmpeg_cleanup);
setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */