static FILE *vstats_file;
+const char *const forced_keyframes_const_names[] = {
+ "n",
+ "n_forced",
+ "prev_forced_n",
+ "prev_forced_t",
+ "t",
+ NULL
+};
+
static void do_video_stats(OutputStream *ost, int frame_size);
static int64_t getutime(void);
avcodec_free_frame(&output_streams[i]->filtered_frame);
av_freep(&output_streams[i]->forced_keyframes);
+ av_expr_free(output_streams[i]->forced_keyframes_pexpr);
av_freep(&output_streams[i]->avfilter);
av_freep(&output_streams[i]->logfile_prefix);
av_freep(&output_streams[i]);
video_size += pkt.size;
write_frame(s, &pkt, ost);
} else {
- int got_packet;
+ int got_packet, forced_keyframe = 0;
AVFrame big_picture;
+ double pts_time;
big_picture = *in_picture;
/* better than nothing: use input picture interlaced
big_picture.quality = ost->st->codec->global_quality;
if (!enc->me_threshold)
big_picture.pict_type = 0;
+
+ pts_time = big_picture.pts != AV_NOPTS_VALUE ?
+ big_picture.pts * av_q2d(enc->time_base) : NAN;
if (ost->forced_kf_index < ost->forced_kf_count &&
big_picture.pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
- big_picture.pict_type = AV_PICTURE_TYPE_I;
ost->forced_kf_index++;
+ forced_keyframe = 1;
+ } else if (ost->forced_keyframes_pexpr) {
+ double res;
+ ost->forced_keyframes_expr_const_values[FKF_T] = pts_time;
+ res = av_expr_eval(ost->forced_keyframes_pexpr,
+ ost->forced_keyframes_expr_const_values, NULL);
+ av_dlog(NULL, "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n",
+ ost->forced_keyframes_expr_const_values[FKF_N],
+ ost->forced_keyframes_expr_const_values[FKF_N_FORCED],
+ ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N],
+ ost->forced_keyframes_expr_const_values[FKF_T],
+ ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T],
+ res);
+ if (res) {
+ forced_keyframe = 1;
+ ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N] =
+ ost->forced_keyframes_expr_const_values[FKF_N];
+ ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T] =
+ ost->forced_keyframes_expr_const_values[FKF_T];
+ ost->forced_keyframes_expr_const_values[FKF_N_FORCED] += 1;
+ }
+
+ ost->forced_keyframes_expr_const_values[FKF_N] += 1;
+ }
+ if (forced_keyframe) {
+ big_picture.pict_type = AV_PICTURE_TYPE_I;
+ av_log(NULL, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time);
}
+
update_benchmark(NULL);
ret = avcodec_encode_video2(enc, &pkt, &big_picture, &got_packet);
update_benchmark("encode_video %d.%d", ost->file_index, ost->index);
if (!dec->channel_layout) {
char layout_name[256];
+ if (dec->channels > ist->guess_layout_max)
+ return 0;
dec->channel_layout = av_get_default_channel_layout(dec->channels);
if (!dec->channel_layout)
return 0;
static void print_sdp(void)
{
- char sdp[2048];
+ char sdp[16384];
int i;
AVFormatContext **avc = av_malloc(sizeof(*avc) * nb_output_files);
return NULL;
}
+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;
+}
+
static void parse_forced_key_frames(char *kf, OutputStream *ost,
AVCodecContext *avctx)
{
char *p;
- int n = 1, i;
- int64_t t;
+ int n = 1, i, size, index = 0;
+ int64_t t, *pts;
for (p = kf; *p; p++)
if (*p == ',')
n++;
- ost->forced_kf_count = n;
- ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n);
- if (!ost->forced_kf_pts) {
+ size = n;
+ pts = av_malloc(sizeof(*pts) * size);
+ if (!pts) {
av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
exit(1);
}
if (next)
*next++ = 0;
- t = parse_time_or_die("force_key_frames", p, 1);
- ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
+ if (!memcmp(p, "chapters", 8)) {
+
+ AVFormatContext *avf = output_files[ost->file_index]->ctx;
+ int j;
+
+ if (avf->nb_chapters > INT_MAX - size ||
+ !(pts = av_realloc_f(pts, size += avf->nb_chapters - 1,
+ sizeof(*pts)))) {
+ av_log(NULL, AV_LOG_FATAL,
+ "Could not allocate forced key frames array.\n");
+ exit(1);
+ }
+ t = p[8] ? parse_time_or_die("force_key_frames", p + 8, 1) : 0;
+ t = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
+
+ for (j = 0; j < avf->nb_chapters; j++) {
+ AVChapter *c = avf->chapters[j];
+ av_assert1(index < size);
+ pts[index++] = av_rescale_q(c->start, c->time_base,
+ avctx->time_base) + t;
+ }
+
+ } else {
+
+ t = parse_time_or_die("force_key_frames", p, 1);
+ av_assert1(index < size);
+ pts[index++] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
+
+ }
p = next;
}
+
+ av_assert0(index == size);
+ qsort(pts, size, sizeof(*pts), compare_int64);
+ ost->forced_kf_count = size;
+ ost->forced_kf_pts = pts;
}
static void report_new_stream(int input_index, AVPacket *pkt)
codec->codec_type = icodec->codec_type;
if (!codec->codec_tag) {
+ unsigned int codec_tag;
if (!oc->oformat->codec_tag ||
av_codec_get_id (oc->oformat->codec_tag, icodec->codec_tag) == codec->codec_id ||
- av_codec_get_tag(oc->oformat->codec_tag, icodec->codec_id) <= 0)
+ !av_codec_get_tag2(oc->oformat->codec_tag, icodec->codec_id, &codec_tag))
codec->codec_tag = icodec->codec_tag;
}
codec->time_base.num *= icodec->ticks_per_frame;
}
}
+ if ( codec->codec_tag == AV_RL32("tmcd")
+ && icodec->time_base.num < icodec->time_base.den
+ && icodec->time_base.num > 0
+ && 121LL*icodec->time_base.num > icodec->time_base.den) {
+ codec->time_base = icodec->time_base;
+ }
if(ost->frame_rate.num)
codec->time_base = av_inv_q(ost->frame_rate);
codec->sample_fmt = ost->filter->filter->inputs[0]->format;
codec->sample_rate = ost->filter->filter->inputs[0]->sample_rate;
codec->channel_layout = ost->filter->filter->inputs[0]->channel_layout;
- codec->channels = av_get_channel_layout_nb_channels(codec->channel_layout);
+ codec->channels = avfilter_link_get_channels(ost->filter->filter->inputs[0]);
codec->time_base = (AVRational){ 1, codec->sample_rate };
break;
case AVMEDIA_TYPE_VIDEO:
codec->bits_per_raw_sample = frame_bits_per_raw_sample;
}
- if (ost->forced_keyframes)
- parse_forced_key_frames(ost->forced_keyframes, ost,
- ost->st->codec);
+ if (ost->forced_keyframes) {
+ if (!strncmp(ost->forced_keyframes, "expr:", 5)) {
+ ret = av_expr_parse(&ost->forced_keyframes_pexpr, ost->forced_keyframes+5,
+ forced_keyframes_const_names, NULL, NULL, NULL, NULL, 0, NULL);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Invalid force_key_frames expression '%s'\n", ost->forced_keyframes+5);
+ return ret;
+ }
+ ost->forced_keyframes_expr_const_values[FKF_N] = 0;
+ ost->forced_keyframes_expr_const_values[FKF_N_FORCED] = 0;
+ ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N] = NAN;
+ ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T] = NAN;
+ } else {
+ parse_forced_key_frames(ost->forced_keyframes, ost, ost->st->codec);
+ }
+ }
break;
case AVMEDIA_TYPE_SUBTITLE:
codec->time_base = (AVRational){1, 1000};