diff --git a/ext/vpx/gstvp8enc.c b/ext/vpx/gstvp8enc.c index 083c5902f1..7513943a66 100644 --- a/ext/vpx/gstvp8enc.c +++ b/ext/vpx/gstvp8enc.c @@ -805,7 +805,6 @@ gst_vp8_enc_finalize (GObject * object) g_mutex_clear (&gst_vp8_enc->encoder_lock); G_OBJECT_CLASS (parent_class)->finalize (object); - } static void @@ -1877,15 +1876,19 @@ gst_vp8_enc_drain (GstVideoEncoder * video_encoder) int flags = 0; vpx_codec_err_t status; gint64 deadline; + vpx_codec_pts_t pts; encoder = GST_VP8_ENC (video_encoder); g_mutex_lock (&encoder->encoder_lock); deadline = encoder->deadline; - status = - vpx_codec_encode (&encoder->encoder, NULL, encoder->n_frames, 1, flags, - deadline); + pts = + gst_util_uint64_scale (encoder->last_pts, + encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND, + encoder->cfg.g_timebase.den); + + status = vpx_codec_encode (&encoder->encoder, NULL, pts, 1, flags, deadline); g_mutex_unlock (&encoder->encoder_lock); if (status != 0) { @@ -1917,11 +1920,18 @@ gst_vp8_enc_drain (GstVideoEncoder * video_encoder) static GstFlowReturn gst_vp8_enc_finish (GstVideoEncoder * video_encoder) { + GstVP8Enc *encoder; GstFlowReturn ret; GST_DEBUG_OBJECT (video_encoder, "finish"); - ret = gst_vp8_enc_drain (video_encoder); + encoder = GST_VP8_ENC (video_encoder); + + if (encoder->inited) { + ret = gst_vp8_enc_drain (video_encoder); + } else { + ret = GST_FLOW_OK; + } return ret; } @@ -1954,13 +1964,13 @@ gst_vp8_enc_handle_frame (GstVideoEncoder * video_encoder, vpx_image_t *image; GstVP8EncUserData *user_data; GstVideoFrame vframe; + vpx_codec_pts_t pts; + unsigned long duration; GST_DEBUG_OBJECT (video_encoder, "handle_frame"); encoder = GST_VP8_ENC (video_encoder); - encoder->n_frames++; - GST_DEBUG_OBJECT (video_encoder, "size %d %d", GST_VIDEO_INFO_WIDTH (&encoder->input_state->info), GST_VIDEO_INFO_HEIGHT (&encoder->input_state->info)); @@ -1979,8 +1989,25 @@ gst_vp8_enc_handle_frame (GstVideoEncoder * video_encoder, } g_mutex_lock (&encoder->encoder_lock); + pts = + gst_util_uint64_scale (frame->pts, + encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND, + encoder->cfg.g_timebase.den); + encoder->last_pts = frame->pts; + + if (frame->duration != GST_CLOCK_TIME_NONE) { + duration = + gst_util_uint64_scale (frame->duration, + encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND, + encoder->cfg.g_timebase.den); + encoder->last_pts += frame->duration; + } else { + duration = 1; + } + status = vpx_codec_encode (&encoder->encoder, image, - encoder->n_frames, 1, flags, encoder->deadline); + pts, duration, flags, encoder->deadline); + g_mutex_unlock (&encoder->encoder_lock); gst_video_frame_unmap (&vframe); diff --git a/ext/vpx/gstvp8enc.h b/ext/vpx/gstvp8enc.h index 206ac02a47..d70f383a38 100644 --- a/ext/vpx/gstvp8enc.h +++ b/ext/vpx/gstvp8enc.h @@ -102,7 +102,7 @@ struct _GstVP8Enc vpx_image_t image; - int n_frames; + GstClockTime last_pts; int keyframe_distance; GstVideoCodecState *input_state; diff --git a/ext/vpx/gstvp9enc.c b/ext/vpx/gstvp9enc.c index 7a18e6102e..2f88984a97 100644 --- a/ext/vpx/gstvp9enc.c +++ b/ext/vpx/gstvp9enc.c @@ -780,7 +780,6 @@ gst_vp9_enc_finalize (GObject * object) g_mutex_clear (&gst_vp9_enc->encoder_lock); G_OBJECT_CLASS (parent_class)->finalize (object); - } static void @@ -1816,15 +1815,19 @@ gst_vp9_enc_drain (GstVideoEncoder * video_encoder) int flags = 0; vpx_codec_err_t status; gint64 deadline; + vpx_codec_pts_t pts; encoder = GST_VP9_ENC (video_encoder); g_mutex_lock (&encoder->encoder_lock); deadline = encoder->deadline; - status = - vpx_codec_encode (&encoder->encoder, NULL, encoder->n_frames, 1, flags, - deadline); + pts = + gst_util_uint64_scale (encoder->last_pts, + encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND, + encoder->cfg.g_timebase.den); + + status = vpx_codec_encode (&encoder->encoder, NULL, pts, 0, flags, deadline); g_mutex_unlock (&encoder->encoder_lock); if (status != 0) { @@ -1856,11 +1859,18 @@ gst_vp9_enc_drain (GstVideoEncoder * video_encoder) static GstFlowReturn gst_vp9_enc_finish (GstVideoEncoder * video_encoder) { + GstVP9Enc *encoder; GstFlowReturn ret; GST_DEBUG_OBJECT (video_encoder, "finish"); - ret = gst_vp9_enc_drain (video_encoder); + encoder = GST_VP9_ENC (video_encoder); + + if (encoder->inited) { + ret = gst_vp9_enc_drain (video_encoder); + } else { + ret = GST_FLOW_OK; + } return ret; } @@ -1892,13 +1902,13 @@ gst_vp9_enc_handle_frame (GstVideoEncoder * video_encoder, int flags = 0; vpx_image_t *image; GstVideoFrame vframe; + vpx_codec_pts_t pts; + unsigned long duration; GST_DEBUG_OBJECT (video_encoder, "handle_frame"); encoder = GST_VP9_ENC (video_encoder); - encoder->n_frames++; - GST_DEBUG_OBJECT (video_encoder, "size %d %d", GST_VIDEO_INFO_WIDTH (&encoder->input_state->info), GST_VIDEO_INFO_HEIGHT (&encoder->input_state->info)); @@ -1912,8 +1922,25 @@ gst_vp9_enc_handle_frame (GstVideoEncoder * video_encoder, } g_mutex_lock (&encoder->encoder_lock); + pts = + gst_util_uint64_scale (frame->pts, + encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND, + encoder->cfg.g_timebase.den); + encoder->last_pts = frame->pts; + + if (frame->duration != GST_CLOCK_TIME_NONE) { + duration = + gst_util_uint64_scale (frame->duration, + encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND, + encoder->cfg.g_timebase.den); + encoder->last_pts += frame->duration; + } else { + duration = 1; + } + status = vpx_codec_encode (&encoder->encoder, image, - encoder->n_frames, 1, flags, encoder->deadline); + pts, duration, flags, encoder->deadline); + g_mutex_unlock (&encoder->encoder_lock); gst_video_frame_unmap (&vframe); diff --git a/ext/vpx/gstvp9enc.h b/ext/vpx/gstvp9enc.h index b991905796..7851f1a32e 100644 --- a/ext/vpx/gstvp9enc.h +++ b/ext/vpx/gstvp9enc.h @@ -102,8 +102,7 @@ struct _GstVP9Enc vpx_image_t image; - int n_frames; - + GstClockTime last_pts; GstVideoCodecState *input_state; };