static int input_sync;
static uint64_t limit_filesize = 0;
static int force_fps = 0;
+static char *forced_key_frames = NULL;
static int pgmyuv_compatibility_hack=0;
static float dts_delta_threshold = 10;
int original_height;
int original_width;
+ /* forced key frames */
+ int64_t *forced_kf_pts;
+ int forced_kf_count;
+ int forced_kf_index;
+
/* audio only */
int audio_resample;
ReSampleContext *resample; /* for audio resampling */
#if CONFIG_AVFILTER
-static int get_filtered_video_pic(AVFilterContext *ctx,
- AVFilterBufferRef **picref, AVFrame *pic2,
- uint64_t *pts)
-{
- AVFilterBufferRef *pic;
-
- if(avfilter_request_frame(ctx->inputs[0]))
- return -1;
- if(!(pic = ctx->inputs[0]->cur_buf))
- return -1;
- *picref = pic;
- ctx->inputs[0]->cur_buf = NULL;
-
- *pts = pic->pts;
-
- memcpy(pic2->data, pic->data, sizeof(pic->data));
- memcpy(pic2->linesize, pic->linesize, sizeof(pic->linesize));
- pic2->interlaced_frame = pic->video->interlaced;
- pic2->top_field_first = pic->video->top_field_first;
-
- return 1;
-}
-
static int configure_filters(AVInputStream *ist, AVOutputStream *ost)
{
AVFilterContext *last_filter, *filter;
{
int nb_frames, i, ret;
AVFrame *final_picture, *formatted_picture, *resampling_dst, *padding_src;
- AVFrame picture_crop_temp, picture_pad_temp;
AVCodecContext *enc, *dec;
double sync_ipts;
- avcodec_get_frame_defaults(&picture_crop_temp);
- avcodec_get_frame_defaults(&picture_pad_temp);
-
enc = ost->st->codec;
dec = ist->st->codec;
big_picture.pts= ost->sync_opts;
// big_picture.pts= av_rescale(ost->sync_opts, AV_TIME_BASE*(int64_t)enc->time_base.num, enc->time_base.den);
//av_log(NULL, AV_LOG_DEBUG, "%"PRId64" -> encoder\n", ost->sync_opts);
+ if (ost->forced_kf_index < ost->forced_kf_count &&
+ big_picture.pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
+ big_picture.pict_type = FF_I_TYPE;
+ ost->forced_kf_index++;
+ }
ret = avcodec_encode_video(enc,
bit_buffer, bit_buffer_size,
&big_picture);
if (start_time == 0 || ist->pts >= start_time)
#if CONFIG_AVFILTER
while (frame_available) {
+ AVRational ist_pts_tb;
if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->output_video_filter)
- get_filtered_video_pic(ist->output_video_filter, &ist->picref, &picture, &ist->pts);
+ get_filtered_video_frame(ist->output_video_filter, &picture, &ist->picref, &ist_pts_tb);
+ if (ist->picref)
+ ist->pts = ist->picref->pts;
#endif
for(i=0;i<nb_ostreams;i++) {
int frame_size;
return 0;
}
+static void parse_forced_key_frames(char *kf, AVOutputStream *ost,
+ AVCodecContext *avctx)
+{
+ char *p;
+ int n = 1, i;
+ int64_t t;
+
+ 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) {
+ av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
+ ffmpeg_exit(1);
+ }
+ for (i = 0; i < n; i++) {
+ p = i ? strchr(p, ',') + 1 : kf;
+ 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);
+ }
+}
+
/*
* The following code is the main loop of the file converter
*/
av_fifo_free(ost->fifo); /* works even if fifo is not
initialized but set to zero */
av_free(ost->pict_tmp.data[0]);
+ av_free(ost->forced_kf_pts);
if (ost->video_resample)
sws_freeContext(ost->img_resample_ctx);
if (ost->resample)
video_enc->flags |= CODEC_FLAG_PASS2;
}
}
+
+ if (forced_key_frames)
+ parse_forced_key_frames(forced_key_frames, ost, video_enc);
}
if (video_language) {
av_metadata_set2(&st->metadata, "language", video_language, 0);
/* reset some key parameters */
video_disable = 0;
av_freep(&video_codec_name);
+ av_freep(&forced_key_frames);
video_stream_copy = 0;
frame_pix_fmt = PIX_FMT_NONE;
}
set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL);
nb_streamid_map = 0;
+ av_freep(&forced_key_frames);
}
/* same option as mencoder */
{ "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" },
{ "force_fps", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&force_fps}, "force the selected framerate, disable the best supported framerate selection" },
{ "streamid", OPT_FUNC2 | HAS_ARG | OPT_EXPERT, {(void*)opt_streamid}, "set the value of an outfile streamid", "streamIndex:value" },
+ { "force_key_frames", OPT_STRING | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void *)&forced_key_frames}, "force key frames at specified timestamps", "timestamps" },
/* audio options */
{ "ab", OPT_FUNC2 | HAS_ARG | OPT_AUDIO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" },