#define HURRY_UP_GUARD2 (300000)
#define HURRY_UP_GUARD3 (100000)
+#define MAX_FRAME_DELAY (FF_MAX_B_FRAMES + 2)
+
/*****************************************************************************
* Local prototypes
*****************************************************************************/
vlc_bool_t b_mpeg4_matrix;
vlc_bool_t b_trellis;
int i_quality; /* for VBR */
+
+ /* Used to work around stupid timestamping behaviour in libavcodec */
+ uint64_t i_framenum;
+ mtime_t pi_delay_pts[MAX_FRAME_DELAY];
};
static const char *ppsz_enc_options[] = {
msg_Err( p_enc, "out of memory" );
return VLC_EGENERIC;
}
+ memset( p_sys, 0, sizeof(encoder_sys_t) );
p_enc->p_sys = p_sys;
p_sys->p_codec = p_codec;
p_sys->p_buffer_out = NULL;
p_sys->p_buffer = NULL;
- p_sys->b_inited = 0;
p_sys->p_context = p_context = avcodec_alloc_context();
if( p_sys->i_key_int > 0 )
p_context->gop_size = p_sys->i_key_int;
p_context->max_b_frames =
- __MIN( p_sys->i_b_frames, FF_MAX_B_FRAMES );
+ __MAX( __MIN( p_sys->i_b_frames, FF_MAX_B_FRAMES ), 0 );
p_context->b_frame_strategy = 0;
#if LIBAVCODEC_BUILD >= 4687
p_sys->p_buffer = malloc( p_sys->i_frame_size );
}
- p_sys->i_last_ref_pts = 0;
- p_sys->i_buggy_pts_detect = 0;
- p_sys->i_samples_delay = 0;
- p_sys->i_pts = 0;
- p_sys->i_last_pts = 0;
-
msg_Dbg( p_enc, "found encoder %s", psz_namecodec );
return VLC_SUCCESS;
frame.quality = p_sys->i_quality;
+ /* Ugly work-around for stupid libavcodec behaviour */
+#if LIBAVCODEC_BUILD >= 4722
+ p_sys->i_framenum++;
+ p_sys->pi_delay_pts[p_sys->i_framenum % MAX_FRAME_DELAY] = frame.pts;
+ frame.pts = p_sys->i_framenum * AV_TIME_BASE *
+ p_enc->fmt_in.video.i_frame_rate_base;
+ frame.pts += p_enc->fmt_in.video.i_frame_rate - 1;
+ frame.pts /= p_enc->fmt_in.video.i_frame_rate;
+#endif
+ /* End work-around */
+
i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out,
AVCODEC_MAX_VIDEO_FRAME_SIZE, &frame );
block_t *p_block = block_New( p_enc, i_out );
memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
- if( p_sys->p_context->coded_frame->pts != AV_NOPTS_VALUE &&
+ /* FIXME, 3-2 pulldown is not handled correctly */
+ p_block->i_length = I64C(1000000) *
+ p_enc->fmt_in.video.i_frame_rate_base /
+ p_enc->fmt_in.video.i_frame_rate;
+
+ if( !p_sys->p_context->max_b_frames || !p_sys->p_context->delay )
+ {
+ /* No delay -> output pts == input pts */
+ p_block->i_pts = p_block->i_dts = p_pict->date;
+ }
+ else if( p_sys->p_context->coded_frame->pts != AV_NOPTS_VALUE &&
p_sys->p_context->coded_frame->pts != 0 &&
p_sys->i_buggy_pts_detect != p_sys->p_context->coded_frame->pts )
{
p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts;
+ p_block->i_pts = p_sys->p_context->coded_frame->pts;
- /* FIXME, 3-2 pulldown is not handled correctly */
- p_block->i_length = I64C(1000000) *
- p_enc->fmt_in.video.i_frame_rate_base /
- p_enc->fmt_in.video.i_frame_rate;
- p_block->i_pts = p_sys->p_context->coded_frame->pts;
+ /* Ugly work-around for stupid libavcodec behaviour */
+#if LIBAVCODEC_BUILD >= 4722
+ {
+ int64_t i_framenum = p_block->i_pts *
+ p_enc->fmt_in.video.i_frame_rate /
+ p_enc->fmt_in.video.i_frame_rate_base / AV_TIME_BASE;
- if( !p_sys->p_context->delay ||
- ( p_sys->p_context->coded_frame->pict_type != FF_I_TYPE &&
- p_sys->p_context->coded_frame->pict_type != FF_P_TYPE ) )
+ p_block->i_pts = p_sys->pi_delay_pts[i_framenum % MAX_FRAME_DELAY];
+ }
+#endif
+ /* End work-around */
+
+ if( p_sys->p_context->coded_frame->pict_type != FF_I_TYPE &&
+ p_sys->p_context->coded_frame->pict_type != FF_P_TYPE )
{
p_block->i_dts = p_block->i_pts;
}
{
/* Buggy libavcodec which doesn't update coded_frame->pts
* correctly */
- p_block->i_length = I64C(1000000) *
- p_enc->fmt_in.video.i_frame_rate_base /
- p_enc->fmt_in.video.i_frame_rate;
p_block->i_dts = p_block->i_pts = p_pict->date;
}