summaryrefslogtreecommitdiff
path: root/ext/openh264
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2014-10-03 13:54:22 +0300
committerSebastian Dröge <sebastian@centricular.com>2014-10-03 17:23:36 +0300
commit088cf16bf9ee2b192c10b5125f26c345c0a34134 (patch)
tree8e84547796c3c005f2f82a217a673861f0d157e4 /ext/openh264
parent09f5b9acecdb987c58c45620e08ea64441e00648 (diff)
openh264: Run gst-indent over everything
Diffstat (limited to 'ext/openh264')
-rw-r--r--ext/openh264/gstopenh264dec.cpp495
-rw-r--r--ext/openh264/gstopenh264enc.cpp1125
-rw-r--r--ext/openh264/gstopenh264plugin.c26
3 files changed, 863 insertions, 783 deletions
diff --git a/ext/openh264/gstopenh264dec.cpp b/ext/openh264/gstopenh264dec.cpp
index 83fc881d4..cac6d6162 100644
--- a/ext/openh264/gstopenh264dec.cpp
+++ b/ext/openh264/gstopenh264dec.cpp
@@ -35,197 +35,221 @@
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideodecoder.h>
-#include <string.h> /* for memcpy */
+#include <string.h> /* for memcpy */
#define GST_OPENH264DEC_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ( \
(obj), GST_TYPE_OPENH264DEC, \
GstOpenh264DecPrivate))
-GST_DEBUG_CATEGORY_STATIC(gst_openh264dec_debug_category);
+GST_DEBUG_CATEGORY_STATIC (gst_openh264dec_debug_category);
#define GST_CAT_DEFAULT gst_openh264dec_debug_category
/* prototypes */
-static void gst_openh264dec_set_property(GObject *object,
- guint property_id, const GValue *value, GParamSpec *pspec);
-static void gst_openh264dec_get_property(GObject *object, guint property_id,
- GValue *value, GParamSpec *pspec);
+static void gst_openh264dec_set_property (GObject * object,
+ guint property_id, const GValue * value, GParamSpec * pspec);
+static void gst_openh264dec_get_property (GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec);
-static gboolean gst_openh264dec_start(GstVideoDecoder *decoder);
-static gboolean gst_openh264dec_stop(GstVideoDecoder *decoder);
+static gboolean gst_openh264dec_start (GstVideoDecoder * decoder);
+static gboolean gst_openh264dec_stop (GstVideoDecoder * decoder);
-static gboolean gst_openh264dec_set_format(GstVideoDecoder *decoder, GstVideoCodecState *state);
-static gboolean gst_openh264dec_reset(GstVideoDecoder *decoder, gboolean hard);
-static GstFlowReturn gst_openh264dec_finish(GstVideoDecoder *decoder);
-static GstFlowReturn gst_openh264dec_handle_frame(GstVideoDecoder *decoder,
- GstVideoCodecFrame *frame);
-static gboolean gst_openh264dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query);
+static gboolean gst_openh264dec_set_format (GstVideoDecoder * decoder,
+ GstVideoCodecState * state);
+static gboolean gst_openh264dec_reset (GstVideoDecoder * decoder,
+ gboolean hard);
+static GstFlowReturn gst_openh264dec_finish (GstVideoDecoder * decoder);
+static GstFlowReturn gst_openh264dec_handle_frame (GstVideoDecoder * decoder,
+ GstVideoCodecFrame * frame);
+static gboolean gst_openh264dec_decide_allocation (GstVideoDecoder * decoder,
+ GstQuery * query);
enum
{
- PROP_0,
- N_PROPERTIES
+ PROP_0,
+ N_PROPERTIES
};
struct _GstOpenh264DecPrivate
{
- ISVCDecoder *decoder;
- GstVideoCodecState *input_state;
- guint width, height;
+ ISVCDecoder *decoder;
+ GstVideoCodecState *input_state;
+ guint width, height;
};
/* pad templates */
-static GstStaticPadTemplate gst_openh264dec_sink_template = GST_STATIC_PAD_TEMPLATE("sink",
+static GstStaticPadTemplate gst_openh264dec_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS("video/x-h264, stream-format=(string)byte-stream, alignment=(string)au"));
+ GST_STATIC_CAPS
+ ("video/x-h264, stream-format=(string)byte-stream, alignment=(string)au"));
-static GstStaticPadTemplate gst_openh264dec_src_template = GST_STATIC_PAD_TEMPLATE("src",
+static GstStaticPadTemplate gst_openh264dec_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS(GST_VIDEO_CAPS_MAKE("I420")));
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420")));
/* class initialization */
-G_DEFINE_TYPE_WITH_CODE(GstOpenh264Dec, gst_openh264dec, GST_TYPE_VIDEO_DECODER,
- GST_DEBUG_CATEGORY_INIT(gst_openh264dec_debug_category,
- "openh264dec", 0, "debug category for openh264dec element"));
+G_DEFINE_TYPE_WITH_CODE (GstOpenh264Dec, gst_openh264dec,
+ GST_TYPE_VIDEO_DECODER,
+ GST_DEBUG_CATEGORY_INIT (gst_openh264dec_debug_category, "openh264dec", 0,
+ "debug category for openh264dec element"));
-static void gst_openh264dec_class_init(GstOpenh264DecClass *klass)
+static void
+gst_openh264dec_class_init (GstOpenh264DecClass * klass)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- GstVideoDecoderClass *video_decoder_class = GST_VIDEO_DECODER_CLASS(klass);
-
- g_type_class_add_private(klass, sizeof(GstOpenh264DecPrivate));
-
- /* Setting up pads and setting metadata should be moved to
- base_class_init if you intend to subclass this class. */
- gst_element_class_add_pad_template(GST_ELEMENT_CLASS(klass),
- gst_static_pad_template_get(&gst_openh264dec_sink_template));
- gst_element_class_add_pad_template(GST_ELEMENT_CLASS(klass),
- gst_static_pad_template_get(&gst_openh264dec_src_template));
-
- gst_element_class_set_static_metadata(GST_ELEMENT_CLASS(klass), "OpenH264 video decoder", "Decoder/Video", "OpenH264 video decoder", "Ericsson AB, http://www.ericsson.com");
- gobject_class->set_property = gst_openh264dec_set_property;
- gobject_class->get_property = gst_openh264dec_get_property;
-
- video_decoder_class->start = GST_DEBUG_FUNCPTR(gst_openh264dec_start);
- video_decoder_class->stop = GST_DEBUG_FUNCPTR(gst_openh264dec_stop);
-
- video_decoder_class->set_format = GST_DEBUG_FUNCPTR(gst_openh264dec_set_format);
- video_decoder_class->reset = GST_DEBUG_FUNCPTR(gst_openh264dec_reset);
- video_decoder_class->finish = GST_DEBUG_FUNCPTR(gst_openh264dec_finish);
- video_decoder_class->handle_frame = GST_DEBUG_FUNCPTR(gst_openh264dec_handle_frame);
- video_decoder_class->decide_allocation = GST_DEBUG_FUNCPTR(gst_openh264dec_decide_allocation);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstVideoDecoderClass *video_decoder_class = GST_VIDEO_DECODER_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GstOpenh264DecPrivate));
+
+ /* Setting up pads and setting metadata should be moved to
+ base_class_init if you intend to subclass this class. */
+ gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
+ gst_static_pad_template_get (&gst_openh264dec_sink_template));
+ gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
+ gst_static_pad_template_get (&gst_openh264dec_src_template));
+
+ gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
+ "OpenH264 video decoder", "Decoder/Video", "OpenH264 video decoder",
+ "Ericsson AB, http://www.ericsson.com");
+ gobject_class->set_property = gst_openh264dec_set_property;
+ gobject_class->get_property = gst_openh264dec_get_property;
+
+ video_decoder_class->start = GST_DEBUG_FUNCPTR (gst_openh264dec_start);
+ video_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_openh264dec_stop);
+
+ video_decoder_class->set_format =
+ GST_DEBUG_FUNCPTR (gst_openh264dec_set_format);
+ video_decoder_class->reset = GST_DEBUG_FUNCPTR (gst_openh264dec_reset);
+ video_decoder_class->finish = GST_DEBUG_FUNCPTR (gst_openh264dec_finish);
+ video_decoder_class->handle_frame =
+ GST_DEBUG_FUNCPTR (gst_openh264dec_handle_frame);
+ video_decoder_class->decide_allocation =
+ GST_DEBUG_FUNCPTR (gst_openh264dec_decide_allocation);
}
-static void gst_openh264dec_init(GstOpenh264Dec *openh264dec)
+static void
+gst_openh264dec_init (GstOpenh264Dec * openh264dec)
{
- openh264dec->priv = GST_OPENH264DEC_GET_PRIVATE(openh264dec);
- openh264dec->priv->decoder = NULL;
+ openh264dec->priv = GST_OPENH264DEC_GET_PRIVATE (openh264dec);
+ openh264dec->priv->decoder = NULL;
- gst_video_decoder_set_packetized(GST_VIDEO_DECODER(openh264dec), TRUE);
- gst_video_decoder_set_needs_format(GST_VIDEO_DECODER(openh264dec), TRUE);
+ gst_video_decoder_set_packetized (GST_VIDEO_DECODER (openh264dec), TRUE);
+ gst_video_decoder_set_needs_format (GST_VIDEO_DECODER (openh264dec), TRUE);
}
-void gst_openh264dec_set_property(GObject *object, guint property_id,
- const GValue *value, GParamSpec *pspec)
+void
+gst_openh264dec_set_property (GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec)
{
- GstOpenh264Dec *openh264dec = GST_OPENH264DEC(object);
+ GstOpenh264Dec *openh264dec = GST_OPENH264DEC (object);
- GST_DEBUG_OBJECT(openh264dec, "set_property");
+ GST_DEBUG_OBJECT (openh264dec, "set_property");
- switch (property_id) {
+ switch (property_id) {
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
}
-void gst_openh264dec_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+void
+gst_openh264dec_get_property (GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec)
{
- GstOpenh264Dec *openh264dec = GST_OPENH264DEC(object);
+ GstOpenh264Dec *openh264dec = GST_OPENH264DEC (object);
- GST_DEBUG_OBJECT(openh264dec, "get_property");
+ GST_DEBUG_OBJECT (openh264dec, "get_property");
- switch (property_id) {
+ switch (property_id) {
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
}
-static gboolean gst_openh264dec_start(GstVideoDecoder *decoder)
+static gboolean
+gst_openh264dec_start (GstVideoDecoder * decoder)
{
- GstOpenh264Dec *openh264dec = GST_OPENH264DEC(decoder);
- gint ret;
- SDecodingParam dec_param = {0};
-
- if (openh264dec->priv->decoder != NULL)
- {
- openh264dec->priv->decoder->Uninitialize();
- WelsDestroyDecoder(openh264dec->priv->decoder);
- openh264dec->priv->decoder = NULL;
- }
- WelsCreateDecoder(&(openh264dec->priv->decoder));
+ GstOpenh264Dec *openh264dec = GST_OPENH264DEC (decoder);
+ gint ret;
+ SDecodingParam dec_param = { 0 };
- dec_param.uiTargetDqLayer = 255;
- dec_param.uiEcActiveFlag = 1;
- dec_param.iOutputColorFormat = videoFormatI420;
- dec_param.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_AVC;
+ if (openh264dec->priv->decoder != NULL) {
+ openh264dec->priv->decoder->Uninitialize ();
+ WelsDestroyDecoder (openh264dec->priv->decoder);
+ openh264dec->priv->decoder = NULL;
+ }
+ WelsCreateDecoder (&(openh264dec->priv->decoder));
+
+ dec_param.uiTargetDqLayer = 255;
+ dec_param.uiEcActiveFlag = 1;
+ dec_param.iOutputColorFormat = videoFormatI420;
+ dec_param.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_AVC;
- ret = openh264dec->priv->decoder->Initialize(&dec_param);
+ ret = openh264dec->priv->decoder->Initialize (&dec_param);
- GST_DEBUG_OBJECT(openh264dec, "openh264_dec_start called, openh264dec %sinitialized OK!", (ret != cmResultSuccess) ? "NOT " : "");
+ GST_DEBUG_OBJECT (openh264dec,
+ "openh264_dec_start called, openh264dec %sinitialized OK!",
+ (ret != cmResultSuccess) ? "NOT " : "");
- return (ret == cmResultSuccess);
+ return (ret == cmResultSuccess);
}
-static gboolean gst_openh264dec_stop(GstVideoDecoder *decoder)
+static gboolean
+gst_openh264dec_stop (GstVideoDecoder * decoder)
{
- GstOpenh264Dec *openh264dec = GST_OPENH264DEC(decoder);
- gint ret = TRUE;
+ GstOpenh264Dec *openh264dec = GST_OPENH264DEC (decoder);
+ gint ret = TRUE;
- if (openh264dec->priv->decoder) {
- ret = openh264dec->priv->decoder->Uninitialize();
- WelsDestroyDecoder(openh264dec->priv->decoder);
- openh264dec->priv->decoder = NULL;
- }
+ if (openh264dec->priv->decoder) {
+ ret = openh264dec->priv->decoder->Uninitialize ();
+ WelsDestroyDecoder (openh264dec->priv->decoder);
+ openh264dec->priv->decoder = NULL;
+ }
- if (openh264dec->priv->input_state) {
- gst_video_codec_state_unref (openh264dec->priv->input_state);
- openh264dec->priv->input_state = NULL;
- }
- openh264dec->priv->width = openh264dec->priv->height = 0;
+ if (openh264dec->priv->input_state) {
+ gst_video_codec_state_unref (openh264dec->priv->input_state);
+ openh264dec->priv->input_state = NULL;
+ }
+ openh264dec->priv->width = openh264dec->priv->height = 0;
- return ret;
+ return ret;
}
-static gboolean gst_openh264dec_set_format(GstVideoDecoder *decoder, GstVideoCodecState *state)
+static gboolean
+gst_openh264dec_set_format (GstVideoDecoder * decoder,
+ GstVideoCodecState * state)
{
- GstOpenh264Dec *openh264dec = GST_OPENH264DEC(decoder);
+ GstOpenh264Dec *openh264dec = GST_OPENH264DEC (decoder);
- GST_DEBUG_OBJECT(openh264dec, "openh264_dec_set_format called, caps: %" GST_PTR_FORMAT, state->caps);
+ GST_DEBUG_OBJECT (openh264dec,
+ "openh264_dec_set_format called, caps: %" GST_PTR_FORMAT, state->caps);
- if (openh264dec->priv->input_state) {
- gst_video_codec_state_unref (openh264dec->priv->input_state);
- openh264dec->priv->input_state = NULL;
- }
- openh264dec->priv->input_state = gst_video_codec_state_ref (state);
+ if (openh264dec->priv->input_state) {
+ gst_video_codec_state_unref (openh264dec->priv->input_state);
+ openh264dec->priv->input_state = NULL;
+ }
+ openh264dec->priv->input_state = gst_video_codec_state_ref (state);
- return TRUE;
+ return TRUE;
}
-static gboolean gst_openh264dec_reset(GstVideoDecoder *decoder, gboolean hard)
+static gboolean
+gst_openh264dec_reset (GstVideoDecoder * decoder, gboolean hard)
{
- GstOpenh264Dec *openh264dec = GST_OPENH264DEC(decoder);
+ GstOpenh264Dec *openh264dec = GST_OPENH264DEC (decoder);
- GST_DEBUG_OBJECT(openh264dec, "reset");
+ GST_DEBUG_OBJECT (openh264dec, "reset");
- return TRUE;
+ return TRUE;
}
static GstVideoCodecFrame *
@@ -254,144 +278,160 @@ get_oldest_pts_frame (GstVideoDecoder * decoder)
return oldest;
}
-static GstFlowReturn gst_openh264dec_handle_frame(GstVideoDecoder *decoder, GstVideoCodecFrame *frame)
+static GstFlowReturn
+gst_openh264dec_handle_frame (GstVideoDecoder * decoder,
+ GstVideoCodecFrame * frame)
{
- GstOpenh264Dec *openh264dec = GST_OPENH264DEC(decoder);
- GstMapInfo map_info;
- GstVideoCodecState *state;
- SBufferInfo dst_buf_info;
- DECODING_STATE ret;
- guint8 *yuvdata[3];
- GstFlowReturn flow_status;
- GstVideoFrame video_frame;
- guint actual_width, actual_height;
- guint i;
- guint8 *p;
- guint row_stride, component_width, component_height, src_width, row;
-
- if (frame) {
- if (!gst_buffer_map(frame->input_buffer, &map_info, GST_MAP_READ)) {
- GST_ERROR_OBJECT(openh264dec, "Cannot map input buffer!");
- return GST_FLOW_ERROR;
- }
-
- GST_LOG_OBJECT(openh264dec, "handle frame, %d", map_info.size > 4 ? map_info.data[4] & 0x1f : -1);
-
- memset (&dst_buf_info, 0, sizeof (SBufferInfo));
- ret = openh264dec->priv->decoder->DecodeFrame2(map_info.data, map_info.size, yuvdata, &dst_buf_info);
-
- if (ret == dsNoParamSets) {
- GST_DEBUG_OBJECT(openh264dec, "Requesting a key unit");
- gst_pad_push_event(GST_VIDEO_DECODER_SINK_PAD(decoder),
- gst_video_event_new_upstream_force_key_unit(GST_CLOCK_TIME_NONE, FALSE, 0));
- }
-
- if (ret != dsErrorFree && ret != dsNoParamSets) {
- GST_DEBUG_OBJECT(openh264dec, "Requesting a key unit");
- gst_pad_push_event(GST_VIDEO_DECODER_SINK_PAD(decoder),
- gst_video_event_new_upstream_force_key_unit(GST_CLOCK_TIME_NONE, FALSE, 0));
- GST_LOG_OBJECT(openh264dec, "error decoding nal, return code: %d", ret);
- }
-
- gst_buffer_unmap(frame->input_buffer, &map_info);
- gst_video_codec_frame_unref (frame);
- frame = NULL;
- } else {
- memset (&dst_buf_info, 0, sizeof (SBufferInfo));
- ret = openh264dec->priv->decoder->DecodeFrame2(NULL, 0, yuvdata, &dst_buf_info);
- if (ret != dsErrorFree)
- return GST_FLOW_EOS;
+ GstOpenh264Dec *openh264dec = GST_OPENH264DEC (decoder);
+ GstMapInfo map_info;
+ GstVideoCodecState *state;
+ SBufferInfo dst_buf_info;
+ DECODING_STATE ret;
+ guint8 *yuvdata[3];
+ GstFlowReturn flow_status;
+ GstVideoFrame video_frame;
+ guint actual_width, actual_height;
+ guint i;
+ guint8 *p;
+ guint row_stride, component_width, component_height, src_width, row;
+
+ if (frame) {
+ if (!gst_buffer_map (frame->input_buffer, &map_info, GST_MAP_READ)) {
+ GST_ERROR_OBJECT (openh264dec, "Cannot map input buffer!");
+ return GST_FLOW_ERROR;
}
- /* FIXME: openh264 has no way for us to get a connection
- * between the input and output frames, we just have to
- * guess based on the input */
- frame = get_oldest_pts_frame (decoder);
- if (!frame) {
- /* Can only happen in finish() */
- return GST_FLOW_EOS;
- }
+ GST_LOG_OBJECT (openh264dec, "handle frame, %d",
+ map_info.size > 4 ? map_info.data[4] & 0x1f : -1);
- /* No output available yet */
- if (dst_buf_info.iBufferStatus != 1) {
- return GST_FLOW_OK;
- }
+ memset (&dst_buf_info, 0, sizeof (SBufferInfo));
+ ret =
+ openh264dec->priv->decoder->DecodeFrame2 (map_info.data, map_info.size,
+ yuvdata, &dst_buf_info);
- actual_width = dst_buf_info.UsrData.sSystemBuffer.iWidth;
- actual_height = dst_buf_info.UsrData.sSystemBuffer.iHeight;
-
- if (!gst_pad_has_current_caps (GST_VIDEO_DECODER_SRC_PAD (openh264dec)) || actual_width != openh264dec->priv->width || actual_height != openh264dec->priv->height) {
- state = gst_video_decoder_set_output_state(decoder,
- GST_VIDEO_FORMAT_I420,
- actual_width,
- actual_height,
- openh264dec->priv->input_state);
- openh264dec->priv->width = actual_width;
- openh264dec->priv->height = actual_height;
-
- if (!gst_video_decoder_negotiate(decoder)) {
- GST_ERROR_OBJECT(openh264dec, "Failed to negotiate with downstream elements");
- return GST_FLOW_NOT_NEGOTIATED;
- }
- } else {
- state = gst_video_decoder_get_output_state(decoder);
+ if (ret == dsNoParamSets) {
+ GST_DEBUG_OBJECT (openh264dec, "Requesting a key unit");
+ gst_pad_push_event (GST_VIDEO_DECODER_SINK_PAD (decoder),
+ gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
+ FALSE, 0));
}
- flow_status = gst_video_decoder_allocate_output_frame(decoder, frame);
- if (flow_status != GST_FLOW_OK) {
- gst_video_codec_state_unref (state);
- return flow_status;
+ if (ret != dsErrorFree && ret != dsNoParamSets) {
+ GST_DEBUG_OBJECT (openh264dec, "Requesting a key unit");
+ gst_pad_push_event (GST_VIDEO_DECODER_SINK_PAD (decoder),
+ gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
+ FALSE, 0));
+ GST_LOG_OBJECT (openh264dec, "error decoding nal, return code: %d", ret);
}
- if (!gst_video_frame_map(&video_frame, &state->info, frame->output_buffer, GST_MAP_WRITE)) {
- GST_ERROR_OBJECT(openh264dec, "Cannot map output buffer!");
- gst_video_codec_state_unref (state);
- return GST_FLOW_ERROR;
- }
+ gst_buffer_unmap (frame->input_buffer, &map_info);
+ gst_video_codec_frame_unref (frame);
+ frame = NULL;
+ } else {
+ memset (&dst_buf_info, 0, sizeof (SBufferInfo));
+ ret =
+ openh264dec->priv->decoder->DecodeFrame2 (NULL, 0, yuvdata,
+ &dst_buf_info);
+ if (ret != dsErrorFree)
+ return GST_FLOW_EOS;
+ }
- for (i = 0; i < 3; i++) {
- p = GST_VIDEO_FRAME_COMP_DATA(&video_frame, i);
- row_stride = GST_VIDEO_FRAME_COMP_STRIDE(&video_frame, i);
- component_width = GST_VIDEO_FRAME_COMP_WIDTH(&video_frame, i);
- component_height = GST_VIDEO_FRAME_COMP_HEIGHT(&video_frame, i);
- src_width = i < 1 ? dst_buf_info.UsrData.sSystemBuffer.iStride[0] : dst_buf_info.UsrData.sSystemBuffer.iStride[1];
- for (row = 0; row < component_height; row++) {
- memcpy(p, yuvdata[i], component_width);
- p += row_stride;
- yuvdata[i] += src_width;
- }
+ /* FIXME: openh264 has no way for us to get a connection
+ * between the input and output frames, we just have to
+ * guess based on the input */
+ frame = get_oldest_pts_frame (decoder);
+ if (!frame) {
+ /* Can only happen in finish() */
+ return GST_FLOW_EOS;
+ }
+
+ /* No output available yet */
+ if (dst_buf_info.iBufferStatus != 1) {
+ return GST_FLOW_OK;
+ }
+
+ actual_width = dst_buf_info.UsrData.sSystemBuffer.iWidth;
+ actual_height = dst_buf_info.UsrData.sSystemBuffer.iHeight;
+
+ if (!gst_pad_has_current_caps (GST_VIDEO_DECODER_SRC_PAD (openh264dec))
+ || actual_width != openh264dec->priv->width
+ || actual_height != openh264dec->priv->height) {
+ state =
+ gst_video_decoder_set_output_state (decoder, GST_VIDEO_FORMAT_I420,
+ actual_width, actual_height, openh264dec->priv->input_state);
+ openh264dec->priv->width = actual_width;
+ openh264dec->priv->height = actual_height;
+
+ if (!gst_video_decoder_negotiate (decoder)) {
+ GST_ERROR_OBJECT (openh264dec,
+ "Failed to negotiate with downstream elements");
+ return GST_FLOW_NOT_NEGOTIATED;
}
+ } else {
+ state = gst_video_decoder_get_output_state (decoder);
+ }
+
+ flow_status = gst_video_decoder_allocate_output_frame (decoder, frame);
+ if (flow_status != GST_FLOW_OK) {
gst_video_codec_state_unref (state);
- gst_video_frame_unmap(&video_frame);
+ return flow_status;
+ }
- return gst_video_decoder_finish_frame(decoder, frame);
+ if (!gst_video_frame_map (&video_frame, &state->info, frame->output_buffer,
+ GST_MAP_WRITE)) {
+ GST_ERROR_OBJECT (openh264dec, "Cannot map output buffer!");
+ gst_video_codec_state_unref (state);
+ return GST_FLOW_ERROR;
+ }
+
+ for (i = 0; i < 3; i++) {
+ p = GST_VIDEO_FRAME_COMP_DATA (&video_frame, i);
+ row_stride = GST_VIDEO_FRAME_COMP_STRIDE (&video_frame, i);
+ component_width = GST_VIDEO_FRAME_COMP_WIDTH (&video_frame, i);
+ component_height = GST_VIDEO_FRAME_COMP_HEIGHT (&video_frame, i);
+ src_width =
+ i <
+ 1 ? dst_buf_info.UsrData.sSystemBuffer.
+ iStride[0] : dst_buf_info.UsrData.sSystemBuffer.iStride[1];
+ for (row = 0; row < component_height; row++) {
+ memcpy (p, yuvdata[i], component_width);
+ p += row_stride;
+ yuvdata[i] += src_width;
+ }
+ }
+ gst_video_codec_state_unref (state);
+ gst_video_frame_unmap (&video_frame);
+
+ return gst_video_decoder_finish_frame (decoder, frame);
}
-static GstFlowReturn gst_openh264dec_finish(GstVideoDecoder *decoder)
+static GstFlowReturn
+gst_openh264dec_finish (GstVideoDecoder * decoder)
{
- GstOpenh264Dec *openh264dec = GST_OPENH264DEC(decoder);
+ GstOpenh264Dec *openh264dec = GST_OPENH264DEC (decoder);
- GST_DEBUG_OBJECT(openh264dec, "finish");
+ GST_DEBUG_OBJECT (openh264dec, "finish");
- /* Decoder not negotiated yet */
- if (openh264dec->priv->width == 0)
- return GST_FLOW_OK;
+ /* Decoder not negotiated yet */
+ if (openh264dec->priv->width == 0)
+ return GST_FLOW_OK;
- /* Drain all pending frames */
- while ((gst_openh264dec_handle_frame (decoder, NULL)) == GST_FLOW_OK);
+ /* Drain all pending frames */
+ while ((gst_openh264dec_handle_frame (decoder, NULL)) == GST_FLOW_OK);
- return GST_FLOW_OK;
+ return GST_FLOW_OK;
}
-static gboolean gst_openh264dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
+static gboolean
+gst_openh264dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
{
GstVideoCodecState *state;
GstBufferPool *pool;
guint size, min, max;
GstStructure *config;
- if (!GST_VIDEO_DECODER_CLASS (gst_openh264dec_parent_class)->decide_allocation (decoder,
- query))
+ if (!GST_VIDEO_DECODER_CLASS (gst_openh264dec_parent_class)->decide_allocation
+ (decoder, query))
return FALSE;
state = gst_video_decoder_get_output_state (decoder);
@@ -413,4 +453,3 @@ static gboolean gst_openh264dec_decide_allocation (GstVideoDecoder * decoder, Gs
return TRUE;
}
-
diff --git a/ext/openh264/gstopenh264enc.cpp b/ext/openh264/gstopenh264enc.cpp
index 9a77eff7d..490380b1a 100644
--- a/ext/openh264/gstopenh264enc.cpp
+++ b/ext/openh264/gstopenh264enc.cpp
@@ -42,69 +42,69 @@
#define GST_OPENH264ENC_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), GST_TYPE_OPENH264ENC, GstOpenh264EncPrivate))
-GST_DEBUG_CATEGORY_STATIC(gst_openh264enc_debug_category);
+GST_DEBUG_CATEGORY_STATIC (gst_openh264enc_debug_category);
#define GST_CAT_DEFAULT gst_openh264enc_debug_category
#define GST_TYPE_USAGE_TYPE (gst_openh264enc_usage_type_get_type ())
static GType
gst_openh264enc_usage_type_get_type (void)
{
- static GType usage_type = 0;
-
- if (!usage_type) {
- static GEnumValue usage_types[] = {
- { CAMERA_VIDEO_REAL_TIME, "video from camera", "camera" },
- { SCREEN_CONTENT_REAL_TIME, "screen content", "screen" },
- { 0, NULL, NULL },
- };
-
- usage_type =
- g_enum_register_static ("EUsageType",
- usage_types);
- }
+ static GType usage_type = 0;
+
+ if (!usage_type) {
+ static GEnumValue usage_types[] = {
+ {CAMERA_VIDEO_REAL_TIME, "video from camera", "camera"},
+ {SCREEN_CONTENT_REAL_TIME, "screen content", "screen"},
+ {0, NULL, NULL},
+ };
+
+ usage_type = g_enum_register_static ("EUsageType", usage_types);
+ }
- return usage_type;
+ return usage_type;
}
#define GST_TYPE_RC_MODES (gst_openh264enc_rc_modes_get_type ())
static GType
gst_openh264enc_rc_modes_get_type (void)
{
- static GType rc_modes_type = 0;
-
- if (!rc_modes_type) {
- static GEnumValue rc_modes_types[] = {
- { RC_QUALITY_MODE, "Quality mode", "quality" },
- { RC_BITRATE_MODE, "Bitrate mode", "bitrate" },
- { RC_LOW_BW_MODE, "Low bandwidth mode", "bandwidth" },
- { RC_OFF_MODE, "Rate control off mode", "off" },
- { 0, NULL, NULL },
- };
-
- rc_modes_type =
- g_enum_register_static ("RC_MODES",
- rc_modes_types);
- }
+ static GType rc_modes_type = 0;
+
+ if (!rc_modes_type) {
+ static GEnumValue rc_modes_types[] = {
+ {RC_QUALITY_MODE, "Quality mode", "quality"},
+ {RC_BITRATE_MODE, "Bitrate mode", "bitrate"},
+ {RC_LOW_BW_MODE, "Low bandwidth mode", "bandwidth"},
+ {RC_OFF_MODE, "Rate control off mode", "off"},
+ {0, NULL, NULL},
+ };
- return rc_modes_type;
+ rc_modes_type = g_enum_register_static ("RC_MODES", rc_modes_types);
+ }
+
+ return rc_modes_type;
}
/* prototypes */
-static void gst_openh264enc_set_property(GObject *object,
- guint property_id, const GValue *value, GParamSpec *pspec);
-static void gst_openh264enc_get_property(GObject *object,
- guint property_id, GValue *value, GParamSpec *pspec);
-static void gst_openh264enc_finalize(GObject *object);
-static gboolean gst_openh264enc_start(GstVideoEncoder *encoder);
-static gboolean gst_openh264enc_stop(GstVideoEncoder *encoder);
-static gboolean gst_openh264enc_set_format(GstVideoEncoder *encoder, GstVideoCodecState *state);
-static GstFlowReturn gst_openh264enc_handle_frame(GstVideoEncoder *encoder,
- GstVideoCodecFrame *frame);
-static GstFlowReturn gst_openh264enc_finish (GstVideoEncoder *encoder);
-static gboolean gst_openh264enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query);
-static void gst_openh264enc_set_usage_type (GstOpenh264Enc *openh264enc, gint usage_type);
-static void gst_openh264enc_set_rate_control (GstOpenh264Enc *openh264enc, gint rc_mode);
+static void gst_openh264enc_set_property (GObject * object,
+ guint property_id, const GValue * value, GParamSpec * pspec);
+static void gst_openh264enc_get_property (GObject * object,
+ guint property_id, GValue * value, GParamSpec * pspec);
+static void gst_openh264enc_finalize (GObject * object);
+static gboolean gst_openh264enc_start (GstVideoEncoder * encoder);
+static gboolean gst_openh264enc_stop (GstVideoEncoder * encoder);
+static gboolean gst_openh264enc_set_format (GstVideoEncoder * encoder,
+ GstVideoCodecState * state);
+static GstFlowReturn gst_openh264enc_handle_frame (GstVideoEncoder * encoder,
+ GstVideoCodecFrame * frame);
+static GstFlowReturn gst_openh264enc_finish (GstVideoEncoder * encoder);
+static gboolean gst_openh264enc_propose_allocation (GstVideoEncoder * encoder,
+ GstQuery * query);
+static void gst_openh264enc_set_usage_type (GstOpenh264Enc * openh264enc,
+ gint usage_type);
+static void gst_openh264enc_set_rate_control (GstOpenh264Enc * openh264enc,
+ gint rc_mode);
#define DEFAULT_BITRATE (128000)
@@ -119,622 +119,665 @@ static void gst_openh264enc_set_rate_control (GstOpenh264Enc *openh264enc, gint
enum
{
- PROP_0,
- PROP_USAGE_TYPE,
- PROP_BITRATE,
- PROP_GOP_SIZE,
- PROP_MAX_SLICE_SIZE,
- PROP_RATE_CONTROL,
- PROP_MULTI_THREAD,
- PROP_ENABLE_DENOISE,
- N_PROPERTIES
+ PROP_0,
+ PROP_USAGE_TYPE,
+ PROP_BITRATE,
+ PROP_GOP_SIZE,
+ PROP_MAX_SLICE_SIZE,
+ PROP_RATE_CONTROL,
+ PROP_MULTI_THREAD,
+ PROP_ENABLE_DENOISE,
+ N_PROPERTIES
};
struct _GstOpenh264EncPrivate
{
- ISVCEncoder *encoder;
- EUsageType usage_type;
- guint gop_size;
- RC_MODES rate_control;
- guint max_slice_size;
- guint bitrate;
- guint framerate;
- guint multi_thread;
- gboolean enable_denoise;
- GstVideoCodecState *input_state;
- guint32 drop_bitrate;
- guint64 time_per_frame;
- guint64 frame_count;
- guint64 previous_timestamp;
+ ISVCEncoder *encoder;
+ EUsageType usage_type;
+ guint gop_size;
+ RC_MODES rate_control;
+ guint max_slice_size;
+ guint bitrate;
+ guint framerate;
+ guint multi_thread;
+ gboolean enable_denoise;
+ GstVideoCodecState *input_state;
+ guint32 drop_bitrate;
+ guint64 time_per_frame;
+ guint64 frame_count;
+ guint64 previous_timestamp;
};
/* pad templates */
-static GstStaticPadTemplate gst_openh264enc_sink_template = GST_STATIC_PAD_TEMPLATE("sink",
+static GstStaticPadTemplate gst_openh264enc_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS(GST_VIDEO_CAPS_MAKE("I420"))
-);
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420"))
+ );
-static GstStaticPadTemplate gst_openh264enc_src_template = GST_STATIC_PAD_TEMPLATE("src",
+static GstStaticPadTemplate gst_openh264enc_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS("video/x-h264, stream-format=(string)\"avc\", alignment=(string)\"au\", profile=(string)\"baseline\"")
-);
+ GST_STATIC_CAPS
+ ("video/x-h264, stream-format=(string)\"avc\", alignment=(string)\"au\", profile=(string)\"baseline\"")
+ );
/* class initialization */
-G_DEFINE_TYPE_WITH_CODE(GstOpenh264Enc, gst_openh264enc, GST_TYPE_VIDEO_ENCODER,
- GST_DEBUG_CATEGORY_INIT(gst_openh264enc_debug_category, "openh264enc", 0,
+G_DEFINE_TYPE_WITH_CODE (GstOpenh264Enc, gst_openh264enc,
+ GST_TYPE_VIDEO_ENCODER,
+ GST_DEBUG_CATEGORY_INIT (gst_openh264enc_debug_category, "openh264enc", 0,
"debug category for openh264enc element"));
-static void gst_openh264enc_class_init(GstOpenh264EncClass *klass)
+static void
+gst_openh264enc_class_init (GstOpenh264EncClass * klass)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- GstVideoEncoderClass *video_encoder_class = GST_VIDEO_ENCODER_CLASS(klass);
-
- g_type_class_add_private(klass, sizeof(GstOpenh264EncPrivate));
-
- /* Setting up pads and setting metadata should be moved to
- base_class_init if you intend to subclass this class. */
- gst_element_class_add_pad_template(GST_ELEMENT_CLASS(klass),
- gst_static_pad_template_get(&gst_openh264enc_src_template));
- gst_element_class_add_pad_template(GST_ELEMENT_CLASS(klass),
- gst_static_pad_template_get(&gst_openh264enc_sink_template));
-
- gst_element_class_set_static_metadata(GST_ELEMENT_CLASS(klass), "OpenH264 video encoder", "Encoder/Video", "OpenH264 video encoder", "Ericsson AB, http://www.ericsson.com");
-
- gobject_class->set_property = gst_openh264enc_set_property;
- gobject_class->get_property = gst_openh264enc_get_property;
- gobject_class->finalize = gst_openh264enc_finalize;
- video_encoder_class->start = GST_DEBUG_FUNCPTR(gst_openh264enc_start);
- video_encoder_class->stop = GST_DEBUG_FUNCPTR(gst_openh264enc_stop);
- video_encoder_class->set_format = GST_DEBUG_FUNCPTR(gst_openh264enc_set_format);
- video_encoder_class->handle_frame = GST_DEBUG_FUNCPTR(gst_openh264enc_handle_frame);
- video_encoder_class->propose_allocation = GST_DEBUG_FUNCPTR(gst_openh264enc_propose_allocation);
- video_encoder_class->finish = GST_DEBUG_FUNCPTR(gst_openh264enc_finish);
-
- /* define properties */
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_USAGE_TYPE,
- g_param_spec_enum ("usage-type", "Usage type",
- "Type of video content",
- GST_TYPE_USAGE_TYPE, CAMERA_VIDEO_REAL_TIME,
- (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_RATE_CONTROL,
- g_param_spec_enum ("rate-control", "Rate control",
- "Rate control mode",
- GST_TYPE_RC_MODES, RC_QUALITY_MODE,
- (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MULTI_THREAD,
- g_param_spec_uint("multi-thread", "Number of threads",
- "The number of threads.",
- 0, G_MAXUINT, DEFAULT_MULTI_THREAD,
- (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
- g_object_class_install_property (gobject_class, PROP_ENABLE_DENOISE,
- g_param_spec_boolean ("enable-denoise", "Denoise Control",
- "Denoise control",
- FALSE,
- (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
- g_object_class_install_property(gobject_class, PROP_BITRATE,
- g_param_spec_uint("bitrate", "Bitrate",
- "Bitrate (in bits per second)",
- 0, G_MAXUINT, DEFAULT_BITRATE,
- (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
- g_object_class_install_property(gobject_class, PROP_GOP_SIZE,
- g_param_spec_uint("gop-size", "GOP size",
- "Number of frames between intra frames",
- 0, G_MAXUINT, DEFAULT_GOP_SIZE,
- (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
- g_object_class_install_property(gobject_class, PROP_MAX_SLICE_SIZE,
- g_param_spec_uint("max-slice-size", "Max slice size",
- "The maximum size of one slice (in bytes).",
- 0, G_MAXUINT, DEFAULT_MAX_SLICE_SIZE,
- (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstVideoEncoderClass *video_encoder_class = GST_VIDEO_ENCODER_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GstOpenh264EncPrivate));
+
+ /* Setting up pads and setting metadata should be moved to
+ base_class_init if you intend to subclass this class. */
+ gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
+ gst_static_pad_template_get (&gst_openh264enc_src_template));
+ gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
+ gst_static_pad_template_get (&gst_openh264enc_sink_template));
+
+ gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
+ "OpenH264 video encoder", "Encoder/Video", "OpenH264 video encoder",
+ "Ericsson AB, http://www.ericsson.com");
+
+ gobject_class->set_property = gst_openh264enc_set_property;
+ gobject_class->get_property = gst_openh264enc_get_property;
+ gobject_class->finalize = gst_openh264enc_finalize;
+ video_encoder_class->start = GST_DEBUG_FUNCPTR (gst_openh264enc_start);
+ video_encoder_class->stop = GST_DEBUG_FUNCPTR (gst_openh264enc_stop);
+ video_encoder_class->set_format =
+ GST_DEBUG_FUNCPTR (gst_openh264enc_set_format);
+ video_encoder_class->handle_frame =
+ GST_DEBUG_FUNCPTR (gst_openh264enc_handle_frame);
+ video_encoder_class->propose_allocation =
+ GST_DEBUG_FUNCPTR (gst_openh264enc_propose_allocation);
+ video_encoder_class->finish = GST_DEBUG_FUNCPTR (gst_openh264enc_finish);
+
+ /* define properties */
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_USAGE_TYPE,
+ g_param_spec_enum ("usage-type", "Usage type",
+ "Type of video content",
+ GST_TYPE_USAGE_TYPE, CAMERA_VIDEO_REAL_TIME,
+ (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_RATE_CONTROL,
+ g_param_spec_enum ("rate-control", "Rate control",
+ "Rate control mode",
+ GST_TYPE_RC_MODES, RC_QUALITY_MODE,
+ (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MULTI_THREAD,
+ g_param_spec_uint ("multi-thread", "Number of threads",
+ "The number of threads.",
+ 0, G_MAXUINT, DEFAULT_MULTI_THREAD,
+ (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+ g_object_class_install_property (gobject_class, PROP_ENABLE_DENOISE,
+ g_param_spec_boolean ("enable-denoise", "Denoise Control",
+ "Denoise control",
+ FALSE, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+ g_object_class_install_property (gobject_class, PROP_BITRATE,
+ g_param_spec_uint ("bitrate", "Bitrate",
+ "Bitrate (in bits per second)",
+ 0, G_MAXUINT, DEFAULT_BITRATE,
+ (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+ g_object_class_install_property (gobject_class, PROP_GOP_SIZE,
+ g_param_spec_uint ("gop-size", "GOP size",
+ "Number of frames between intra frames",
+ 0, G_MAXUINT, DEFAULT_GOP_SIZE,
+ (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+ g_object_class_install_property (gobject_class, PROP_MAX_SLICE_SIZE,
+ g_param_spec_uint ("max-slice-size", "Max slice size",
+ "The maximum size of one slice (in bytes).",
+ 0, G_MAXUINT, DEFAULT_MAX_SLICE_SIZE,
+ (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
}
-static void gst_openh264enc_init(GstOpenh264Enc *openh264enc)
+static void
+gst_openh264enc_init (GstOpenh264Enc * openh264enc)
{
- openh264enc->priv = GST_OPENH264ENC_GET_PRIVATE(openh264enc);
- openh264enc->priv->gop_size = DEFAULT_GOP_SIZE;
- openh264enc->priv->usage_type = DEFAULT_USAGE_TYPE;
- openh264enc->priv->rate_control = DEFAULT_RATE_CONTROL;
- openh264enc->priv->multi_thread = DEFAULT_MULTI_THREAD;
- openh264enc->priv->max_slice_size = DEFAULT_MAX_SLICE_SIZE;
- openh264enc->priv->bitrate = DEFAULT_BITRATE;
- openh264enc->priv->framerate = START_FRAMERATE;
- openh264enc->priv->input_state = NULL;
- openh264enc->priv->time_per_frame = GST_SECOND/openh264enc->priv->framerate;
- openh264enc->priv->frame_count = 0;
- openh264enc->priv->previous_timestamp = 0;
- openh264enc->priv->drop_bitrate = DROP_BITRATE;
- openh264enc->priv->enable_denoise = DEFAULT_ENABLE_DENOISE;
- openh264enc->priv->encoder = NULL;
- gst_openh264enc_set_usage_type(openh264enc, CAMERA_VIDEO_REAL_TIME);
- gst_openh264enc_set_rate_control(openh264enc, RC_QUALITY_MODE);
+ openh264enc->priv = GST_OPENH264ENC_GET_PRIVATE (openh264enc);
+ openh264enc->priv->gop_size = DEFAULT_GOP_SIZE;
+ openh264enc->priv->usage_type = DEFAULT_USAGE_TYPE;
+ openh264enc->priv->rate_control = DEFAULT_RATE_CONTROL;
+ openh264enc->priv->multi_thread = DEFAULT_MULTI_THREAD;
+ openh264enc->priv->max_slice_size = DEFAULT_MAX_SLICE_SIZE;
+ openh264enc->priv->bitrate = DEFAULT_BITRATE;
+ openh264enc->priv->framerate = START_FRAMERATE;
+ openh264enc->priv->input_state = NULL;
+ openh264enc->priv->time_per_frame = GST_SECOND / openh264enc->priv->framerate;
+ openh264enc->priv->frame_count = 0;
+ openh264enc->priv->previous_timestamp = 0;
+ openh264enc->priv->drop_bitrate = DROP_BITRATE;
+ openh264enc->priv->enable_denoise = DEFAULT_ENABLE_DENOISE;
+ openh264enc->priv->encoder = NULL;
+ gst_openh264enc_set_usage_type (openh264enc, CAMERA_VIDEO_REAL_TIME);
+ gst_openh264enc_set_rate_control (openh264enc, RC_QUALITY_MODE);
}
static void
-gst_openh264enc_set_usage_type (GstOpenh264Enc *openh264enc, gint usage_type)
+gst_openh264enc_set_usage_type (GstOpenh264Enc * openh264enc, gint usage_type)
{
- switch (usage_type) {
- case CAMERA_VIDEO_REAL_TIME:
- openh264enc->priv->usage_type = CAMERA_VIDEO_REAL_TIME;
- break;
- case SCREEN_CONTENT_REAL_TIME:
- openh264enc->priv->usage_type = SCREEN_CONTENT_REAL_TIME;
- break;
- default:
- g_assert_not_reached ();
- }
+ switch (usage_type) {
+ case CAMERA_VIDEO_REAL_TIME:
+ openh264enc->priv->usage_type = CAMERA_VIDEO_REAL_TIME;
+ break;
+ case SCREEN_CONTENT_REAL_TIME:
+ openh264enc->priv->usage_type = SCREEN_CONTENT_REAL_TIME;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
}
static void
-gst_openh264enc_set_rate_control (GstOpenh264Enc *openh264enc, gint rc_mode)
+gst_openh264enc_set_rate_control (GstOpenh264Enc * openh264enc, gint rc_mode)
{
- switch (rc_mode) {
- case RC_QUALITY_MODE:
- openh264enc->priv->rate_control = RC_QUALITY_MODE;
- break;
- case RC_BITRATE_MODE:
- openh264enc->priv->rate_control = RC_BITRATE_MODE;
- break;
- case RC_LOW_BW_MODE:
- openh264enc->priv->rate_control = RC_LOW_BW_MODE;
- break;
- case RC_OFF_MODE:
- openh264enc->priv->rate_control = RC_OFF_MODE;
- break;
- default:
- g_assert_not_reached ();
- }
+ switch (rc_mode) {
+ case RC_QUALITY_MODE:
+ openh264enc->priv->rate_control = RC_QUALITY_MODE;
+ break;
+ case RC_BITRATE_MODE:
+ openh264enc->priv->rate_control = RC_BITRATE_MODE;
+ break;
+ case RC_LOW_BW_MODE:
+ openh264enc->priv->rate_control = RC_LOW_BW_MODE;
+ break;
+ case RC_OFF_MODE:
+ openh264enc->priv->rate_control = RC_OFF_MODE;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
}
-void gst_openh264enc_set_property(GObject *object, guint property_id,
- const GValue *value, GParamSpec *pspec)
+void
+gst_openh264enc_set_property (GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec)
{
- GstOpenh264Enc *openh264enc = GST_OPENH264ENC(object);
+ GstOpenh264Enc *openh264enc = GST_OPENH264ENC (object);
- GST_DEBUG_OBJECT(openh264enc, "set_property");
+ GST_DEBUG_OBJECT (openh264enc, "set_property");
- switch (property_id) {
+ switch (property_id) {
case PROP_BITRATE:
- openh264enc->priv->bitrate = g_value_get_uint(value);
- break;
+ openh264enc->priv->bitrate = g_value_get_uint (value);
+ break;
case PROP_MULTI_THREAD:
- openh264enc->priv->multi_thread = g_value_get_uint(value);
- break;
+ openh264enc->priv->multi_thread = g_value_get_uint (value);
+ break;
case PROP_USAGE_TYPE:
- gst_openh264enc_set_usage_type(openh264enc, g_value_get_enum (value));
- break;
+ gst_openh264enc_set_usage_type (openh264enc, g_value_get_enum (value));
+ break;
case PROP_ENABLE_DENOISE:
- openh264enc->priv->enable_denoise = g_value_get_boolean(value);
- break;
+ openh264enc->priv->enable_denoise = g_value_get_boolean (value);
+ break;
case PROP_RATE_CONTROL:
- gst_openh264enc_set_rate_control(openh264enc, g_value_get_enum (value));
- break;
+ gst_openh264enc_set_rate_control (openh264enc, g_value_get_enum (value));
+ break;
case PROP_GOP_SIZE:
- openh264enc->priv->gop_size = g_value_get_uint(value);
- break;
+ openh264enc->priv->gop_size = g_value_get_uint (value);
+ break;
case PROP_MAX_SLICE_SIZE:
- openh264enc->priv->max_slice_size = g_value_get_uint(value);
- break;
+ openh264enc->priv->max_slice_size = g_value_get_uint (value);
+ break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
}
-void gst_openh264enc_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+void
+gst_openh264enc_get_property (GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec)
{
- GstOpenh264Enc *openh264enc = GST_OPENH264ENC(object);
+ GstOpenh264Enc *openh264enc = GST_OPENH264ENC (object);
- GST_DEBUG_OBJECT(openh264enc, "get_property");
+ GST_DEBUG_OBJECT (openh264enc, "get_property");
- switch (property_id) {
+ switch (property_id) {
case PROP_USAGE_TYPE:
- g_value_set_enum(value, openh264enc->priv->usage_type);
- break;
+ g_value_set_enum (value, openh264enc->priv->usage_type);
+ break;
case PROP_RATE_CONTROL:
- g_value_set_enum(value, openh264enc->priv->rate_control);
- break;
+ g_value_set_enum (value, openh264enc->priv->rate_control);
+ break;
case PROP_BITRATE:
- g_value_set_uint(value, openh264enc->priv->bitrate);
- break;
+ g_value_set_uint (value, openh264enc->priv->bitrate);
+ break;
case PROP_ENABLE_DENOISE:
- g_value_set_boolean(value, openh264enc->priv->enable_denoise);
- break;
+ g_value_set_boolean (value, openh264enc->priv->enable_denoise);
+ break;
case PROP_MULTI_THREAD:
- g_value_set_uint(value, openh264enc->priv->multi_thread);
- break;
+ g_value_set_uint (value, openh264enc->priv->multi_thread);
+ break;
case PROP_GOP_SIZE:
- g_value_set_uint(value, openh264enc->priv->gop_size);
- break;
+ g_value_set_uint (value, openh264enc->priv->gop_size);
+ break;
case PROP_MAX_SLICE_SIZE:
- g_value_set_uint(value, openh264enc->priv->max_slice_size);
- break;
+ g_value_set_uint (value, openh264enc->priv->max_slice_size);
+ break;
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
}
-void gst_openh264enc_finalize(GObject * object)
+void
+gst_openh264enc_finalize (GObject * object)
{
- GstOpenh264Enc *openh264enc = GST_OPENH264ENC(object);
+ GstOpenh264Enc *openh264enc = GST_OPENH264ENC (object);
- GST_DEBUG_OBJECT(openh264enc, "finalize");
+ GST_DEBUG_OBJECT (openh264enc, "finalize");
- /* clean up object here */
+ /* clean up object here */
- if (openh264enc->priv->input_state) {
- gst_video_codec_state_unref(openh264enc->priv->input_state);
- }
- openh264enc->priv->input_state = NULL;
+ if (openh264enc->priv->input_state) {
+ gst_video_codec_state_unref (openh264enc->priv->input_state);
+ }
+ openh264enc->priv->input_state = NULL;
- G_OBJECT_CLASS(gst_openh264enc_parent_class)->finalize(object);
+ G_OBJECT_CLASS (gst_openh264enc_parent_class)->finalize (object);
}
-static gboolean gst_openh264enc_start(GstVideoEncoder *encoder)
+static gboolean
+gst_openh264enc_start (GstVideoEncoder * encoder)
{
- GstOpenh264Enc *openh264enc = GST_OPENH264ENC(encoder);
- GST_DEBUG_OBJECT(openh264enc, "start");
+ GstOpenh264Enc *openh264enc = GST_OPENH264ENC (encoder);
+ GST_DEBUG_OBJECT (openh264enc, "start");
- return TRUE;
+ return TRUE;
}
-static gboolean gst_openh264enc_stop(GstVideoEncoder *encoder)
+static gboolean
+gst_openh264enc_stop (GstVideoEncoder * encoder)
{
- GstOpenh264Enc *openh264enc;
+ GstOpenh264Enc *openh264enc;
- openh264enc = GST_OPENH264ENC(encoder);
+ openh264enc = GST_OPENH264ENC (encoder);
- if (openh264enc->priv->encoder != NULL) {
- openh264enc->priv->encoder->Uninitialize();
- WelsDestroySVCEncoder(openh264enc->priv->encoder);
- openh264enc->priv->encoder = NULL;
- }
+ if (openh264enc->priv->encoder != NULL) {
+ openh264enc->priv->encoder->Uninitialize ();
+ WelsDestroySVCEncoder (openh264enc->priv->encoder);
openh264enc->priv->encoder = NULL;
+ }
+ openh264enc->priv->encoder = NULL;
- if (openh264enc->priv->input_state) {
- gst_video_codec_state_unref(openh264enc->priv->input_state);
- }
- openh264enc->priv->input_state = NULL;
+ if (openh264enc->priv->input_state) {
+ gst_video_codec_state_unref (openh264enc->priv->input_state);
+ }
+ openh264enc->priv->input_state = NULL;
- GST_DEBUG_OBJECT(openh264enc, "openh264_enc_stop called");
+ GST_DEBUG_OBJECT (openh264enc, "openh264_enc_stop called");
- return TRUE;
+ return TRUE;
}
-static gboolean gst_openh264enc_set_format(GstVideoEncoder *encoder, GstVideoCodecState *state)
+static gboolean
+gst_openh264enc_set_format (GstVideoEncoder * encoder,
+ GstVideoCodecState * state)
{
- GstOpenh264Enc *openh264enc = GST_OPENH264ENC(encoder);
- GstOpenh264EncPrivate *priv = openh264enc->priv;
- gchar *debug_caps;
- SFrameBSInfo bsInfo;
- guint width, height, fps_n, fps_d;
- SEncParamExt enc_params;
- gint ret;
- guchar *nal_sps_data = NULL;
- gint nal_sps_length = 0;
- guchar *nal_pps_data = NULL;
- gint nal_pps_length = 0;
- guchar *sps_tmp_buf;
- guchar *codec_data_tmp_buf;
- GstBuffer *codec_data;
- GstCaps *outcaps;
- GstVideoCodecState *output_state;
- openh264enc->priv->frame_count = 0;
-
- debug_caps = gst_caps_to_string(state->caps);
- GST_DEBUG_OBJECT(openh264enc, "gst_e26d4_enc_set_format called, caps: %s", debug_caps);
- g_free(debug_caps);
-
- gst_openh264enc_stop(encoder);
-
- if (priv->input_state) {
- gst_video_codec_state_unref(priv->input_state);
- }
- priv->input_state = gst_video_codec_state_ref(state);
-
- width = GST_VIDEO_INFO_WIDTH(&state->info);
- height = GST_VIDEO_INFO_HEIGHT(&state->info);
- fps_n = GST_VIDEO_INFO_FPS_N(&state->info);
- fps_d = GST_VIDEO_INFO_FPS_D(&state->info);
-
- if (priv->encoder != NULL) {
- priv->encoder->Uninitialize();
- WelsDestroySVCEncoder(priv->encoder);
- priv->encoder = NULL;
- }
- WelsCreateSVCEncoder(&(priv->encoder));
- priv->encoder->GetDefaultParams(&enc_params);
-
- enc_params.iUsageType = openh264enc->priv->usage_type;
- enc_params.iPicWidth = width;
- enc_params.iPicHeight = height;
- enc_params.iTargetBitrate = openh264enc->priv->bitrate;
- enc_params.iRCMode = RC_QUALITY_MODE;
- enc_params.iTemporalLayerNum = 1;
- enc_params.iSpatialLayerNum = 1;
- enc_params.iLtrMarkPeriod = 30;
- enc_params.iInputCsp = videoFormatI420;
- enc_params.iMultipleThreadIdc = openh264enc->priv->multi_thread;
- enc_params.bEnableDenoise = openh264enc->priv->enable_denoise;
- enc_params.uiIntraPeriod = priv->gop_size;
- enc_params.bEnableDenoise = 0;
- enc_params.bEnableBackgroundDetection = 1;
- enc_params.bEnableAdaptiveQuant = 1;
- enc_params.bEnableFrameSkip = 1;
- enc_params.bEnableLongTermReference = 0;
- enc_params.bEnableSpsPpsIdAddition = 1;
- enc_params.bPrefixNalAddingCtrl = 0;
- enc_params.fMaxFrameRate = fps_n * 1.0 / fps_d;
- enc_params.sSpatialLayers[0].uiProfileIdc = PRO_BASELINE;
- enc_params.sSpatialLayers[0].iVideoWidth = width;
- enc_params.sSpatialLayers[0].iVideoHeight = height;
- enc_params.sSpatialLayers[0].fFrameRate = fps_n * 1.0 / fps_d;
- enc_params.sSpatialLayers[0].iSpatialBitrate = openh264enc->priv->bitrate;
- enc_params.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
-
- priv->framerate = (1 + fps_n / fps_d);
-
- ret = priv->encoder->InitializeExt(&enc_params) ;
-
- if (ret != cmResultSuccess) {
- GST_ERROR_OBJECT(openh264enc, "failed to initialize encoder");
- return FALSE;
- }
-
- memset (&bsInfo, 0, sizeof (SFrameBSInfo));
-
- ret = priv->encoder->EncodeParameterSets (&bsInfo);
-
- nal_sps_data = bsInfo.sLayerInfo[0].pBsBuf + 4;
- nal_sps_length = bsInfo.sLayerInfo[0].pNalLengthInByte[0] - 4;
-
- nal_pps_data = bsInfo.sLayerInfo[0].pBsBuf + nal_sps_length + 8;
- nal_pps_length = bsInfo.sLayerInfo[0].pNalLengthInByte[1] - 4;
-
- if (ret != cmResultSuccess) {
- GST_ELEMENT_ERROR(openh264enc, STREAM, ENCODE, ("Could not create headers"), ("Could not create SPS"));
- return FALSE;
- }
-
- sps_tmp_buf = (guchar *)(g_memdup(nal_sps_data, nal_sps_length));
-
- codec_data_tmp_buf = (guchar *)g_malloc(5 + 3 + nal_sps_length + 3 + nal_pps_length);
- codec_data_tmp_buf[0] = 1; /* version 1 */;
- codec_data_tmp_buf[1] = sps_tmp_buf[1]; /* profile */
- codec_data_tmp_buf[2] = sps_tmp_buf[2]; /* profile constraints */
- codec_data_tmp_buf[3] = sps_tmp_buf[3]; /* level */
- codec_data_tmp_buf[4] = 1; /* NAL length marker length minus one */
- codec_data_tmp_buf[5] = 1; /* Number of SPS */
- GST_WRITE_UINT16_BE(codec_data_tmp_buf + 6, nal_sps_length);
- memcpy(codec_data_tmp_buf + 8, sps_tmp_buf, nal_sps_length);
-
- g_free(sps_tmp_buf);
-
- codec_data_tmp_buf[8 + nal_sps_length] = 1; /* Number of PPS */
- GST_WRITE_UINT16_BE(codec_data_tmp_buf + 8 + nal_sps_length + 1, nal_pps_length);
- memcpy(codec_data_tmp_buf + 8 + nal_sps_length + 3, nal_pps_data, nal_pps_length);
-
- GST_DEBUG_OBJECT(openh264enc, "Got SPS of size %d and PPS of size %d", nal_sps_length, nal_pps_length);
-
- codec_data = gst_buffer_new_wrapped(codec_data_tmp_buf, 5 + 3 + nal_sps_length + 3 + nal_pps_length);
-
- outcaps = gst_caps_copy(gst_static_pad_template_get_caps(&gst_openh264enc_src_template));
- gst_caps_set_simple(outcaps,
- "codec_data", GST_TYPE_BUFFER, codec_data,
- NULL);
- gst_buffer_unref(codec_data);
-
- output_state = gst_video_encoder_set_output_state(encoder, outcaps, state);
- gst_video_codec_state_unref(output_state);
-
- return gst_video_encoder_negotiate (encoder);
+ GstOpenh264Enc *openh264enc = GST_OPENH264ENC (encoder);
+ GstOpenh264EncPrivate *priv = openh264enc->priv;
+ gchar *debug_caps;
+ SFrameBSInfo bsInfo;
+ guint width, height, fps_n, fps_d;
+ SEncParamExt enc_params;
+ gint ret;
+ guchar *nal_sps_data = NULL;
+ gint nal_sps_length = 0;
+ guchar *nal_pps_data = NULL;
+ gint nal_pps_length = 0;
+ guchar *sps_tmp_buf;
+ guchar *codec_data_tmp_buf;
+ GstBuffer *codec_data;
+ GstCaps *outcaps;
+ GstVideoCodecState *output_state;
+ openh264enc->priv->frame_count = 0;
+
+ debug_caps = gst_caps_to_string (state->caps);
+ GST_DEBUG_OBJECT (openh264enc, "gst_e26d4_enc_set_format called, caps: %s",
+ debug_caps);
+ g_free (debug_caps);
+
+ gst_openh264enc_stop (encoder);
+
+ if (priv->input_state) {
+ gst_video_codec_state_unref (priv->input_state);
+ }
+ priv->input_state = gst_video_codec_state_ref (state);
+
+ width = GST_VIDEO_INFO_WIDTH (&state->info);
+ height = GST_VIDEO_INFO_HEIGHT (&state->info);
+ fps_n = GST_VIDEO_INFO_FPS_N (&state->info);
+ fps_d = GST_VIDEO_INFO_FPS_D (&state->info);
+
+ if (priv->encoder != NULL) {
+ priv->encoder->Uninitialize ();
+ WelsDestroySVCEncoder (priv->encoder);
+ priv->encoder = NULL;
+ }
+ WelsCreateSVCEncoder (&(priv->encoder));
+ priv->encoder->GetDefaultParams (&enc_params);
+
+ enc_params.iUsageType = openh264enc->priv->usage_type;
+ enc_params.iPicWidth = width;
+ enc_params.iPicHeight = height;
+ enc_params.iTargetBitrate = openh264enc->priv->bitrate;
+ enc_params.iRCMode = RC_QUALITY_MODE;
+ enc_params.iTemporalLayerNum = 1;
+ enc_params.iSpatialLayerNum = 1;
+ enc_params.iLtrMarkPeriod = 30;
+ enc_params.iInputCsp = videoFormatI420;
+ enc_params.iMultipleThreadIdc = openh264enc->priv->multi_thread;
+ enc_params.bEnableDenoise = openh264enc->priv->enable_denoise;
+ enc_params.uiIntraPeriod = priv->gop_size;
+ enc_params.bEnableDenoise = 0;
+ enc_params.bEnableBackgroundDetection = 1;
+ enc_params.bEnableAdaptiveQuant = 1;
+ enc_params.bEnableFrameSkip = 1;
+ enc_params.bEnableLongTermReference = 0;
+ enc_params.bEnableSpsPpsIdAddition = 1;
+ enc_params.bPrefixNalAddingCtrl = 0;
+ enc_params.fMaxFrameRate = fps_n * 1.0 / fps_d;
+ enc_params.sSpatialLayers[0].uiProfileIdc = PRO_BASELINE;
+ enc_params.sSpatialLayers[0].iVideoWidth = width;
+ enc_params.sSpatialLayers[0].iVideoHeight = height;
+ enc_params.sSpatialLayers[0].fFrameRate = fps_n * 1.0 / fps_d;
+ enc_params.sSpatialLayers[0].iSpatialBitrate = openh264enc->priv->bitrate;
+ enc_params.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
+
+ priv->framerate = (1 + fps_n / fps_d);
+
+ ret = priv->encoder->InitializeExt (&enc_params);
+
+ if (ret != cmResultSuccess) {
+ GST_ERROR_OBJECT (openh264enc, "failed to initialize encoder");
+ return FALSE;
+ }
+
+ memset (&bsInfo, 0, sizeof (SFrameBSInfo));
+
+ ret = priv->encoder->EncodeParameterSets (&bsInfo);
+
+ nal_sps_data = bsInfo.sLayerInfo[0].pBsBuf + 4;
+ nal_sps_length = bsInfo.sLayerInfo[0].pNalLengthInByte[0] - 4;
+
+ nal_pps_data = bsInfo.sLayerInfo[0].pBsBuf + nal_sps_length + 8;
+ nal_pps_length = bsInfo.sLayerInfo[0].pNalLengthInByte[1] - 4;
+
+ if (ret != cmResultSuccess) {
+ GST_ELEMENT_ERROR (openh264enc, STREAM, ENCODE,
+ ("Could not create headers"), ("Could not create SPS"));
+ return FALSE;
+ }
+
+ sps_tmp_buf = (guchar *) (g_memdup (nal_sps_data, nal_sps_length));
+
+ codec_data_tmp_buf =
+ (guchar *) g_malloc (5 + 3 + nal_sps_length + 3 + nal_pps_length);
+ codec_data_tmp_buf[0] = 1; /* version 1 */ ;
+ codec_data_tmp_buf[1] = sps_tmp_buf[1]; /* profile */
+ codec_data_tmp_buf[2] = sps_tmp_buf[2]; /* profile constraints */
+ codec_data_tmp_buf[3] = sps_tmp_buf[3]; /* level */
+ codec_data_tmp_buf[4] = 1; /* NAL length marker length minus one */
+ codec_data_tmp_buf[5] = 1; /* Number of SPS */
+ GST_WRITE_UINT16_BE (codec_data_tmp_buf + 6, nal_sps_length);
+ memcpy (codec_data_tmp_buf + 8, sps_tmp_buf, nal_sps_length);
+
+ g_free (sps_tmp_buf);
+
+ codec_data_tmp_buf[8 + nal_sps_length] = 1; /* Number of PPS */
+ GST_WRITE_UINT16_BE (codec_data_tmp_buf + 8 + nal_sps_length + 1,
+ nal_pps_length);
+ memcpy (codec_data_tmp_buf + 8 + nal_sps_length + 3, nal_pps_data,
+ nal_pps_length);
+
+ GST_DEBUG_OBJECT (openh264enc, "Got SPS of size %d and PPS of size %d",
+ nal_sps_length, nal_pps_length);
+
+ codec_data =
+ gst_buffer_new_wrapped (codec_data_tmp_buf,
+ 5 + 3 + nal_sps_length + 3 + nal_pps_length);
+
+ outcaps =
+ gst_caps_copy (gst_static_pad_template_get_caps
+ (&gst_openh264enc_src_template));
+ gst_caps_set_simple (outcaps, "codec_data", GST_TYPE_BUFFER, codec_data,
+ NULL);
+ gst_buffer_unref (codec_data);
+
+ output_state = gst_video_encoder_set_output_state (encoder, outcaps, state);
+ gst_video_codec_state_unref (output_state);
+
+ return gst_video_encoder_negotiate (encoder);
}
-static gboolean gst_openh264enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
+static gboolean
+gst_openh264enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
{
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
- return GST_VIDEO_ENCODER_CLASS (gst_openh264enc_parent_class)->propose_allocation (encoder,
- query);
+ return
+ GST_VIDEO_ENCODER_CLASS (gst_openh264enc_parent_class)->propose_allocation
+ (encoder, query);
}
-static GstFlowReturn gst_openh264enc_handle_frame(GstVideoEncoder *encoder, GstVideoCodecFrame *frame)
+static GstFlowReturn
+gst_openh264enc_handle_frame (GstVideoEncoder * encoder,
+ GstVideoCodecFrame * frame)
{
- GstOpenh264Enc *openh264enc = GST_OPENH264ENC(encoder);
- SSourcePicture* src_pic = NULL;
- GstVideoFrame video_frame;
- gboolean force_keyframe;
- gint ret;
- SFrameBSInfo frame_info;
- gfloat fps;
- GstVideoEncoder *base_encoder = GST_VIDEO_ENCODER(openh264enc);
-
- if (frame) {
- src_pic = new SSourcePicture;
-
- if (src_pic == NULL) {
- if (frame)
- gst_video_codec_frame_unref(frame);
- return GST_FLOW_ERROR;
+ GstOpenh264Enc *openh264enc = GST_OPENH264ENC (encoder);
+ SSourcePicture *src_pic = NULL;
+ GstVideoFrame video_frame;
+ gboolean force_keyframe;
+ gint ret;
+ SFrameBSInfo frame_info;
+ gfloat fps;
+ GstVideoEncoder *base_encoder = GST_VIDEO_ENCODER (openh264enc);
+
+ if (frame) {
+ src_pic = new SSourcePicture;
+
+ if (src_pic == NULL) {
+ if (frame)
+ gst_video_codec_frame_unref (frame);
+ return GST_FLOW_ERROR;
+ }
+ //fill default src_pic
+ src_pic->iColorFormat = videoFormatI420;
+ src_pic->uiTimeStamp = 0;
+ }
+
+ openh264enc->priv->frame_count++;
+ if (frame) {
+ if (G_UNLIKELY (openh264enc->priv->frame_count == 1)) {
+ openh264enc->priv->time_per_frame =
+ (GST_NSECOND / openh264enc->priv->framerate);
+ openh264enc->priv->previous_timestamp = frame->pts;
+ } else {
+ openh264enc->priv->time_per_frame =
+ openh264enc->priv->time_per_frame * 0.8 + (frame->pts -
+ openh264enc->priv->previous_timestamp) * 0.2;
+ openh264enc->priv->previous_timestamp = frame->pts;
+ if (openh264enc->priv->frame_count % 10 == 0) {
+ fps = GST_SECOND / (gdouble) openh264enc->priv->time_per_frame;
+ openh264enc->priv->encoder->SetOption (ENCODER_OPTION_FRAME_RATE, &fps);
}
- //fill default src_pic
- src_pic->iColorFormat = videoFormatI420;
- src_pic->uiTimeStamp = 0;
}
+ }
- openh264enc->priv->frame_count++;
+ if (openh264enc->priv->bitrate <= openh264enc->priv->drop_bitrate) {
+ GST_LOG_OBJECT (openh264enc, "Dropped frame due to too low bitrate");
if (frame) {
- if (G_UNLIKELY(openh264enc->priv->frame_count == 1)) {
- openh264enc->priv->time_per_frame = (GST_NSECOND / openh264enc->priv->framerate);
- openh264enc->priv->previous_timestamp = frame->pts;
- } else {
- openh264enc->priv->time_per_frame = openh264enc->priv->time_per_frame * 0.8 +
- (frame->pts - openh264enc->priv->previous_timestamp) * 0.2;
- openh264enc->priv->previous_timestamp = frame->pts;
- if (openh264enc->priv->frame_count % 10 == 0) {
- fps = GST_SECOND/(gdouble)openh264enc->priv->time_per_frame;
- openh264enc->priv->encoder->SetOption(ENCODER_OPTION_FRAME_RATE, &fps);
- }
- }
+ gst_video_encoder_finish_frame (encoder, frame);
+ delete src_pic;
}
-
- if (openh264enc->priv->bitrate <= openh264enc->priv->drop_bitrate) {
- GST_LOG_OBJECT(openh264enc, "Dropped frame due to too low bitrate");
- if (frame) {
- gst_video_encoder_finish_frame(encoder, frame);
- delete src_pic;
- }
- return GST_FLOW_OK;
+ return GST_FLOW_OK;
+ }
+
+ if (frame) {
+ gst_video_frame_map (&video_frame, &openh264enc->priv->input_state->info,
+ frame->input_buffer, GST_MAP_READ);
+ src_pic->iPicWidth = GST_VIDEO_FRAME_WIDTH (&video_frame);
+ src_pic->iPicHeight = GST_VIDEO_FRAME_HEIGHT (&video_frame);
+ src_pic->iStride[0] = GST_VIDEO_FRAME_COMP_STRIDE (&video_frame, 0);
+ src_pic->iStride[1] = GST_VIDEO_FRAME_COMP_STRIDE (&video_frame, 1);
+ src_pic->iStride[2] = GST_VIDEO_FRAME_COMP_STRIDE (&video_frame, 2);
+ src_pic->pData[0] = GST_VIDEO_FRAME_COMP_DATA (&video_frame, 0);
+ src_pic->pData[1] = GST_VIDEO_FRAME_COMP_DATA (&video_frame, 1);
+ src_pic->pData[2] = GST_VIDEO_FRAME_COMP_DATA (&video_frame, 2);
+
+ force_keyframe = GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame);
+ if (force_keyframe) {
+ openh264enc->priv->encoder->ForceIntraFrame (true);
+ GST_DEBUG_OBJECT (openh264enc,
+ "Got force key unit event, next frame coded as intra picture");
}
+ }
+ memset (&frame_info, 0, sizeof (SFrameBSInfo));
+ ret = openh264enc->priv->encoder->EncodeFrame (src_pic, &frame_info);
+ if (ret != cmResultSuccess) {
if (frame) {
- gst_video_frame_map(&video_frame, &openh264enc->priv->input_state->info, frame->input_buffer, GST_MAP_READ);
- src_pic->iPicWidth = GST_VIDEO_FRAME_WIDTH(&video_frame);
- src_pic->iPicHeight = GST_VIDEO_FRAME_HEIGHT(&video_frame);
- src_pic->iStride[0] = GST_VIDEO_FRAME_COMP_STRIDE(&video_frame, 0);
- src_pic->iStride[1] = GST_VIDEO_FRAME_COMP_STRIDE(&video_frame, 1);
- src_pic->iStride[2] = GST_VIDEO_FRAME_COMP_STRIDE(&video_frame, 2);
- src_pic->pData[0] = GST_VIDEO_FRAME_COMP_DATA(&video_frame, 0);
- src_pic->pData[1] = GST_VIDEO_FRAME_COMP_DATA(&video_frame, 1);
- src_pic->pData[2] = GST_VIDEO_FRAME_COMP_DATA(&video_frame, 2);
-
- force_keyframe = GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME(frame);
- if (force_keyframe) {
- openh264enc->priv->encoder->ForceIntraFrame(true);
- GST_DEBUG_OBJECT(openh264enc,"Got force key unit event, next frame coded as intra picture");
- }
- }
-
- memset (&frame_info, 0, sizeof (SFrameBSInfo));
- ret = openh264enc->priv->encoder->EncodeFrame(src_pic, &frame_info);
- if (ret != cmResultSuccess) {
- if (frame) {
- gst_video_frame_unmap(&video_frame);
- gst_video_codec_frame_unref(frame);
- delete src_pic;
- GST_ELEMENT_ERROR(openh264enc, STREAM, ENCODE, ("Could not encode frame"), ("Openh264 returned %d", ret));
- return GST_FLOW_ERROR;
- } else {
- return GST_FLOW_EOS;
- }
- }
-
- if (videoFrameTypeSkip == frame_info.eFrameType) {
- if (frame) {
- gst_video_frame_unmap(&video_frame);
- gst_video_encoder_finish_frame(base_encoder, frame);
- delete src_pic;
- }
-
- return GST_FLOW_OK;
+ gst_video_frame_unmap (&video_frame);
+ gst_video_codec_frame_unref (frame);
+ delete src_pic;
+ GST_ELEMENT_ERROR (openh264enc, STREAM, ENCODE,
+ ("Could not encode frame"), ("Openh264 returned %d", ret));
+ return GST_FLOW_ERROR;
+ } else {
+ return GST_FLOW_EOS;
}
+ }
+ if (videoFrameTypeSkip == frame_info.eFrameType) {
if (frame) {
- gst_video_frame_unmap(&video_frame);
- gst_video_codec_frame_unref(frame);
+ gst_video_frame_unmap (&video_frame);
+ gst_video_encoder_finish_frame (base_encoder, frame);
delete src_pic;
- src_pic = NULL;
- frame = NULL;
- }
-
- /* FIXME: openh264 has no way for us to get a connection
- * between the input and output frames, we just have to
- * guess based on the input */
- frame = gst_video_encoder_get_oldest_frame(base_encoder);
- if (!frame) {
- GST_ELEMENT_ERROR(openh264enc, STREAM, ENCODE, ("Could not encode frame"), ("openh264enc returned %d", ret));
- gst_video_codec_frame_unref(frame);
- return GST_FLOW_ERROR;
}
- SLayerBSInfo* bs_info = &frame_info.sLayerInfo[0];
- gint nal_size = bs_info->pNalLengthInByte[0] - 4;
- guchar *nal_sps_data, *nal_pps_data;
- gint nal_sps_length, nal_pps_length, idr_length, tmp_buf_length;
-
- if (videoFrameTypeIDR == frame_info.eFrameType) {
- GstMapInfo map;
-
- /* sps */
- nal_sps_data = frame_info.sLayerInfo[0].pBsBuf + 4;
- nal_sps_length = frame_info.sLayerInfo[0].pNalLengthInByte[0] - 4;
- /* pps */
- nal_pps_data = nal_sps_data + frame_info.sLayerInfo[0].pNalLengthInByte[0];
- nal_pps_length = frame_info.sLayerInfo[0].pNalLengthInByte[1] - 4;
- /* idr */
- bs_info = &frame_info.sLayerInfo[1];
- idr_length = bs_info->pNalLengthInByte[0] - 4;
-
- tmp_buf_length = nal_sps_length + 2 + nal_pps_length + 2 + idr_length + 2;
- frame->output_buffer = gst_video_encoder_allocate_output_buffer (encoder, tmp_buf_length);
- gst_buffer_map (frame->output_buffer, &map, GST_MAP_WRITE);
-
- GST_WRITE_UINT16_BE(map.data, nal_sps_length);
- memcpy(map.data + 2, nal_sps_data, nal_sps_length);
-
- GST_WRITE_UINT16_BE(map.data + nal_sps_length + 2, nal_pps_length);
- memcpy(map.data + nal_sps_length + 2 + 2, nal_pps_data, nal_pps_length);
-
- GST_WRITE_UINT16_BE(map.data + nal_sps_length + 2 + nal_pps_length + 2 , idr_length);
- memcpy(map.data + nal_sps_length + 2 + nal_pps_length + 2 + 2, bs_info->pBsBuf + 4, idr_length);
-
- gst_buffer_unmap (frame->output_buffer, &map);
-
- GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT(frame);
- } else {
- GstMapInfo map;
-
- tmp_buf_length = nal_size + 2;
- frame->output_buffer = gst_video_encoder_allocate_output_buffer (encoder, tmp_buf_length);
- gst_buffer_map (frame->output_buffer, &map, GST_MAP_WRITE);
-
- GST_WRITE_UINT16_BE(map.data, nal_size);
- memcpy(map.data + 2, bs_info->pBsBuf + 4, nal_size);
-
- gst_buffer_unmap (frame->output_buffer, &map);
-
- GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT(frame);
- }
-
- GST_LOG_OBJECT(openh264enc, "openh264 picture %scoded OK!", (ret != cmResultSuccess) ? "NOT " : "");
-
- return gst_video_encoder_finish_frame(encoder, frame);
+ return GST_FLOW_OK;
+ }
+
+ if (frame) {
+ gst_video_frame_unmap (&video_frame);
+ gst_video_codec_frame_unref (frame);
+ delete src_pic;
+ src_pic = NULL;
+ frame = NULL;
+ }
+
+ /* FIXME: openh264 has no way for us to get a connection
+ * between the input and output frames, we just have to
+ * guess based on the input */
+ frame = gst_video_encoder_get_oldest_frame (base_encoder);
+ if (!frame) {
+ GST_ELEMENT_ERROR (openh264enc, STREAM, ENCODE, ("Could not encode frame"),
+ ("openh264enc returned %d", ret));
+ gst_video_codec_frame_unref (frame);
+ return GST_FLOW_ERROR;
+ }
+
+ SLayerBSInfo *bs_info = &frame_info.sLayerInfo[0];
+ gint nal_size = bs_info->pNalLengthInByte[0] - 4;
+ guchar *nal_sps_data, *nal_pps_data;
+ gint nal_sps_length, nal_pps_length, idr_length, tmp_buf_length;
+
+ if (videoFrameTypeIDR == frame_info.eFrameType) {
+ GstMapInfo map;
+
+ /* sps */
+ nal_sps_data = frame_info.sLayerInfo[0].pBsBuf + 4;
+ nal_sps_length = frame_info.sLayerInfo[0].pNalLengthInByte[0] - 4;
+ /* pps */
+ nal_pps_data = nal_sps_data + frame_info.sLayerInfo[0].pNalLengthInByte[0];
+ nal_pps_length = frame_info.sLayerInfo[0].pNalLengthInByte[1] - 4;
+ /* idr */
+ bs_info = &frame_info.sLayerInfo[1];
+ idr_length = bs_info->pNalLengthInByte[0] - 4;
+
+ tmp_buf_length = nal_sps_length + 2 + nal_pps_length + 2 + idr_length + 2;
+ frame->output_buffer =
+ gst_video_encoder_allocate_output_buffer (encoder, tmp_buf_length);
+ gst_buffer_map (frame->output_buffer, &map, GST_MAP_WRITE);
+
+ GST_WRITE_UINT16_BE (map.data, nal_sps_length);
+ memcpy (map.data + 2, nal_sps_data, nal_sps_length);
+
+ GST_WRITE_UINT16_BE (map.data + nal_sps_length + 2, nal_pps_length);
+ memcpy (map.data + nal_sps_length + 2 + 2, nal_pps_data, nal_pps_length);
+
+ GST_WRITE_UINT16_BE (map.data + nal_sps_length + 2 + nal_pps_length + 2,
+ idr_length);
+ memcpy (map.data + nal_sps_length + 2 + nal_pps_length + 2 + 2,
+ bs_info->pBsBuf + 4, idr_length);
+
+ gst_buffer_unmap (frame->output_buffer, &map);
+
+ GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
+ } else {
+ GstMapInfo map;
+
+ tmp_buf_length = nal_size + 2;
+ frame->output_buffer =
+ gst_video_encoder_allocate_output_buffer (encoder, tmp_buf_length);
+ gst_buffer_map (frame->output_buffer, &map, GST_MAP_WRITE);
+
+ GST_WRITE_UINT16_BE (map.data, nal_size);
+ memcpy (map.data + 2, bs_info->pBsBuf + 4, nal_size);
+
+ gst_buffer_unmap (frame->output_buffer, &map);
+
+ GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT (frame);
+ }
+
+ GST_LOG_OBJECT (openh264enc, "openh264 picture %scoded OK!",
+ (ret != cmResultSuccess) ? "NOT " : "");
+
+ return gst_video_encoder_finish_frame (encoder, frame);
}
-static GstFlowReturn gst_openh264enc_finish (GstVideoEncoder *encoder)
+static GstFlowReturn
+gst_openh264enc_finish (GstVideoEncoder * encoder)
{
- GstOpenh264Enc *openh264enc = GST_OPENH264ENC(encoder);
+ GstOpenh264Enc *openh264enc = GST_OPENH264ENC (encoder);
- if (openh264enc->priv->frame_count == 0)
- return GST_FLOW_OK;
+ if (openh264enc->priv->frame_count == 0)
+ return GST_FLOW_OK;
- /* Drain encoder */
- while ((gst_openh264enc_handle_frame (encoder, NULL)) == GST_FLOW_OK);
+ /* Drain encoder */
+ while ((gst_openh264enc_handle_frame (encoder, NULL)) == GST_FLOW_OK);
- return GST_FLOW_OK;
+ return GST_FLOW_OK;
}
diff --git a/ext/openh264/gstopenh264plugin.c b/ext/openh264/gstopenh264plugin.c
index fcd7e6207..c15a9a822 100644
--- a/ext/openh264/gstopenh264plugin.c
+++ b/ext/openh264/gstopenh264plugin.c
@@ -36,21 +36,19 @@
#include "gstopenh264enc.h"
static gboolean
-plugin_init(GstPlugin *plugin)
+plugin_init (GstPlugin * plugin)
{
- gst_element_register(plugin, "openh264dec", GST_RANK_NONE, GST_TYPE_OPENH264DEC);
- gst_element_register(plugin, "openh264enc", GST_RANK_NONE, GST_TYPE_OPENH264ENC);
+ gst_element_register (plugin, "openh264dec", GST_RANK_NONE,
+ GST_TYPE_OPENH264DEC);
+ gst_element_register (plugin, "openh264enc", GST_RANK_NONE,
+ GST_TYPE_OPENH264ENC);
- return TRUE;
+ return TRUE;
}
-GST_PLUGIN_DEFINE(
- GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- openh264,
- "OpenH264 encoder/decoder plugin",
- plugin_init,
- VERSION,
- "BSD",
- "OpenWebRTC GStreamer plugins",
- "http://www.ericsson.com")
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ openh264,
+ "OpenH264 encoder/decoder plugin",
+ plugin_init,
+ VERSION, "BSD", "OpenWebRTC GStreamer plugins", "http://www.ericsson.com")