*/
if (!(avctx->codec_type == AVMEDIA_TYPE_VIDEO && avctx->codec)) {
if (ost->frame_number >= ost->max_frames) {
- av_free_packet(pkt);
+ av_packet_unref(pkt);
return;
}
ost->frame_number++;
else
ost->error[i] = -1;
}
+
+ if (ost->frame_rate.num && ost->is_cfr) {
+ if (pkt->duration > 0)
+ av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
+ pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
+ ost->st->time_base);
+ }
}
if (bsfc)
if (a > 0) {
pkt->side_data = NULL;
pkt->side_data_elems = 0;
- av_free_packet(pkt);
+ av_packet_unref(pkt);
new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
av_buffer_default_free, NULL, 0);
if (!new_pkt.buf)
main_return_code = 1;
close_all_output_streams(ost, MUXER_FINISHED | ENCODER_FINISHED, ENCODER_FINISHED);
}
- av_free_packet(pkt);
+ av_packet_unref(pkt);
}
static void close_output_stream(OutputStream *ost)
ost->last_nb0_frames[1],
ost->last_nb0_frames[2]);
} else {
- delta0 = sync_ipts - ost->sync_opts;
+ delta0 = sync_ipts - ost->sync_opts; // delta0 is the "drift" between the input frame (next_picture) and where it would fall in the output.
delta = delta0 + duration;
/* by default, we output a single frame */
- nb0_frames = 0;
+ nb0_frames = 0; // tracks the number of times the PREVIOUS frame should be duplicated, mostly for variable framerate (VFR)
nb_frames = 1;
format_video_sync = video_sync_method;
format_video_sync = VSYNC_VSCFR;
}
}
+ ost->is_cfr = (format_video_sync == VSYNC_CFR || format_video_sync == VSYNC_VSCFR);
if (delta0 < 0 &&
delta > 0 &&
format_video_sync != VSYNC_PASSTHROUGH &&
format_video_sync != VSYNC_DROP) {
- double cor = FFMIN(-delta0, duration);
if (delta0 < -0.6) {
av_log(NULL, AV_LOG_WARNING, "Past duration %f too large\n", -delta0);
} else
- av_log(NULL, AV_LOG_DEBUG, "Cliping frame in rate conversion by %f\n", -delta0);
- sync_ipts += cor;
- duration -= cor;
- delta0 += cor;
+ av_log(NULL, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0);
+ sync_ipts = ost->sync_opts;
+ duration += delta0;
+ delta0 = 0;
}
switch (format_video_sync) {
case VSYNC_VSCFR:
- if (ost->frame_number == 0 && delta - duration >= 0.5) {
- av_log(NULL, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta - duration));
+ if (ost->frame_number == 0 && delta0 >= 0.5) {
+ av_log(NULL, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0));
delta = duration;
delta0 = 0;
ost->sync_opts = lrint(sync_ipts);
sizeof(ost->last_nb0_frames[0]) * (FF_ARRAY_ELEMS(ost->last_nb0_frames) - 1));
ost->last_nb0_frames[0] = nb0_frames;
- if (nb0_frames == 0 && ost->last_droped) {
+ if (nb0_frames == 0 && ost->last_dropped) {
nb_frames_drop++;
av_log(NULL, AV_LOG_VERBOSE,
"*** dropping frame %d from stream %d at ts %"PRId64"\n",
ost->frame_number, ost->st->index, ost->last_frame->pts);
}
- if (nb_frames > (nb0_frames && ost->last_droped) + (nb_frames > nb0_frames)) {
+ if (nb_frames > (nb0_frames && ost->last_dropped) + (nb_frames > nb0_frames)) {
if (nb_frames > dts_error_threshold * 30) {
av_log(NULL, AV_LOG_ERROR, "%d frame duplication too large, skipping\n", nb_frames - 1);
nb_frames_drop++;
return;
}
- nb_frames_dup += nb_frames - (nb0_frames && ost->last_droped) - (nb_frames > nb0_frames);
+ nb_frames_dup += nb_frames - (nb0_frames && ost->last_dropped) - (nb_frames > nb0_frames);
av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1);
}
- ost->last_droped = nb_frames == nb0_frames && next_picture;
+ ost->last_dropped = nb_frames == nb0_frames && next_picture;
/* duplicates frame if needed */
for (i = 0; i < nb_frames; i++) {
static double psnr(double d)
{
- return -10.0 * log(d) / log(10.0);
+ return -10.0 * log10(d);
}
static void do_video_stats(OutputStream *ost, int frame_size)
pts = FFMAX(pts, av_rescale_q(av_stream_get_end_pts(ost->st),
ost->st->time_base, AV_TIME_BASE_Q));
if (is_last_report)
- nb_frames_drop += ost->last_droped;
+ nb_frames_drop += ost->last_dropped;
}
secs = FFABS(pts) / AV_TIME_BASE;
break;
}
if (ost->finished & MUXER_FINISHED) {
- av_free_packet(&pkt);
+ av_packet_unref(&pkt);
continue;
}
av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
InputFile *f = input_files [ist->file_index];
int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
int64_t ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost->st->time_base);
- int64_t ist_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ist->st->time_base);
AVPicture pict;
AVPacket opkt;
!ost->copy_initial_nonkeyframes)
return;
- if (pkt->pts == AV_NOPTS_VALUE) {
- if (!ost->frame_number && ist->pts < start_time &&
- !ost->copy_prior_start)
- return;
- } else {
- if (!ost->frame_number && pkt->pts < ist_tb_start_time &&
- !ost->copy_prior_start)
+ if (!ost->frame_number && !ost->copy_prior_start) {
+ int64_t comp_start = start_time;
+ if (copy_ts && f->start_time != AV_NOPTS_VALUE)
+ comp_start = FFMAX(start_time, f->start_time + f->ts_offset);
+ if (pkt->pts == AV_NOPTS_VALUE ?
+ ist->pts < comp_start :
+ pkt->pts < av_rescale_q(comp_start, AV_TIME_BASE_Q, ist->st->time_base))
return;
}
}
}
+ if (!j)
+ goto fail;
+
av_sdp_create(avc, j, sdp, sizeof(sdp));
if (!sdp_filename) {
}
}
+fail:
av_freep(&avc);
}
static int compare_int64(const void *a, const void *b)
{
- int64_t va = *(int64_t *)a, vb = *(int64_t *)b;
- return va < vb ? -1 : va > vb ? +1 : 0;
+ return FFDIFFSIGN(*(const int64_t *)a, *(const int64_t *)b);
}
static int init_output_stream(OutputStream *ost, char *error, int error_len)
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
for (i = 0; i < nb_output_streams; i++) {
OutputStream *ost = output_streams[i];
- int64_t opts = av_rescale_q(ost->st->cur_dts, ost->st->time_base,
+ int64_t opts = ost->st->cur_dts == AV_NOPTS_VALUE ? INT64_MIN :
+ av_rescale_q(ost->st->cur_dts, ost->st->time_base,
AV_TIME_BASE_Q);
+ if (ost->st->cur_dts == AV_NOPTS_VALUE)
+ av_log(NULL, AV_LOG_DEBUG, "cur_dts is invalid (this is harmless if it occurs once at the start per stream)\n");
+
if (!ost->finished && opts < opts_min) {
opts_min = opts;
ost_min = ost->unavailable ? NULL : ost;
av_thread_message_queue_set_err_recv(f->in_thread_queue, ret);
break;
}
- av_dup_packet(&pkt);
ret = av_thread_message_queue_send(f->in_thread_queue, &pkt, flags);
if (flags && ret == AVERROR(EAGAIN)) {
flags = 0;
av_log(f->ctx, AV_LOG_ERROR,
"Unable to send packet to main thread: %s\n",
av_err2str(ret));
- av_free_packet(&pkt);
+ av_packet_unref(&pkt);
av_thread_message_queue_set_err_recv(f->in_thread_queue, ret);
break;
}
continue;
av_thread_message_queue_set_err_send(f->in_thread_queue, AVERROR_EOF);
while (av_thread_message_queue_recv(f->in_thread_queue, &pkt, 0) >= 0)
- av_free_packet(&pkt);
+ av_packet_unref(&pkt);
pthread_join(f->thread, NULL);
f->joined = 1;
ifile->time_base);
}
- ifile->loop--;
+ if (ifile->loop > 0)
+ ifile->loop--;
return ret;
}
ifile->eagain = 1;
return ret;
}
- if ((ret < 0) && (ifile->loop > 1)) {
+ if (ret < 0 && ifile->loop) {
if ((ret = seek_to_start(ifile, is)) < 0)
return ret;
ret = get_input_packet(ifile, &pkt);
process_input_packet(ist, &pkt, 0);
discard_packet:
- av_free_packet(&pkt);
+ av_packet_unref(&pkt);
return 0;
}