From 239b623a9c819564f9e2b64a66530a806e2cc5c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 25 Jul 2013 13:31:07 +0200 Subject: [PATCH] theoraenc: Clean up handling of reset/flushing/start/stop --- ext/theora/gsttheoraenc.c | 97 +++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 44 deletions(-) diff --git a/ext/theora/gsttheoraenc.c b/ext/theora/gsttheoraenc.c index 37ca24b33d..061453faf5 100644 --- a/ext/theora/gsttheoraenc.c +++ b/ext/theora/gsttheoraenc.c @@ -177,6 +177,7 @@ G_DEFINE_TYPE (GstTheoraEnc, gst_theora_enc, GST_TYPE_VIDEO_ENCODER); static gboolean theora_enc_start (GstVideoEncoder * enc); static gboolean theora_enc_stop (GstVideoEncoder * enc); +static gboolean theora_enc_reset (GstVideoEncoder * enc, gboolean hard); static gboolean theora_enc_set_format (GstVideoEncoder * enc, GstVideoCodecState * state); static GstFlowReturn theora_enc_handle_frame (GstVideoEncoder * enc, @@ -221,6 +222,7 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass) gstvideo_encoder_class->start = GST_DEBUG_FUNCPTR (theora_enc_start); gstvideo_encoder_class->stop = GST_DEBUG_FUNCPTR (theora_enc_stop); + gstvideo_encoder_class->reset = GST_DEBUG_FUNCPTR (theora_enc_reset); gstvideo_encoder_class->set_format = GST_DEBUG_FUNCPTR (theora_enc_set_format); gstvideo_encoder_class->handle_frame = @@ -355,9 +357,10 @@ theora_enc_finalize (GObject * object) G_OBJECT_CLASS (parent_class)->finalize (object); } -static void -theora_enc_reset (GstTheoraEnc * enc) +static gboolean +theora_enc_reset (GstVideoEncoder * encoder, gboolean hard) { + GstTheoraEnc *enc = GST_THEORA_ENC (encoder); ogg_uint32_t keyframe_force; int rate_flags; @@ -370,40 +373,56 @@ theora_enc_reset (GstTheoraEnc * enc) if (enc->encoder) th_encode_free (enc->encoder); - enc->encoder = th_encode_alloc (&enc->info); - /* We ensure this function cannot fail. */ - g_assert (enc->encoder != NULL); - th_encode_ctl (enc->encoder, TH_ENCCTL_SET_SPLEVEL, &enc->speed_level, - sizeof (enc->speed_level)); - th_encode_ctl (enc->encoder, TH_ENCCTL_SET_VP3_COMPATIBLE, - &enc->vp3_compatible, sizeof (enc->vp3_compatible)); - rate_flags = 0; - if (enc->drop_frames) - rate_flags |= TH_RATECTL_DROP_FRAMES; - if (enc->drop_frames) - rate_flags |= TH_RATECTL_CAP_OVERFLOW; - if (enc->drop_frames) - rate_flags |= TH_RATECTL_CAP_UNDERFLOW; - th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_FLAGS, - &rate_flags, sizeof (rate_flags)); + if (!hard) { + enc->encoder = th_encode_alloc (&enc->info); + /* We ensure this function cannot fail. */ + g_assert (enc->encoder != NULL); + th_encode_ctl (enc->encoder, TH_ENCCTL_SET_SPLEVEL, &enc->speed_level, + sizeof (enc->speed_level)); + th_encode_ctl (enc->encoder, TH_ENCCTL_SET_VP3_COMPATIBLE, + &enc->vp3_compatible, sizeof (enc->vp3_compatible)); - if (enc->rate_buffer) { - th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_BUFFER, - &enc->rate_buffer, sizeof (enc->rate_buffer)); + rate_flags = 0; + if (enc->drop_frames) + rate_flags |= TH_RATECTL_DROP_FRAMES; + if (enc->drop_frames) + rate_flags |= TH_RATECTL_CAP_OVERFLOW; + if (enc->drop_frames) + rate_flags |= TH_RATECTL_CAP_UNDERFLOW; + th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_FLAGS, + &rate_flags, sizeof (rate_flags)); + + if (enc->rate_buffer) { + th_encode_ctl (enc->encoder, TH_ENCCTL_SET_RATE_BUFFER, + &enc->rate_buffer, sizeof (enc->rate_buffer)); + } else { + /* FIXME */ + } + + keyframe_force = enc->keyframe_auto ? + enc->keyframe_force : enc->keyframe_freq; + th_encode_ctl (enc->encoder, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE, + &keyframe_force, sizeof (keyframe_force)); + + /* Get placeholder data */ + if (enc->multipass_cache_fd + && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS) + theora_enc_write_multipass_cache (enc, TRUE, FALSE); } else { - /* FIXME */ + enc->encoder = NULL; + th_comment_clear (&enc->comment); + th_info_clear (&enc->info); + + if (enc->input_state) + gst_video_codec_state_unref (enc->input_state); + enc->input_state = NULL; + + enc->packetno = 0; + enc->initialised = FALSE; } - keyframe_force = enc->keyframe_auto ? - enc->keyframe_force : enc->keyframe_freq; - th_encode_ctl (enc->encoder, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE, - &keyframe_force, sizeof (keyframe_force)); - - /* Get placeholder data */ - if (enc->multipass_cache_fd - && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS) - theora_enc_write_multipass_cache (enc, TRUE, FALSE); + return TRUE; } static gboolean @@ -414,10 +433,6 @@ theora_enc_start (GstVideoEncoder * benc) GST_DEBUG_OBJECT (benc, "start: init theora"); enc = GST_THEORA_ENC (benc); - th_info_init (&enc->info); - th_comment_init (&enc->comment); - enc->packetno = 0; - if (enc->multipass_mode >= MULTIPASS_MODE_FIRST_PASS) { GError *err = NULL; @@ -453,14 +468,8 @@ theora_enc_stop (GstVideoEncoder * benc) GST_DEBUG_OBJECT (benc, "stop: clearing theora state"); enc = GST_THEORA_ENC (benc); - if (enc->encoder) { - th_encode_free (enc->encoder); - enc->encoder = NULL; - } - th_comment_clear (&enc->comment); - th_info_clear (&enc->info); - - enc->initialised = FALSE; + /* Everything else is handled in reset() */ + theora_enc_clear_multipass_cache (enc); return TRUE; } @@ -587,7 +596,7 @@ theora_enc_set_format (GstVideoEncoder * benc, GstVideoCodecState * state) "keyframe_frequency_force is %d, granule shift is %d", enc->keyframe_force, enc->info.keyframe_granule_shift); - theora_enc_reset (enc); + theora_enc_reset (benc, FALSE); enc->initialised = TRUE; return TRUE;