gboolean gst_amc_codec_flush (GstAmcCodec * codec, GError **err);
gboolean gst_amc_codec_release (GstAmcCodec * codec, GError **err);
gboolean gst_amc_codec_request_key_frame (GstAmcCodec * codec, GError **err);
+gboolean gst_amc_codec_have_dynamic_bitrate (void);
+gboolean gst_amc_codec_set_dynamic_bitrate (GstAmcCodec * codec, GError **err, gint bitrate);
GstAmcBuffer * gst_amc_codec_get_output_buffer (GstAmcCodec * codec, gint index, GError **err);
GstAmcBuffer * gst_amc_codec_get_input_buffer (GstAmcCodec * codec, gint index, GError **err);
{
GstAmcVideoEnc *encoder;
GstState state;
+ gboolean codec_active;
+ GError *err = NULL;
encoder = GST_AMC_VIDEO_ENC (object);
GST_OBJECT_LOCK (encoder);
state = GST_STATE (encoder);
- if (state != GST_STATE_READY && state != GST_STATE_NULL)
- goto wrong_state;
+ codec_active = (encoder->codec && state != GST_STATE_READY
+ && state != GST_STATE_NULL);
switch (prop_id) {
case PROP_BIT_RATE:
encoder->bitrate = g_value_get_uint (value);
+
+ g_mutex_lock (&encoder->codec_lock);
+ if (encoder->codec) {
+ if (!gst_amc_codec_set_dynamic_bitrate (encoder->codec, &err,
+ encoder->bitrate)) {
+ g_mutex_unlock (&encoder->codec_lock);
+ goto wrong_state;
+ }
+ }
+ g_mutex_unlock (&encoder->codec_lock);
+ if (err) {
+ GST_ELEMENT_WARNING_FROM_ERROR (encoder, err);
+ g_clear_error (&err);
+ }
+
break;
case PROP_I_FRAME_INTERVAL:
encoder->i_frame_int = g_value_get_uint (value);
+ if (codec_active)
+ goto wrong_state;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstVideoEncoderClass *videoenc_class = GST_VIDEO_ENCODER_CLASS (klass);
+ GParamFlags dynamic_flag = 0;
parent_class = g_type_class_peek_parent (klass);
GST_DEBUG_FUNCPTR (gst_amc_video_enc_handle_frame);
videoenc_class->finish = GST_DEBUG_FUNCPTR (gst_amc_video_enc_finish);
+ // On Android >= 19, we can set bitrate dynamically
+ // so add the flag so apps can detect it.
+ if (gst_amc_codec_have_dynamic_bitrate ())
+ dynamic_flag = GST_PARAM_MUTABLE_PLAYING;
+
g_object_class_install_property (gobject_class, PROP_BIT_RATE,
g_param_spec_uint ("bitrate", "Bitrate", "Bitrate in bit/sec", 1,
G_MAXINT, BIT_RATE_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ dynamic_flag | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_I_FRAME_INTERVAL,
g_param_spec_uint ("i-frame-interval", "I-frame interval",
static void
gst_amc_video_enc_init (GstAmcVideoEnc * self)
{
+ g_mutex_init (&self->codec_lock);
g_mutex_init (&self->drain_lock);
g_cond_init (&self->drain_cond);
GST_DEBUG_OBJECT (self, "Opening encoder");
+ g_mutex_lock (&self->codec_lock);
self->codec = gst_amc_codec_new (klass->codec_info->name, TRUE, &err);
if (!self->codec) {
+ g_mutex_unlock (&self->codec_lock);
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
return FALSE;
}
+ g_mutex_unlock (&self->codec_lock);
self->started = FALSE;
self->flushing = TRUE;
GST_DEBUG_OBJECT (self, "Closing encoder");
+ g_mutex_lock (&self->codec_lock);
if (self->codec) {
GError *err = NULL;
gst_amc_codec_free (self->codec);
}
self->codec = NULL;
+ g_mutex_unlock (&self->codec_lock);
self->started = FALSE;
self->flushing = TRUE;
{
GstAmcVideoEnc *self = GST_AMC_VIDEO_ENC (object);
+ g_mutex_clear (&self->codec_lock);
g_mutex_clear (&self->drain_lock);
g_cond_clear (&self->drain_cond);
#include "gstamcsurface.h"
#define PARAMETER_KEY_REQUEST_SYNC_FRAME "request-sync"
+#define PARAMETER_KEY_VIDEO_BITRATE "video-bitrate"
struct _GstAmcCodec
{
}
gboolean
+gst_amc_codec_have_dynamic_bitrate ()
+{
+ /* Dynamic bitrate scaling is supported on Android >= 19,
+ * where the setParameters() call is available */
+ return (media_codec.setParameters != NULL);
+}
+
+gboolean
+gst_amc_codec_set_dynamic_bitrate (GstAmcCodec * codec, GError ** err,
+ gint bitrate)
+{
+ JNIEnv *env;
+
+ g_return_val_if_fail (codec != NULL, FALSE);
+
+ env = gst_amc_jni_get_env ();
+ return gst_amc_codec_set_parameter (codec, env, err,
+ PARAMETER_KEY_VIDEO_BITRATE, bitrate);
+}
+
+gboolean
gst_amc_codec_release (GstAmcCodec * codec, GError ** err)
{
JNIEnv *env;