/* do not send the heartbeat frame if the subtitle is already ahead */
if (pts2 <= ist2->sub2video.last_pts)
continue;
- if (pts2 >= ist2->sub2video.end_pts || !ist2->sub2video.frame->data[0])
+ if (pts2 >= ist2->sub2video.end_pts ||
+ (!ist2->sub2video.frame->data[0] && ist2->sub2video.end_pts < INT64_MAX))
sub2video_update(ist2, NULL);
for (j = 0, nb_reqs = 0; j < ist2->nb_filters; j++)
nb_reqs += av_buffersrc_get_nb_failed_requests(ist2->filters[j]->filter);
av_frame_free(&ost->last_frame);
av_dict_free(&ost->encoder_opts);
- av_parser_close(ost->parser);
- avcodec_free_context(&ost->parser_avctx);
-
av_freep(&ost->forced_keyframes);
av_expr_free(ost->forced_keyframes_pexpr);
av_freep(&ost->avfilter);
static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time)
{
- char buf[1024];
- AVBPrint buf_script;
+ AVBPrint buf, buf_script;
OutputStream *ost;
AVFormatContext *oc;
int64_t total_size;
static int64_t last_time = -1;
static int qp_histogram[52];
int hours, mins, secs, us;
+ const char *hours_sign;
int ret;
float t;
if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too
total_size = avio_tell(oc->pb);
- buf[0] = '\0';
vid = 0;
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
av_bprint_init(&buf_script, 0, 1);
for (i = 0; i < nb_output_streams; i++) {
float q = -1;
q = ost->quality / (float) FF_QP2LAMBDA;
if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);
+ av_bprintf(&buf, "q=%2.1f ", q);
av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
ost->file_index, ost->index, q);
}
frame_number = ost->frame_number;
fps = t > 1 ? frame_number / t : 0;
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3.*f q=%3.1f ",
+ av_bprintf(&buf, "frame=%5d fps=%3.*f q=%3.1f ",
frame_number, fps < 9.95, fps, q);
av_bprintf(&buf_script, "frame=%d\n", frame_number);
av_bprintf(&buf_script, "fps=%.1f\n", fps);
av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
ost->file_index, ost->index, q);
if (is_last_report)
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L");
+ av_bprintf(&buf, "L");
if (qp_hist) {
int j;
int qp = lrintf(q);
if (qp >= 0 && qp < FF_ARRAY_ELEMS(qp_histogram))
qp_histogram[qp]++;
for (j = 0; j < 32; j++)
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", av_log2(qp_histogram[j] + 1));
+ av_bprintf(&buf, "%X", av_log2(qp_histogram[j] + 1));
}
if ((enc->flags & AV_CODEC_FLAG_PSNR) && (ost->pict_type != AV_PICTURE_TYPE_NONE || is_last_report)) {
double scale, scale_sum = 0;
double p;
char type[3] = { 'Y','U','V' };
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "PSNR=");
+ av_bprintf(&buf, "PSNR=");
for (j = 0; j < 3; j++) {
if (is_last_report) {
error = enc->error[j];
error_sum += error;
scale_sum += scale;
p = psnr(error / scale);
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], p);
+ av_bprintf(&buf, "%c:%2.2f ", type[j], p);
av_bprintf(&buf_script, "stream_%d_%d_psnr_%c=%2.2f\n",
ost->file_index, ost->index, type[j] | 32, p);
}
p = psnr(error_sum / scale_sum);
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum / scale_sum));
+ av_bprintf(&buf, "*:%2.2f ", psnr(error_sum / scale_sum));
av_bprintf(&buf_script, "stream_%d_%d_psnr_all=%2.2f\n",
ost->file_index, ost->index, p);
}
secs %= 60;
hours = mins / 60;
mins %= 60;
+ hours_sign = (pts < 0) ? "-" : "";
bitrate = pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
speed = t != 0.0 ? (double)pts / AV_TIME_BASE / t : -1;
- if (total_size < 0) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- "size=N/A time=");
- else snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- "size=%8.0fkB time=", total_size / 1024.0);
- if (pts < 0)
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "-");
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
- "%02d:%02d:%02d.%02d ", hours, mins, secs,
- (100 * us) / AV_TIME_BASE);
+ if (total_size < 0) av_bprintf(&buf, "size=N/A time=");
+ else av_bprintf(&buf, "size=%8.0fkB time=", total_size / 1024.0);
+ if (pts == AV_NOPTS_VALUE) {
+ av_bprintf(&buf, "N/A ");
+ } else {
+ av_bprintf(&buf, "%s%02d:%02d:%02d.%02d ",
+ hours_sign, hours, mins, secs, (100 * us) / AV_TIME_BASE);
+ }
if (bitrate < 0) {
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),"bitrate=N/A");
+ av_bprintf(&buf, "bitrate=N/A");
av_bprintf(&buf_script, "bitrate=N/A\n");
}else{
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),"bitrate=%6.1fkbits/s", bitrate);
+ av_bprintf(&buf, "bitrate=%6.1fkbits/s", bitrate);
av_bprintf(&buf_script, "bitrate=%6.1fkbits/s\n", bitrate);
}
if (total_size < 0) av_bprintf(&buf_script, "total_size=N/A\n");
else av_bprintf(&buf_script, "total_size=%"PRId64"\n", total_size);
- av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
- av_bprintf(&buf_script, "out_time=%02d:%02d:%02d.%06d\n",
- hours, mins, secs, us);
+ if (pts == AV_NOPTS_VALUE) {
+ av_bprintf(&buf_script, "out_time_ms=N/A\n");
+ av_bprintf(&buf_script, "out_time=N/A\n");
+ } else {
+ av_bprintf(&buf_script, "out_time_ms=%"PRId64"\n", pts);
+ av_bprintf(&buf_script, "out_time=%s%02d:%02d:%02d.%06d\n",
+ hours_sign, hours, mins, secs, us);
+ }
if (nb_frames_dup || nb_frames_drop)
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",
- nb_frames_dup, nb_frames_drop);
+ av_bprintf(&buf, " dup=%d drop=%d", nb_frames_dup, nb_frames_drop);
av_bprintf(&buf_script, "dup_frames=%d\n", nb_frames_dup);
av_bprintf(&buf_script, "drop_frames=%d\n", nb_frames_drop);
if (speed < 0) {
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf)," speed=N/A");
+ av_bprintf(&buf, " speed=N/A");
av_bprintf(&buf_script, "speed=N/A\n");
} else {
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf)," speed=%4.3gx", speed);
+ av_bprintf(&buf, " speed=%4.3gx", speed);
av_bprintf(&buf_script, "speed=%4.3gx\n", speed);
}
if (print_stats || is_last_report) {
const char end = is_last_report ? '\n' : '\r';
if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
- fprintf(stderr, "%s %c", buf, end);
+ fprintf(stderr, "%s %c", buf.str, end);
} else
- av_log(NULL, AV_LOG_INFO, "%s %c", buf, end);
+ av_log(NULL, AV_LOG_INFO, "%s %c", buf.str, end);
fflush(stderr);
}
+ av_bprint_finalize(&buf, NULL);
if (progress_avio) {
av_bprintf(&buf_script, "progress=%s\n",
print_final_stats(total_size);
}
+static void ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par)
+{
+ // We never got any input. Set a fake format, which will
+ // come from libavformat.
+ ifilter->format = par->format;
+ ifilter->sample_rate = par->sample_rate;
+ ifilter->channels = par->channels;
+ ifilter->channel_layout = par->channel_layout;
+ ifilter->width = par->width;
+ ifilter->height = par->height;
+ ifilter->sample_aspect_ratio = par->sample_aspect_ratio;
+}
+
static void flush_encoders(void)
{
int i, ret;
int x;
for (x = 0; x < fg->nb_inputs; x++) {
InputFilter *ifilter = fg->inputs[x];
- if (ifilter->format < 0) {
- AVCodecParameters *par = ifilter->ist->st->codecpar;
- // We never got any input. Set a fake format, which will
- // come from libavformat.
- ifilter->format = par->format;
- ifilter->sample_rate = par->sample_rate;
- ifilter->channels = par->channels;
- ifilter->channel_layout = par->channel_layout;
- ifilter->width = par->width;
- ifilter->height = par->height;
- ifilter->sample_aspect_ratio = par->sample_aspect_ratio;
- }
+ if (ifilter->format < 0)
+ ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar);
}
if (!ifilter_has_all_input_formats(fg))
opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->mux_timebase);
opkt.flags = pkt->flags;
- // FIXME remove the following 2 lines they shall be replaced by the bitstream filters
- 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->parser_avctx,
- &opkt.data, &opkt.size,
- pkt->data, pkt->size,
- pkt->flags & AV_PKT_FLAG_KEY);
- if (ret < 0) {
- av_log(NULL, AV_LOG_FATAL, "av_parser_change failed: %s\n",
- av_err2str(ret));
+
+ if (pkt->buf) {
+ opkt.buf = av_buffer_ref(pkt->buf);
+ if (!opkt.buf)
exit_program(1);
- }
- if (ret) {
- opkt.buf = av_buffer_create(opkt.data, opkt.size, av_buffer_default_free, NULL, 0);
- if (!opkt.buf)
- exit_program(1);
- }
- } else {
- opkt.data = pkt->data;
- opkt.size = pkt->size;
}
+ opkt.data = pkt->data;
+ opkt.size = pkt->size;
+
av_copy_packet_side_data(&opkt, pkt);
output_packet(of, &opkt, ost, 0);
ret = reap_filters(1);
if (ret < 0 && ret != AVERROR_EOF) {
- char errbuf[128];
- av_strerror(ret, errbuf, sizeof(errbuf));
-
- av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", errbuf);
+ av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret));
return ret;
}
static int ifilter_send_eof(InputFilter *ifilter, int64_t pts)
{
- int i, j, ret;
+ int ret;
ifilter->eof = 1;
return ret;
} else {
// the filtergraph was never configured
- FilterGraph *fg = ifilter->graph;
- for (i = 0; i < fg->nb_inputs; i++)
- if (!fg->inputs[i]->eof)
- break;
- if (i == fg->nb_inputs) {
- // All the input streams have finished without the filtergraph
- // ever being configured.
- // Mark the output streams as finished.
- for (j = 0; j < fg->nb_outputs; j++)
- finish_output_stream(fg->outputs[j]->ost);
+ if (ifilter->format < 0)
+ ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar);
+ if (ifilter->format < 0 && (ifilter->type == AVMEDIA_TYPE_AUDIO || ifilter->type == AVMEDIA_TYPE_VIDEO)) {
+ av_log(NULL, AV_LOG_ERROR, "Cannot determine format of input stream %d:%d after EOF\n", ifilter->ist->file_index, ifilter->ist->st->index);
+ return AVERROR_INVALIDDATA;
}
}
av_display_rotation_set((int32_t *)sd, -ost->rotate_override_value);
}
- ost->parser = av_parser_init(par_dst->codec_id);
- ost->parser_avctx = avcodec_alloc_context3(NULL);
- if (!ost->parser_avctx)
- return AVERROR(ENOMEM);
-
switch (par_dst->codec_type) {
case AVMEDIA_TYPE_AUDIO:
if (audio_volume != 256) {
av_buffersink_set_frame_size(ost->filter->filter,
ost->enc_ctx->frame_size);
assert_avoptions(ost->encoder_opts);
- if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000)
+ if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000 &&
+ ost->enc_ctx->codec_id != AV_CODEC_ID_CODEC2 /* don't complain about 700 bit/s modes */)
av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
" It takes bits/s as argument, not kbits/s\n");
ret = init_output_stream_streamcopy(ost);
if (ret < 0)
return ret;
-
- /*
- * FIXME: will the codec context used by the parser during streamcopy
- * This should go away with the new parser API.
- */
- ret = avcodec_parameters_to_context(ost->parser_avctx, ost->st->codecpar);
- if (ret < 0)
- return ret;
}
// parse user provided disposition, and update stream values
{ "clean_effects" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CLEAN_EFFECTS }, .unit = "flags" },
{ "captions" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CAPTIONS }, .unit = "flags" },
{ "descriptions" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DESCRIPTIONS }, .unit = "flags" },
+ { "dependent" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEPENDENT }, .unit = "flags" },
{ "metadata" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_METADATA }, .unit = "flags" },
{ NULL },
};
ist = input_streams[ifile->ist_index + i];
avctx = ist->dec_ctx;
- // flush decoders
- if (ist->decoding_needed) {
- process_input_packet(ist, NULL, 1);
- avcodec_flush_buffers(avctx);
- }
-
/* duration is the length of the last frame in a stream
* when audio stream is present we don't care about
* last video frame length because it's not defined exactly */
return ret;
}
if (ret < 0 && ifile->loop) {
+ AVCodecContext *avctx;
+ for (i = 0; i < ifile->nb_streams; i++) {
+ ist = input_streams[ifile->ist_index + i];
+ avctx = ist->dec_ctx;
+ if (ist->decoding_needed) {
+ ret = process_input_packet(ist, NULL, 1);
+ if (ret>0)
+ return 0;
+ avcodec_flush_buffers(avctx);
+ }
+ }
ret = seek_to_start(ifile, is);
if (ret < 0)
av_log(NULL, AV_LOG_WARNING, "Seek to start failed.\n");
ret = transcode_step();
if (ret < 0 && ret != AVERROR_EOF) {
- char errbuf[128];
- av_strerror(ret, errbuf, sizeof(errbuf));
-
- av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", errbuf);
+ av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret));
break;
}
argv++;
}
- avcodec_register_all();
#if CONFIG_AVDEVICE
avdevice_register_all();
#endif
- avfilter_register_all();
- av_register_all();
avformat_network_init();
show_banner(argc, argv, options);