vp9enc: Allow caps renegotiation

https://bugzilla.gnome.org/show_bug.cgi?id=726329
This commit is contained in:
Sebastian Dröge 2014-09-30 11:31:43 +03:00
parent ced5d657e3
commit df053c997c

View file

@ -345,9 +345,10 @@ static gboolean gst_vp9_enc_start (GstVideoEncoder * encoder);
static gboolean gst_vp9_enc_stop (GstVideoEncoder * encoder); static gboolean gst_vp9_enc_stop (GstVideoEncoder * encoder);
static gboolean gst_vp9_enc_set_format (GstVideoEncoder * static gboolean gst_vp9_enc_set_format (GstVideoEncoder *
video_encoder, GstVideoCodecState * state); video_encoder, GstVideoCodecState * state);
static gboolean gst_vp9_enc_finish (GstVideoEncoder * video_encoder); static GstFlowReturn gst_vp9_enc_finish (GstVideoEncoder * video_encoder);
static GstFlowReturn gst_vp9_enc_handle_frame (GstVideoEncoder * static GstFlowReturn gst_vp9_enc_handle_frame (GstVideoEncoder *
video_encoder, GstVideoCodecFrame * frame); video_encoder, GstVideoCodecFrame * frame);
static GstFlowReturn gst_vp9_enc_drain (GstVideoEncoder * video_encoder);
static gboolean gst_vp9_enc_sink_event (GstVideoEncoder * static gboolean gst_vp9_enc_sink_event (GstVideoEncoder *
video_encoder, GstEvent * event); video_encoder, GstEvent * event);
static gboolean gst_vp9_enc_propose_allocation (GstVideoEncoder * encoder, static gboolean gst_vp9_enc_propose_allocation (GstVideoEncoder * encoder,
@ -1486,8 +1487,8 @@ gst_vp9_enc_set_format (GstVideoEncoder * video_encoder,
GST_DEBUG_OBJECT (video_encoder, "set_format"); GST_DEBUG_OBJECT (video_encoder, "set_format");
if (encoder->inited) { if (encoder->inited) {
GST_DEBUG_OBJECT (video_encoder, "refusing renegotiation"); gst_vp9_enc_drain (video_encoder);
return FALSE; vpx_codec_destroy (&encoder->encoder);
} }
g_mutex_lock (&encoder->encoder_lock); g_mutex_lock (&encoder->encoder_lock);
@ -1528,7 +1529,9 @@ gst_vp9_enc_set_format (GstVideoEncoder * video_encoder,
} }
if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS) { if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS) {
encoder->first_pass_cache_content = g_byte_array_sized_new (4096); if (encoder->first_pass_cache_content == NULL) {
encoder->first_pass_cache_content = g_byte_array_sized_new (4096);
}
} else if (encoder->cfg.g_pass == VPX_RC_LAST_PASS) { } else if (encoder->cfg.g_pass == VPX_RC_LAST_PASS) {
GError *err = NULL; GError *err = NULL;
@ -1539,6 +1542,12 @@ gst_vp9_enc_set_format (GstVideoEncoder * video_encoder,
return FALSE; return FALSE;
} }
if (encoder->cfg.rc_twopass_stats_in.buf != NULL) {
g_free (encoder->cfg.rc_twopass_stats_in.buf);
encoder->cfg.rc_twopass_stats_in.buf = NULL;
encoder->cfg.rc_twopass_stats_in.sz = 0;
}
if (!g_file_get_contents (encoder->multipass_cache_file, if (!g_file_get_contents (encoder->multipass_cache_file,
(gchar **) & encoder->cfg.rc_twopass_stats_in.buf, (gchar **) & encoder->cfg.rc_twopass_stats_in.buf,
&encoder->cfg.rc_twopass_stats_in.sz, &err)) { &encoder->cfg.rc_twopass_stats_in.sz, &err)) {
@ -1805,22 +1814,25 @@ gst_vp9_enc_process (GstVP9Enc * encoder)
return ret; return ret;
} }
/* This function should be called holding then stream lock*/
static GstFlowReturn static GstFlowReturn
gst_vp9_enc_finish (GstVideoEncoder * video_encoder) gst_vp9_enc_drain (GstVideoEncoder * video_encoder)
{ {
GstVP9Enc *encoder; GstVP9Enc *encoder;
int flags = 0; int flags = 0;
vpx_codec_err_t status; vpx_codec_err_t status;
gint64 deadline;
GST_DEBUG_OBJECT (video_encoder, "finish");
encoder = GST_VP9_ENC (video_encoder); encoder = GST_VP9_ENC (video_encoder);
g_mutex_lock (&encoder->encoder_lock); g_mutex_lock (&encoder->encoder_lock);
deadline = encoder->deadline;
g_mutex_unlock (&encoder->encoder_lock);
status = status =
vpx_codec_encode (&encoder->encoder, NULL, encoder->n_frames, 1, flags, vpx_codec_encode (&encoder->encoder, NULL, encoder->n_frames, 1, flags,
encoder->deadline); deadline);
g_mutex_unlock (&encoder->encoder_lock);
if (status != 0) { if (status != 0) {
GST_ERROR_OBJECT (encoder, "encode returned %d %s", status, GST_ERROR_OBJECT (encoder, "encode returned %d %s", status,
gst_vpx_error_name (status)); gst_vpx_error_name (status));
@ -1830,6 +1842,7 @@ gst_vp9_enc_finish (GstVideoEncoder * video_encoder)
/* dispatch remaining frames */ /* dispatch remaining frames */
gst_vp9_enc_process (encoder); gst_vp9_enc_process (encoder);
g_mutex_lock (&encoder->encoder_lock);
if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS && encoder->multipass_cache_file) { if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS && encoder->multipass_cache_file) {
GError *err = NULL; GError *err = NULL;
@ -1841,10 +1854,23 @@ gst_vp9_enc_finish (GstVideoEncoder * video_encoder)
g_error_free (err); g_error_free (err);
} }
} }
g_mutex_unlock (&encoder->encoder_lock);
return GST_FLOW_OK; return GST_FLOW_OK;
} }
static GstFlowReturn
gst_vp9_enc_finish (GstVideoEncoder * video_encoder)
{
GstFlowReturn ret;
GST_DEBUG_OBJECT (video_encoder, "finish");
ret = gst_vp9_enc_drain (video_encoder);
return ret;
}
static vpx_image_t * static vpx_image_t *
gst_vp9_enc_buffer_to_image (GstVP9Enc * enc, GstVideoFrame * frame) gst_vp9_enc_buffer_to_image (GstVP9Enc * enc, GstVideoFrame * frame)
{ {