#include "libavutil/parseutils.h"
#include "libavutil/samplefmt.h"
#include "libavutil/fifo.h"
+#include "libavutil/hwcontext.h"
#include "libavutil/internal.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/dict.h"
for (j = 0; j < ost->nb_bitstream_filters; j++)
av_bsf_free(&ost->bsf_ctx[j]);
av_freep(&ost->bsf_ctx);
- av_freep(&ost->bitstream_filters);
av_frame_free(&ost->filtered_frame);
avcodec_free_context(&ost->enc_ctx);
- while (av_fifo_size(ost->muxing_queue)) {
- AVPacket pkt;
- av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL);
- av_packet_unref(&pkt);
+ if (ost->muxing_queue) {
+ while (av_fifo_size(ost->muxing_queue)) {
+ AVPacket pkt;
+ av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL);
+ av_packet_unref(&pkt);
+ }
+ av_fifo_free(ost->muxing_queue);
}
- av_fifo_free(ost->muxing_queue);
-
av_freep(&output_streams[i]);
}
for (i = 0; i < nb_input_files; i++) {
for (i = 0; i < nb_output_streams; i++) {
int64_t pts = output_streams[i]->sync_opts;
+ if (output_streams[i]->filter && !output_streams[i]->filter->graph->graph &&
+ !output_streams[i]->filter->graph->nb_inputs) {
+ ret = configure_filtergraph(output_streams[i]->filter->graph);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error reinitializing filters!\n");
+ return ret;
+ }
+ }
+
if (!output_streams[i]->filter || output_streams[i]->finished ||
!output_streams[i]->filter->graph->graph)
continue;
return 1;
}
-static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
+static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output,
+ int *decode_failed)
{
AVFrame *decoded_frame, *f;
AVCodecContext *avctx = ist->dec_ctx;
decoded_frame = ist->decoded_frame;
ret = decode(avctx, decoded_frame, got_output, pkt);
+ if (ret < 0)
+ *decode_failed = 1;
if (!*got_output || ret < 0)
return ret;
/* if the decoder provides a pts, use it instead of the last packet pts.
the decoder could be delaying output by a packet or more. */
if (decoded_frame->pts != AV_NOPTS_VALUE)
- ist->next_dts = decoded_frame->pts;
+ ist->next_dts = av_rescale_q(decoded_frame->pts, ist->st->time_base, AV_TIME_BASE_Q);
else if (pkt && pkt->pts != AV_NOPTS_VALUE) {
decoded_frame->pts = pkt->pts;
}
return err < 0 ? err : ret;
}
-static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
+static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output,
+ int *decode_failed)
{
AVFrame *decoded_frame, *f;
int i, ret = 0, err = 0;
decoded_frame = ist->decoded_frame;
ret = decode(ist->dec_ctx, decoded_frame, got_output, pkt);
+ if (ret < 0)
+ *decode_failed = 1;
if (!*got_output || ret < 0)
return ret;
decoded_frame->pts = guess_correct_pts(&ist->pts_ctx, decoded_frame->pts,
decoded_frame->pkt_dts);
+ if (ist->framerate.num)
+ decoded_frame->pts = ist->cfr_next_pts++;
if (ist->st->sample_aspect_ratio.num)
decoded_frame->sample_aspect_ratio = ist->st->sample_aspect_ratio;
return err < 0 ? err : ret;
}
-static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
+static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output,
+ int *decode_failed)
{
AVSubtitle subtitle;
int i, ret = avcodec_decode_subtitle2(ist->dec_ctx,
&subtitle, got_output, pkt);
- if (ret < 0)
+ if (ret < 0) {
+ *decode_failed = 1;
return ret;
+ }
if (!*got_output)
return ret;
while (ist->decoding_needed && (!pkt || avpkt.size > 0)) {
int ret = 0;
int got_output = 0;
+ int decode_failed = 0;
if (!repeating)
ist->last_dts = ist->next_dts;
switch (ist->dec_ctx->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- ret = decode_audio (ist, repeating ? NULL : &avpkt, &got_output);
+ ret = decode_audio (ist, repeating ? NULL : &avpkt, &got_output,
+ &decode_failed);
break;
case AVMEDIA_TYPE_VIDEO:
- ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output);
+ ret = decode_video (ist, repeating ? NULL : &avpkt, &got_output,
+ &decode_failed);
if (repeating && !got_output)
;
else if (pkt && pkt->duration)
case AVMEDIA_TYPE_SUBTITLE:
if (repeating)
break;
- ret = transcode_subtitles(ist, &avpkt, &got_output);
+ ret = transcode_subtitles(ist, &avpkt, &got_output, &decode_failed);
break;
default:
return;
}
if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n",
- ist->file_index, ist->st->index);
- if (exit_on_error)
+ if (decode_failed) {
+ av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n",
+ ist->file_index, ist->st->index);
+ } else {
+ av_log(NULL, AV_LOG_FATAL, "Error while processing the decoded "
+ "data for stream #%d:%d\n", ist->file_index, ist->st->index);
+ }
+ if (!decode_failed || exit_on_error)
exit_program(1);
break;
}
if (!ost->nb_bitstream_filters)
return 0;
- ost->bsf_ctx = av_mallocz_array(ost->nb_bitstream_filters, sizeof(*ost->bsf_ctx));
- if (!ost->bsf_ctx)
- return AVERROR(ENOMEM);
-
for (i = 0; i < ost->nb_bitstream_filters; i++) {
- ret = av_bsf_alloc(ost->bitstream_filters[i], &ctx);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error allocating a bitstream filter context\n");
- return ret;
- }
- ost->bsf_ctx[i] = ctx;
+ ctx = ost->bsf_ctx[i];
ret = avcodec_parameters_copy(ctx->par_in,
i ? ost->bsf_ctx[i - 1]->par_out : ost->st->codecpar);
ret = av_bsf_init(ctx);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
- ost->bitstream_filters[i]->name);
+ ctx->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->filter->filter->inputs[0]->sample_aspect_ratio;
enc_ctx->pix_fmt = ost->filter->filter->inputs[0]->format;
+ enc_ctx->framerate = ost->frame_rate;
+
ost->st->avg_frame_rate = ost->frame_rate;
if (dec_ctx &&
if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0))
av_dict_set(&ost->encoder_opts, "threads", "auto", 0);
- if (ost->filter && ost->filter->filter->inputs[0]->hw_frames_ctx) {
+ if (ost->filter && ost->filter->filter->inputs[0]->hw_frames_ctx &&
+ ((AVHWFramesContext*)ost->filter->filter->inputs[0]->hw_frames_ctx->data)->format ==
+ ost->filter->filter->inputs[0]->format) {
ost->enc_ctx->hw_frames_ctx = av_buffer_ref(ost->filter->filter->inputs[0]->hw_frames_ctx);
if (!ost->enc_ctx->hw_frames_ctx)
return AVERROR(ENOMEM);