diff options
author | Alessandro Decina <alessandro.decina@collabora.co.uk> | 2011-10-20 15:59:56 +0200 |
---|---|---|
committer | Alessandro Decina <alessandro.decina@collabora.co.uk> | 2011-10-21 10:38:03 +0200 |
commit | 05e439256130a78384add9c60304f721d120d00c (patch) | |
tree | ce09ddbf286211ad18a8e510ffd242196de62f19 | |
parent | 031257bc8acd79f37e691d8f9aef9a8be933d0eb (diff) |
Factor out a base encoder class from ducatih264enc
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/gstducatih264enc.c | 463 | ||||
-rw-r--r-- | src/gstducatih264enc.h | 34 | ||||
-rw-r--r-- | src/gstducatividenc.c | 603 | ||||
-rw-r--r-- | src/gstducatividenc.h | 85 |
5 files changed, 723 insertions, 465 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index ba39759..bccf8e1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,6 +10,8 @@ noinst_HEADERS = \ gstducatimpeg4dec.h \ gstducatih264dec.h \ gstducatividdec.h \ + gstducatih264enc.h \ + gstducatividenc.h \ gstducatibufferpool.h \ gstducati.h @@ -25,6 +27,7 @@ libgstducati_la_SOURCES = \ gstducatividdec.c \ gstducatibufferpool.c \ gstducatih264enc.c \ + gstducatividenc.c \ gstducati.c \ $(noinst_HEADERS) diff --git a/src/gstducatih264enc.c b/src/gstducatih264enc.c index 7fbdccb..1b2e32e 100644 --- a/src/gstducatih264enc.c +++ b/src/gstducatih264enc.c @@ -35,12 +35,9 @@ #define DEFAULT_PROFILE GST_DUCATI_H264ENC_PROFILE_HIGH #define DEFAULT_LEVEL GST_DUCATI_H264ENC_LEVEL_40 -#define DEFAULT_BITRATE 2048 -#define DEFAULT_RATE_PRESET GST_DUCATI_H264ENC_RATE_PRESET_LOW_DELAY #define GST_TYPE_DUCATI_H264ENC_PROFILE (gst_ducati_h264enc_profile_get_type ()) #define GST_TYPE_DUCATI_H264ENC_LEVEL (gst_ducati_h264enc_level_get_type ()) -#define GST_TYPE_DUCATI_H264ENC_RATE_PRESET (gst_ducati_h264enc_rate_preset_get_type ()) enum @@ -53,8 +50,6 @@ enum PROP_0, PROP_PROFILE, PROP_LEVEL, - PROP_BITRATE, - PROP_RATE_PRESET }; static void gst_ducati_h264enc_set_property (GObject * object, guint prop_id, @@ -62,16 +57,11 @@ static void gst_ducati_h264enc_set_property (GObject * object, guint prop_id, static void gst_ducati_h264enc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static gboolean gst_ducati_h264enc_set_format (GstBaseVideoEncoder * - base_video_encoder, GstVideoState * state); -static gboolean gst_ducati_h264enc_start (GstBaseVideoEncoder * - base_video_encoder); -static gboolean gst_ducati_h264enc_stop (GstBaseVideoEncoder * - base_video_encoder); -static GstFlowReturn gst_ducati_h264enc_finish (GstBaseVideoEncoder * - base_video_encoder); -static GstFlowReturn gst_ducati_h264enc_handle_frame (GstBaseVideoEncoder * - base_video_encoder, GstVideoFrame * frame); +static gboolean gst_ducati_h264enc_allocate_params (GstDucatiVidEnc * + self, gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz, + gint outargs_sz); +static gboolean gst_ducati_h264enc_configure (GstDucatiVidEnc * self); + static GstStaticPadTemplate gst_ducati_h264enc_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", @@ -87,8 +77,8 @@ GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_CAPS ("video/x-h264") ); -GST_BOILERPLATE (GstDucatiH264Enc, gst_ducati_h264enc, GstBaseVideoEncoder, - GST_TYPE_BASE_VIDEO_ENCODER); +GST_BOILERPLATE (GstDucatiH264Enc, gst_ducati_h264enc, GstDucatiVidEnc, + GST_TYPE_DUCATIVIDENC); /* the values for the following enums are taken from the codec */ @@ -123,23 +113,6 @@ enum GST_DUCATI_H264ENC_LEVEL_51 = 51 /**< Level 5.1 */ }; -enum -{ - GST_DUCATI_H264ENC_RATE_PRESET_LOW_DELAY = 1, /**< CBR rate control for video conferencing. */ - GST_DUCATI_H264ENC_RATE_PRESET_STORAGE = 2, /**< VBR rate control for local storage (DVD) - * recording. - */ - GST_DUCATI_H264ENC_RATE_PRESET_TWOPASS = 3, /**< Two pass rate control for non real time - * applications. - */ - GST_DUCATI_H264ENC_RATE_PRESET_NONE = 4, /**< No configurable video rate control - * mechanism. - */ - GST_DUCATI_H264ENC_RATE_PRESET_USER_DEFINED = 5,/**< User defined configuration using extended - * parameters. - */ -}; - static GType gst_ducati_h264enc_profile_get_type (void) { @@ -194,25 +167,6 @@ gst_ducati_h264enc_level_get_type (void) return type; } -static GType -gst_ducati_h264enc_rate_preset_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GEnumValue vals[] = { - {GST_DUCATI_H264ENC_RATE_PRESET_LOW_DELAY, "Low Delay", "low-delay"}, - {GST_DUCATI_H264ENC_RATE_PRESET_STORAGE, "Storage", "storage"}, - {GST_DUCATI_H264ENC_RATE_PRESET_TWOPASS, "Two-Pass", "two-pass"}, - {0, NULL, NULL}, - }; - - type = g_enum_register_static ("GstDucatiH264EncRatePreset", vals); - } - - return type; -} - static void gst_ducati_h264enc_base_init (gpointer g_class) { @@ -228,27 +182,24 @@ gst_ducati_h264enc_base_init (gpointer g_class) "Codec/Encoder/Video", "Encode raw video into H264 stream", "Alessandro Decina <alessandro.decina@collabora.com>"); + + GST_DUCATIVIDENC_CLASS (element_class)->codec_name = "ivahd_h264enc"; } static void gst_ducati_h264enc_class_init (GstDucatiH264EncClass * klass) { GObjectClass *gobject_class; - GstBaseVideoEncoderClass *basevideocoder_class; + GstDucatiVidEncClass *videnc_class; gobject_class = G_OBJECT_CLASS (klass); - basevideocoder_class = GST_BASE_VIDEO_ENCODER_CLASS (klass); + videnc_class = GST_DUCATIVIDENC_CLASS (klass); gobject_class->set_property = gst_ducati_h264enc_set_property; gobject_class->get_property = gst_ducati_h264enc_get_property; - basevideocoder_class->set_format = - GST_DEBUG_FUNCPTR (gst_ducati_h264enc_set_format); - basevideocoder_class->start = GST_DEBUG_FUNCPTR (gst_ducati_h264enc_start); - basevideocoder_class->stop = GST_DEBUG_FUNCPTR (gst_ducati_h264enc_stop); - basevideocoder_class->finish = GST_DEBUG_FUNCPTR (gst_ducati_h264enc_finish); - basevideocoder_class->handle_frame = - GST_DEBUG_FUNCPTR (gst_ducati_h264enc_handle_frame); + videnc_class->allocate_params = gst_ducati_h264enc_allocate_params; + videnc_class->configure = gst_ducati_h264enc_configure; g_object_class_install_property (gobject_class, PROP_PROFILE, g_param_spec_enum ("profile", "H.264 Profile", "H.264 Profile", @@ -257,16 +208,6 @@ gst_ducati_h264enc_class_init (GstDucatiH264EncClass * klass) g_object_class_install_property (gobject_class, PROP_LEVEL, g_param_spec_enum ("level", "H.264 Level", "H.264 Level", GST_TYPE_DUCATI_H264ENC_LEVEL, DEFAULT_LEVEL, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_BITRATE, - g_param_spec_int ("bitrate", "Bitrate", "Bitrate in kbit/sec", -1, - 100 * 1024, DEFAULT_BITRATE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_RATE_PRESET, - g_param_spec_enum ("rate-preset", "H.264 Rate Control", - "H.264 Rate Control", - GST_TYPE_DUCATI_H264ENC_RATE_PRESET, DEFAULT_RATE_PRESET, - G_PARAM_READWRITE)); } static void @@ -274,33 +215,8 @@ gst_ducati_h264enc_init (GstDucatiH264Enc * self, GstDucatiH264EncClass * klass) { GST_DEBUG ("gst_ducati_h264enc_init"); - self->engine = NULL; - self->codec = NULL; - self->params = NULL; - self->status = NULL; - self->inBufs = NULL; - self->outBufs = NULL; - self->inArgs = NULL; - self->outArgs = NULL; - self->configure = FALSE; - self->input_pool = NULL; - self->output_pool = NULL; - self->profile = DEFAULT_PROFILE; self->level = DEFAULT_LEVEL; - self->bitrate = DEFAULT_BITRATE * 1000; - self->rate_preset = DEFAULT_RATE_PRESET; -} - -static gboolean -gst_ducati_h264enc_set_format (GstBaseVideoEncoder * base_video_encoder, - GstVideoState * state) -{ - GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder); - - self->configure = TRUE; - - return TRUE; } static void @@ -319,12 +235,6 @@ gst_ducati_h264enc_set_property (GObject * object, guint prop_id, case PROP_LEVEL: self->level = g_value_get_enum (value); break; - case PROP_BITRATE: - self->bitrate = g_value_get_int (value) * 1000; - break; - case PROP_RATE_PRESET: - self->rate_preset = g_value_get_enum (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -346,353 +256,34 @@ gst_ducati_h264enc_get_property (GObject * object, guint prop_id, case PROP_LEVEL: g_value_set_enum (value, self->level); break; - case PROP_BITRATE: - g_value_set_int (value, self->bitrate / 1000); - break; - case PROP_RATE_PRESET: - g_value_set_enum (value, self->rate_preset); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static gboolean -gst_ducati_h264enc_configure (GstDucatiH264Enc * self) +gst_ducati_h264enc_configure (GstDucatiVidEnc * videnc) { - int err, i, max_out_size = 0; - VIDENC2_DynamicParams *dynParams; - VIDENC2_Params *baseParams; + GstDucatiH264Enc *self = GST_DUCATIH264ENC (videnc); IH264ENC_Params *params; - const GstVideoState *state; - - state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (self)); - - params = self->params; - baseParams = (VIDENC2_Params *) self->params; - baseParams->encodingPreset = 0x03; /* ??? */ - baseParams->rateControlPreset = self->rate_preset; - baseParams->maxHeight = state->height; - baseParams->maxWidth = state->width; - baseParams->dataEndianness = XDM_BYTE; - baseParams->maxInterFrameInterval = 1; - baseParams->maxBitRate = self->bitrate; - baseParams->minBitRate = 0; - baseParams->inputChromaFormat = XDM_YUV_420SP; - baseParams->inputContentType = IVIDEO_PROGRESSIVE; - baseParams->operatingMode = IVIDEO_ENCODE_ONLY; - baseParams->profile = self->profile; - baseParams->level = self->level; - baseParams->inputDataMode = IVIDEO_ENTIREFRAME; - baseParams->outputDataMode = IVIDEO_ENTIREFRAME; - baseParams->numInputDataUnits = 1; - baseParams->numOutputDataUnits = 1; - for (i = 0; i < IVIDEO_MAX_NUM_METADATA_PLANES; i++) { - baseParams->metadataType[i] = IVIDEO_METADATAPLANE_NONE; - } + videnc->params->profile = self->profile; + videnc->params->level = self->level; + + params = (IH264ENC_Params *) videnc->params; /* this is the only non-base field strictly required */ params->maxIntraFrameInterval = 0x7fffffff; - if (self->codec == NULL) { - self->codec = VIDENC2_create (self->engine, - (String) "ivahd_h264enc", baseParams); - if (self->codec == NULL) { - GST_ERROR_OBJECT (self, "couldn't create codec"); - return FALSE; - } - } - - dynParams = self->dynParams; - dynParams = (VIDENC2_DynamicParams *) self->dynParams; - dynParams->size = sizeof (IVIDENC2_DynamicParams); - - dynParams->refFrameRate = - gst_util_uint64_scale (1000, state->fps_n, state->fps_d); - dynParams->targetFrameRate = dynParams->refFrameRate; - dynParams->inputWidth = state->width; - dynParams->inputHeight = state->height; - dynParams->targetBitRate = self->bitrate; - dynParams->intraFrameInterval = 15; - dynParams->captureWidth = dynParams->inputWidth; - dynParams->forceFrame = IVIDEO_NA_FRAME; - dynParams->interFrameInterval = 1; - dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL; - dynParams->sampleAspectRatioHeight = 1; - dynParams->sampleAspectRatioWidth = 1; - dynParams->generateHeader = XDM_ENCODE_AU; - dynParams->ignoreOutbufSizeFlag = 1; - dynParams->lateAcquireArg = -1; - - err = VIDENC2_control (self->codec, - XDM_SETPARAMS, dynParams, self->status); - if (err) { - GST_ERROR_OBJECT (self, "XDM_SETPARAMS err=%d, extendedError=%08x", - err, self->status->extendedError); - - return FALSE; - } - - err = VIDENC2_control (self->codec, - XDM_GETBUFINFO, dynParams, self->status); - if (err) { - GST_ERROR_OBJECT (self, "XDM_GETBUFINFO err=%d, extendedError=%08x", - err, self->status->extendedError); - - return FALSE; - } - - self->inBufs->chromaFormat = XDM_YUV_420SP; - self->inBufs->numPlanes = 2; - - self->outBufs->numBufs = self->status->bufInfo.minNumOutBufs; - for (i = 0; i < self->outBufs->numBufs; i++) { - int size = self->status->bufInfo.minOutBufSize[i].bytes; - if (size > max_out_size) - max_out_size = size; - } - - g_assert (self->input_pool == NULL); - self->input_pool = - gst_ducati_bufferpool_new (GST_ELEMENT (self), NULL, - state->bytes_per_picture); - - g_assert (self->output_pool == NULL); - self->output_pool = - gst_ducati_bufferpool_new (GST_ELEMENT (self), NULL, max_out_size); - - GST_INFO_OBJECT (self, "configured"); - - self->configure = FALSE; - - return TRUE; -} - -static gboolean -gst_ducati_h264enc_alloc_dce (GstDucatiH264Enc * self) -{ - self->engine = Engine_open ((String) "ivahd_vidsvr", NULL, NULL); - if (self->engine == NULL) { - GST_ERROR_OBJECT (self, "couldn't open engine"); - return FALSE; - } - - self->params = dce_alloc (sizeof (IH264ENC_Params)); - memset (self->params, 0, sizeof (IH264ENC_Params)); - self->params->videnc2Params.size = sizeof (IH264ENC_Params); - - self->codec = NULL; - - self->dynParams = dce_alloc (sizeof (IVIDENC2_DynamicParams)); - memset (self->dynParams, 0, sizeof (IVIDENC2_DynamicParams)); - self->dynParams->size = sizeof (IVIDENC2_DynamicParams); - - self->status = dce_alloc (sizeof (IVIDENC2_Status)); - memset (self->status, 0, sizeof (IVIDENC2_Status)); - self->status->size = sizeof (IVIDENC2_Status); - - self->inBufs = dce_alloc (sizeof (IVIDEO2_BufDesc)); - memset (self->inBufs, 0, sizeof (IVIDEO2_BufDesc)); - - self->outBufs = dce_alloc (sizeof (XDM2_BufDesc)); - memset (self->outBufs, 0, sizeof (XDM2_BufDesc)); - - self->inArgs = dce_alloc (sizeof (IVIDENC2_InArgs)); - memset (self->inArgs, 0, sizeof (IVIDENC2_InArgs)); - self->inArgs->size = sizeof (IVIDENC2_InArgs); - - self->outArgs = dce_alloc (sizeof (IVIDENC2_OutArgs)); - memset (self->outArgs, 0, sizeof (IVIDENC2_OutArgs)); - self->outArgs->size = sizeof (IVIDENC2_OutArgs); - - GST_INFO_OBJECT (self, "started"); - - return TRUE; -} - -static gboolean -gst_ducati_h264enc_free_dce (GstDucatiH264Enc * self) -{ - if (self->params) { - dce_free (self->params); - self->params = NULL; - } - - if (self->dynParams) { - dce_free (self->dynParams); - self->dynParams = NULL; - } - - if (self->inArgs) { - dce_free (self->inArgs); - self->inArgs = NULL; - } - - if (self->outArgs) { - dce_free (self->outArgs); - self->outArgs = NULL; - } - - if (self->status) { - dce_free (self->status); - self->status = NULL; - } - - if (self->inBufs) { - dce_free (self->inBufs); - self->inBufs = NULL; - } - - if (self->outBufs) { - dce_free (self->outBufs); - self->inBufs = NULL; - } - - if (self->codec) { - VIDENC2_delete (self->codec); - self->codec = NULL; - } - - if (self->engine) { - Engine_close (self->engine); - self->engine = NULL; - } - - return TRUE; -} - -static gboolean -gst_ducati_h264enc_start (GstBaseVideoEncoder * base_video_encoder) -{ - GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder); - - if (!gst_ducati_h264enc_alloc_dce (self)) - goto fail; - - return TRUE; - -fail: - gst_ducati_h264enc_free_dce (self); - return FALSE; + return GST_DUCATIVIDENC_CLASS (parent_class)->configure (videnc); } static gboolean -gst_ducati_h264enc_stop (GstBaseVideoEncoder * base_video_encoder) -{ - GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder); - - gst_ducati_h264enc_free_dce (self); - - if (self->input_pool) { - gst_ducati_bufferpool_destroy (self->input_pool); - self->input_pool = NULL; - } - - if (self->output_pool) { - gst_ducati_bufferpool_destroy (self->output_pool); - self->output_pool = NULL; - } - - return TRUE; -} - -static GstFlowReturn -gst_ducati_h264enc_finish (GstBaseVideoEncoder * base_video_encoder) +gst_ducati_h264enc_allocate_params (GstDucatiVidEnc * + videnc, gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz, + gint outargs_sz) { - GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder); - - GST_DEBUG_OBJECT (self, "finish"); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_ducati_h264enc_handle_frame (GstBaseVideoEncoder * base_video_encoder, - GstVideoFrame * frame) -{ - GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder); - GstBuffer *inbuf, *outbuf; - guint8 *y_vaddr, *uv_vaddr; - SSPtr y_paddr, uv_paddr, outbuf_paddr; - XDAS_Int32 err; - const GstVideoState *state; - int i; - - state = gst_base_video_encoder_get_state (base_video_encoder); - - if (G_UNLIKELY (self->configure)) { - if (!gst_ducati_h264enc_configure (self)) { - GST_DEBUG_OBJECT (self, "configure failed"); - GST_ELEMENT_ERROR (self, STREAM, ENCODE, (NULL), (NULL)); - - return GST_FLOW_ERROR; - } - } - - inbuf = GST_BUFFER (gst_ducati_bufferpool_get (self->input_pool, NULL)); - memcpy (GST_BUFFER_DATA (inbuf), GST_BUFFER_DATA (frame->sink_buffer), - GST_BUFFER_SIZE (frame->sink_buffer)); - outbuf = GST_BUFFER (gst_ducati_bufferpool_get (self->output_pool, NULL)); - - y_vaddr = GST_BUFFER_DATA (inbuf); - uv_vaddr = y_vaddr + gst_video_format_get_component_offset (state->format, - 1, state->width, state->height); - - y_paddr = TilerMem_VirtToPhys (y_vaddr); - uv_paddr = TilerMem_VirtToPhys (uv_vaddr); - - outbuf_paddr = TilerMem_VirtToPhys (GST_BUFFER_DATA (outbuf)); - - self->inBufs->planeDesc[0].buf = (XDAS_Int8 *) y_paddr; - self->inBufs->planeDesc[0].memType = XDM_MEMTYPE_TILEDPAGE; - self->inBufs->planeDesc[0].bufSize.tileMem.width = state->width; - self->inBufs->planeDesc[0].bufSize.tileMem.height = state->height; - self->inBufs->planeDesc[1].buf = (XDAS_Int8 *) uv_paddr; - self->inBufs->planeDesc[1].memType = XDM_MEMTYPE_TILEDPAGE; - self->inBufs->planeDesc[1].bufSize.tileMem.width = state->width; - self->inBufs->planeDesc[1].bufSize.tileMem.height = state->height / 2; - self->inBufs->imagePitch[0] = state->width; - self->inBufs->imagePitch[1] = state->width; - self->inBufs->imageRegion.bottomRight.x = state->width; - self->inBufs->activeFrameRegion.bottomRight.x = state->width; - self->inBufs->imageRegion.bottomRight.y = state->height; - self->inBufs->activeFrameRegion.bottomRight.y = state->height; - self->inBufs->topFieldFirstFlag = TRUE; - - self->outBufs->numBufs = 1; - self->outBufs->descs[0].buf = (XDAS_Int8 *) outbuf_paddr; - self->outBufs->descs[0].bufSize.bytes = GST_BUFFER_SIZE (outbuf); - - self->inArgs->inputID = GPOINTER_TO_INT (inbuf); - - err = VIDENC2_process (self->codec, self->inBufs, self->outBufs, - self->inArgs, self->outArgs); - if (err) { - GST_WARNING_OBJECT (self, "process failed: err=%d, extendedError=%08x", - err, self->status->extendedError); - - err = VIDENC2_control (self->codec, - XDM_GETSTATUS, (IVIDENC2_DynamicParams *) self->dynParams, - self->status); - - GST_WARNING_OBJECT (self, "XDM_GETSTATUS: err=%d, extendedError=%08x", - err, self->status->extendedError); - - return GST_FLOW_ERROR; - } - - frame->src_buffer = gst_buffer_new_and_alloc (self->outArgs->bytesGenerated); - memcpy (GST_BUFFER_DATA (frame->src_buffer), - GST_BUFFER_DATA (outbuf), self->outArgs->bytesGenerated); - - gst_buffer_unref (outbuf); - - for (i = 0; self->outArgs->freeBufID[i]; i++) { - GstBuffer *buf = (GstBuffer *) self->outArgs->freeBufID[i]; - - GST_LOG_OBJECT (self, "free buffer: %p", buf); - gst_buffer_unref (buf); - } - - return gst_base_video_encoder_finish_frame (base_video_encoder, frame); + return GST_DUCATIVIDENC_CLASS (parent_class)->allocate_params (videnc, + sizeof (IH264ENC_Params), sizeof (IVIDENC2_DynamicParams), + sizeof (IVIDENC2_Status), sizeof (IVIDENC2_InArgs), + sizeof (IVIDENC2_OutArgs)); } diff --git a/src/gstducatih264enc.h b/src/gstducatih264enc.h index 84d445f..b747ea8 100644 --- a/src/gstducatih264enc.h +++ b/src/gstducatih264enc.h @@ -20,15 +20,8 @@ #ifndef __GST_DUCATIH264ENC_H__ #define __GST_DUCATIH264ENC_H__ -#include <gst/gst.h> -#include <gst/video/video.h> -#include <gst/video/gstbasevideoencoder.h> -#include <gst/video/gstbasevideoutils.h> - -#include <ti/sdo/ce/video2/videnc2.h> #include <ti/sdo/codecs/h264enc/ih264enc.h> - -#include "gstducatibufferpool.h" +#include "gstducatividenc.h" #define GST_TYPE_DUCATIH264ENC \ (gst_ducati_h264enc_get_type()) @@ -40,40 +33,23 @@ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DUCATIH264ENC)) #define GST_IS_DUCATIH264ENC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DUCATIH264ENC)) +#define GST_DUCATIH264ENC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_DUCATIH264ENC, GstDucatiH264EncClass)) typedef struct _GstDucatiH264Enc GstDucatiH264Enc; typedef struct _GstDucatiH264EncClass GstDucatiH264EncClass; struct _GstDucatiH264Enc { - GstBaseVideoEncoder base_encoder; - - GstPad *sinkpad; - GstPad *srcpad; - - Engine_Handle engine; - VIDENC2_Handle codec; - IH264ENC_Params *params; - IVIDENC2_DynamicParams *dynParams; - IVIDENC2_Status *status; - IVIDEO2_BufDesc *inBufs; - XDM2_BufDesc *outBufs; - IVIDENC2_InArgs *inArgs; - IVIDENC2_OutArgs *outArgs; - - GstDucatiBufferPool *input_pool; - GstDucatiBufferPool *output_pool; - gboolean configure; + GstDucatiVidEnc parent; guint profile; guint level; - gint bitrate; - guint rate_preset; }; struct _GstDucatiH264EncClass { - GstBaseVideoEncoderClass parent_class; + GstDucatiVidEncClass parent_class; }; GType gst_ducati_h264enc_get_type (void); diff --git a/src/gstducatividenc.c b/src/gstducatividenc.c new file mode 100644 index 0000000..294cee7 --- /dev/null +++ b/src/gstducatividenc.c @@ -0,0 +1,603 @@ +/* GStreamer + * Copyright (c) 2011, Texas Instruments Incorporated + * Copyright (c) 2011, Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alessandro Decina <alessandro.decina@collabora.com> + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstducati.h" +#include "gstducatividenc.h" +#include <ti/sdo/codecs/mpeg4enc/impeg4enc.h> + +#include <string.h> + +#include <math.h> + +#define GST_CAT_DEFAULT gst_ducati_debug + +#define DEFAULT_BITRATE 2048 +#define DEFAULT_RATE_PRESET GST_DUCATI_VIDENC_RATE_PRESET_STORAGE + +#define GST_TYPE_DUCATI_VIDENC_RATE_PRESET (gst_ducati_videnc_rate_preset_get_type ()) + + +enum +{ + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_BITRATE, + PROP_RATE_PRESET +}; + +static void gst_ducati_videnc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_ducati_videnc_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +static gboolean gst_ducati_videnc_set_format (GstBaseVideoEncoder * + base_video_encoder, GstVideoState * state); +static gboolean gst_ducati_videnc_start (GstBaseVideoEncoder * + base_video_encoder); +static gboolean gst_ducati_videnc_stop (GstBaseVideoEncoder * + base_video_encoder); +static GstFlowReturn gst_ducati_videnc_finish (GstBaseVideoEncoder * + base_video_encoder); +static GstFlowReturn gst_ducati_videnc_handle_frame (GstBaseVideoEncoder * + base_video_encoder, GstVideoFrame * frame); +static gboolean gst_ducati_videnc_allocate_params_default (GstDucatiVidEnc * + self, gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz, + gint outargs_sz); +static gboolean gst_ducati_videnc_configure_default (GstDucatiVidEnc * self); + + +GST_BOILERPLATE (GstDucatiVidEnc, gst_ducati_videnc, GstBaseVideoEncoder, + GST_TYPE_BASE_VIDEO_ENCODER); + + +/* the values for the following enums are taken from the codec */ + +enum +{ + GST_DUCATI_VIDENC_RATE_PRESET_LOW_DELAY = 1, /**< CBR rate control for video conferencing. */ + GST_DUCATI_VIDENC_RATE_PRESET_STORAGE = 2, /**< VBR rate control for local storage (DVD) + * recording. + */ + GST_DUCATI_VIDENC_RATE_PRESET_TWOPASS = 3, /**< Two pass rate control for non real time + * applications. + */ + GST_DUCATI_VIDENC_RATE_PRESET_NONE = 4, /**< No configurable video rate control + * mechanism. + */ + GST_DUCATI_VIDENC_RATE_PRESET_USER_DEFINED = 5,/**< User defined configuration using extended + * parameters. + */ +}; + +static GType +gst_ducati_videnc_rate_preset_get_type (void) +{ + static GType type = 0; + + if (!type) { + static const GEnumValue vals[] = { + {GST_DUCATI_VIDENC_RATE_PRESET_LOW_DELAY, "Low Delay", "low-delay"}, + {GST_DUCATI_VIDENC_RATE_PRESET_STORAGE, "Storage", "storage"}, + {GST_DUCATI_VIDENC_RATE_PRESET_TWOPASS, "Two-Pass", "two-pass"}, + {0, NULL, NULL}, + }; + + type = g_enum_register_static ("GstDucatiVidEncRatePreset", vals); + } + + return type; +} + +static void +gst_ducati_videnc_base_init (gpointer g_class) +{ +} + +static void +gst_ducati_videnc_class_init (GstDucatiVidEncClass * klass) +{ + GObjectClass *gobject_class; + GstBaseVideoEncoderClass *basevideocoder_class; + + gobject_class = G_OBJECT_CLASS (klass); + basevideocoder_class = GST_BASE_VIDEO_ENCODER_CLASS (klass); + + gobject_class->set_property = gst_ducati_videnc_set_property; + gobject_class->get_property = gst_ducati_videnc_get_property; + + basevideocoder_class->set_format = + GST_DEBUG_FUNCPTR (gst_ducati_videnc_set_format); + basevideocoder_class->start = GST_DEBUG_FUNCPTR (gst_ducati_videnc_start); + basevideocoder_class->stop = GST_DEBUG_FUNCPTR (gst_ducati_videnc_stop); + basevideocoder_class->finish = GST_DEBUG_FUNCPTR (gst_ducati_videnc_finish); + basevideocoder_class->handle_frame = + GST_DEBUG_FUNCPTR (gst_ducati_videnc_handle_frame); + + klass->allocate_params = gst_ducati_videnc_allocate_params_default; + klass->configure = gst_ducati_videnc_configure_default; + + g_object_class_install_property (gobject_class, PROP_BITRATE, + g_param_spec_int ("bitrate", "Bitrate", "Bitrate in kbit/sec", -1, + 100 * 1024, DEFAULT_BITRATE, G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_RATE_PRESET, + g_param_spec_enum ("rate-preset", "H.264 Rate Control", + "H.264 Rate Control", + GST_TYPE_DUCATI_VIDENC_RATE_PRESET, DEFAULT_RATE_PRESET, + G_PARAM_READWRITE)); +} + +static void +gst_ducati_videnc_init (GstDucatiVidEnc * self, GstDucatiVidEncClass * klass) +{ + GST_DEBUG ("gst_ducati_videnc_init"); + + self->engine = NULL; + self->codec = NULL; + self->params = NULL; + self->status = NULL; + self->inBufs = NULL; + self->outBufs = NULL; + self->inArgs = NULL; + self->outArgs = NULL; + self->configure = FALSE; + self->input_pool = NULL; + self->output_pool = NULL; + + self->bitrate = DEFAULT_BITRATE * 1000; + self->rate_preset = DEFAULT_RATE_PRESET; +} + +static gboolean +gst_ducati_videnc_set_format (GstBaseVideoEncoder * base_video_encoder, + GstVideoState * state) +{ + GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder); + + self->configure = TRUE; + + return TRUE; +} + +static void +gst_ducati_videnc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstDucatiVidEnc *self = GST_DUCATIVIDENC (object); + + g_return_if_fail (GST_IS_DUCATIVIDENC (object)); + self = GST_DUCATIVIDENC (object); + + switch (prop_id) { + case PROP_BITRATE: + self->bitrate = g_value_get_int (value) * 1000; + break; + case PROP_RATE_PRESET: + self->rate_preset = g_value_get_enum (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gst_ducati_videnc_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstDucatiVidEnc *self = GST_DUCATIVIDENC (object); + + g_return_if_fail (GST_IS_DUCATIVIDENC (object)); + self = GST_DUCATIVIDENC (object); + + switch (prop_id) { + case PROP_BITRATE: + g_value_set_int (value, self->bitrate / 1000); + break; + case PROP_RATE_PRESET: + g_value_set_enum (value, self->rate_preset); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static gboolean +gst_ducati_videnc_configure (GstDucatiVidEnc * self) +{ + int err; + int i; + int max_out_size; + const GstVideoState *state; + + state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (self)); + + if (!GST_DUCATIVIDENC_GET_CLASS (self)->configure (self)) + return FALSE; + + if (self->codec == NULL) { + const gchar *codec_name; + + codec_name = GST_DUCATIVIDENC_GET_CLASS (self)->codec_name; + self->codec = VIDENC2_create (self->engine, + (String) codec_name, self->params); + if (self->codec == NULL) { + GST_ERROR_OBJECT (self, "couldn't create codec"); + return FALSE; + } + } + + err = VIDENC2_control (self->codec, + XDM_SETPARAMS, self->dynParams, self->status); + if (err) { + GST_ERROR_OBJECT (self, "XDM_SETPARAMS err=%d, extendedError=%08x", + err, self->status->extendedError); + + return FALSE; + } + + err = VIDENC2_control (self->codec, + XDM_GETBUFINFO, self->dynParams, self->status); + if (err) { + GST_ERROR_OBJECT (self, "XDM_GETBUFINFO err=%d, extendedError=%08x", + err, self->status->extendedError); + + return FALSE; + } + + self->outBufs->numBufs = self->status->bufInfo.minNumOutBufs; + for (i = 0; i < self->outBufs->numBufs; i++) { + int size = self->status->bufInfo.minOutBufSize[i].bytes; + if (size > max_out_size) + max_out_size = size; + } + + g_assert (self->input_pool == NULL); + self->input_pool = + gst_ducati_bufferpool_new (GST_ELEMENT (self), NULL, + state->bytes_per_picture); + + g_assert (self->output_pool == NULL); + self->output_pool = + gst_ducati_bufferpool_new (GST_ELEMENT (self), NULL, max_out_size); + + GST_INFO_OBJECT (self, "configured"); + + self->configure = FALSE; + + return TRUE; +} + +static gboolean +gst_ducati_videnc_configure_default (GstDucatiVidEnc * self) +{ + VIDENC2_DynamicParams *dynParams; + const GstVideoState *state; + int i; + + state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (self)); + + self->params = (VIDENC2_Params *) self->params; + self->params->encodingPreset = 0x03; + self->params->rateControlPreset = self->rate_preset; + self->params->maxHeight = state->height; + self->params->maxWidth = state->width; + self->params->dataEndianness = XDM_BYTE; + self->params->maxInterFrameInterval = 1; + self->params->maxBitRate = -1; + self->params->minBitRate = 0; + self->params->inputChromaFormat = XDM_YUV_420SP; + self->params->inputContentType = IVIDEO_PROGRESSIVE; + self->params->operatingMode = IVIDEO_ENCODE_ONLY; + self->params->inputDataMode = IVIDEO_ENTIREFRAME; + self->params->outputDataMode = IVIDEO_ENTIREFRAME; + self->params->numInputDataUnits = 1; + self->params->numOutputDataUnits = 1; + for (i = 0; i < IVIDEO_MAX_NUM_METADATA_PLANES; i++) { + self->params->metadataType[i] = IVIDEO_METADATAPLANE_NONE; + } + + dynParams = self->dynParams; + dynParams = (VIDENC2_DynamicParams *) self->dynParams; + + dynParams->refFrameRate = + gst_util_uint64_scale (1000, state->fps_n, state->fps_d); + dynParams->targetFrameRate = dynParams->refFrameRate; + dynParams->inputWidth = state->width; + dynParams->inputHeight = state->height; + dynParams->targetBitRate = self->bitrate; + dynParams->intraFrameInterval = 15; + dynParams->captureWidth = dynParams->inputWidth; + dynParams->forceFrame = IVIDEO_NA_FRAME; + dynParams->interFrameInterval = 1; + dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL; + dynParams->sampleAspectRatioHeight = 1; + dynParams->sampleAspectRatioWidth = 1; + dynParams->generateHeader = XDM_ENCODE_AU; + dynParams->ignoreOutbufSizeFlag = 1; + dynParams->lateAcquireArg = -1; + + self->inBufs->chromaFormat = XDM_YUV_420SP; + self->inBufs->numPlanes = 2; + + return TRUE; +} + +static gboolean +gst_ducati_videnc_open_engine (GstDucatiVidEnc * self) +{ + self->engine = Engine_open ((String) "ivahd_vidsvr", NULL, NULL); + if (self->engine == NULL) { + GST_ERROR_OBJECT (self, "couldn't open engine"); + return FALSE; + } + + return TRUE; +} + +static gboolean +gst_ducati_videnc_allocate_params (GstDucatiVidEnc * self) +{ + return GST_DUCATIVIDENC_GET_CLASS (self)->allocate_params (self, + sizeof (IVIDENC2_Params), sizeof (IVIDENC2_DynamicParams), + sizeof (IVIDENC2_Status), sizeof (IVIDENC2_InArgs), + sizeof (IVIDENC2_OutArgs)); +} + +static gboolean +gst_ducati_videnc_allocate_params_default (GstDucatiVidEnc * self, gint params_sz, + gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz) +{ + self->params = dce_alloc (params_sz); + memset (self->params, 0, params_sz); + self->params->size = params_sz; + + self->dynParams = dce_alloc (dynparams_sz); + memset (self->dynParams, 0, dynparams_sz); + self->dynParams->size = dynparams_sz; + + self->status = dce_alloc (status_sz); + memset (self->status, 0, status_sz); + self->status->size = status_sz; + + self->inBufs = dce_alloc (sizeof (IVIDEO2_BufDesc)); + memset (self->inBufs, 0, sizeof (IVIDEO2_BufDesc)); + + self->outBufs = dce_alloc (sizeof (XDM2_BufDesc)); + memset (self->outBufs, 0, sizeof (XDM2_BufDesc)); + + self->inArgs = dce_alloc (inargs_sz); + memset (self->inArgs, 0, inargs_sz); + self->inArgs->size = inargs_sz; + + self->outArgs = dce_alloc (outargs_sz); + memset (self->outArgs, 0, outargs_sz); + self->outArgs->size = outargs_sz; + + GST_INFO_OBJECT (self, "started"); + + return TRUE; +} + +static gboolean +gst_ducati_videnc_free_params (GstDucatiVidEnc * self) +{ + if (self->params) { + dce_free (self->params); + self->params = NULL; + } + + if (self->dynParams) { + dce_free (self->dynParams); + self->dynParams = NULL; + } + + if (self->inArgs) { + dce_free (self->inArgs); + self->inArgs = NULL; + } + + if (self->outArgs) { + dce_free (self->outArgs); + self->outArgs = NULL; + } + + if (self->status) { + dce_free (self->status); + self->status = NULL; + } + + if (self->inBufs) { + dce_free (self->inBufs); + self->inBufs = NULL; + } + + if (self->outBufs) { + dce_free (self->outBufs); + self->inBufs = NULL; + } + + if (self->codec) { + VIDENC2_delete (self->codec); + self->codec = NULL; + } + + return TRUE; +} + +static void +gst_ducati_videnc_close_engine (GstDucatiVidEnc * self) +{ + if (self->engine) { + Engine_close (self->engine); + self->engine = NULL; + } +} + + +static gboolean +gst_ducati_videnc_start (GstBaseVideoEncoder * base_video_encoder) +{ + GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder); + + if (!gst_ducati_videnc_open_engine (self)) + goto fail; + + if (!gst_ducati_videnc_allocate_params (self)) + goto fail; + + return TRUE; + +fail: + gst_ducati_videnc_free_params (self); + gst_ducati_videnc_close_engine (self); + return FALSE; +} + +static gboolean +gst_ducati_videnc_stop (GstBaseVideoEncoder * base_video_encoder) +{ + GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder); + + gst_ducati_videnc_free_params (self); + gst_ducati_videnc_close_engine (self); + + if (self->input_pool) { + gst_ducati_bufferpool_destroy (self->input_pool); + self->input_pool = NULL; + } + + if (self->output_pool) { + gst_ducati_bufferpool_destroy (self->output_pool); + self->output_pool = NULL; + } + + return TRUE; +} + +static GstFlowReturn +gst_ducati_videnc_finish (GstBaseVideoEncoder * base_video_encoder) +{ + GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder); + + GST_DEBUG_OBJECT (self, "finish"); + + return GST_FLOW_OK; +} + +static GstFlowReturn +gst_ducati_videnc_handle_frame (GstBaseVideoEncoder * base_video_encoder, + GstVideoFrame * frame) +{ + GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder); + GstBuffer *inbuf, *outbuf; + guint8 *y_vaddr, *uv_vaddr; + SSPtr y_paddr, uv_paddr, outbuf_paddr; + XDAS_Int32 err; + const GstVideoState *state; + int i; + + state = gst_base_video_encoder_get_state (base_video_encoder); + + if (G_UNLIKELY (self->configure)) { + if (!gst_ducati_videnc_configure (self)) { + GST_DEBUG_OBJECT (self, "configure failed"); + GST_ELEMENT_ERROR (self, STREAM, ENCODE, (NULL), (NULL)); + + return GST_FLOW_ERROR; + } + } + + inbuf = GST_BUFFER (gst_ducati_bufferpool_get (self->input_pool, NULL)); + memcpy (GST_BUFFER_DATA (inbuf), GST_BUFFER_DATA (frame->sink_buffer), + GST_BUFFER_SIZE (frame->sink_buffer)); + outbuf = GST_BUFFER (gst_ducati_bufferpool_get (self->output_pool, NULL)); + + y_vaddr = GST_BUFFER_DATA (inbuf); + uv_vaddr = y_vaddr + gst_video_format_get_component_offset (state->format, + 1, state->width, state->height); + + y_paddr = TilerMem_VirtToPhys (y_vaddr); + uv_paddr = TilerMem_VirtToPhys (uv_vaddr); + + outbuf_paddr = TilerMem_VirtToPhys (GST_BUFFER_DATA (outbuf)); + + self->inBufs->planeDesc[0].buf = (XDAS_Int8 *) y_paddr; + self->inBufs->planeDesc[0].memType = XDM_MEMTYPE_TILEDPAGE; + self->inBufs->planeDesc[0].bufSize.tileMem.width = state->width; + self->inBufs->planeDesc[0].bufSize.tileMem.height = state->height; + self->inBufs->planeDesc[1].buf = (XDAS_Int8 *) uv_paddr; + self->inBufs->planeDesc[1].memType = XDM_MEMTYPE_TILEDPAGE; + self->inBufs->planeDesc[1].bufSize.tileMem.width = state->width; + self->inBufs->planeDesc[1].bufSize.tileMem.height = state->height / 2; + self->inBufs->imagePitch[0] = state->width; + self->inBufs->imagePitch[1] = state->width; + self->inBufs->imageRegion.bottomRight.x = state->width; + self->inBufs->activeFrameRegion.bottomRight.x = state->width; + self->inBufs->imageRegion.bottomRight.y = state->height; + self->inBufs->activeFrameRegion.bottomRight.y = state->height; + self->inBufs->topFieldFirstFlag = TRUE; + + self->outBufs->numBufs = 1; + self->outBufs->descs[0].buf = (XDAS_Int8 *) outbuf_paddr; + self->outBufs->descs[0].bufSize.bytes = GST_BUFFER_SIZE (outbuf); + + self->inArgs->inputID = GPOINTER_TO_INT (inbuf); + + err = VIDENC2_process (self->codec, self->inBufs, self->outBufs, + self->inArgs, self->outArgs); + if (err) { + GST_WARNING_OBJECT (self, "process failed: err=%d, extendedError=%08x", + err, self->status->extendedError); + + err = VIDENC2_control (self->codec, + XDM_GETSTATUS, (IVIDENC2_DynamicParams *) self->dynParams, + self->status); + + GST_WARNING_OBJECT (self, "XDM_GETSTATUS: err=%d, extendedError=%08x", + err, self->status->extendedError); + + return GST_FLOW_ERROR; + } + + frame->src_buffer = gst_buffer_new_and_alloc (self->outArgs->bytesGenerated); + memcpy (GST_BUFFER_DATA (frame->src_buffer), + GST_BUFFER_DATA (outbuf), self->outArgs->bytesGenerated); + + gst_buffer_unref (outbuf); + + for (i = 0; self->outArgs->freeBufID[i]; i++) { + GstBuffer *buf = (GstBuffer *) self->outArgs->freeBufID[i]; + + GST_LOG_OBJECT (self, "free buffer: %p", buf); + gst_buffer_unref (buf); + } + + return gst_base_video_encoder_finish_frame (base_video_encoder, frame); +} diff --git a/src/gstducatividenc.h b/src/gstducatividenc.h new file mode 100644 index 0000000..90f81af --- /dev/null +++ b/src/gstducatividenc.h @@ -0,0 +1,85 @@ +/* + * GStreamer + * Copyright (c) 2010, Texas Instruments Incorporated + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __GST_DUCATIVIDENC_H__ +#define __GST_DUCATIVIDENC_H__ + +#include <gst/gst.h> +#include <gst/video/video.h> +#include <gst/video/gstbasevideoencoder.h> +#include <gst/video/gstbasevideoutils.h> + +#include <ti/sdo/ce/video2/videnc2.h> + +#include "gstducatibufferpool.h" + +#define GST_TYPE_DUCATIVIDENC \ + (gst_ducati_videnc_get_type()) +#define GST_DUCATIVIDENC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DUCATIVIDENC,GstDucatiVidEnc)) +#define GST_DUCATIVIDENC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DUCATIVIDENC,GstDucatiVidEncClass)) +#define GST_IS_DUCATIVIDENC(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DUCATIVIDENC)) +#define GST_IS_DUCATIVIDENC_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DUCATIVIDENC)) +#define GST_DUCATIVIDENC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_DUCATIVIDENC, GstDucatiVidEncClass)) + +typedef struct _GstDucatiVidEnc GstDucatiVidEnc; +typedef struct _GstDucatiVidEncClass GstDucatiVidEncClass; + +struct _GstDucatiVidEnc +{ + GstBaseVideoEncoder base_encoder; + + GstPad *sinkpad; + GstPad *srcpad; + + Engine_Handle engine; + VIDENC2_Handle codec; + IVIDENC2_Params *params; + IVIDENC2_DynamicParams *dynParams; + IVIDENC2_Status *status; + IVIDEO2_BufDesc *inBufs; + XDM2_BufDesc *outBufs; + IVIDENC2_InArgs *inArgs; + IVIDENC2_OutArgs *outArgs; + + GstDucatiBufferPool *input_pool; + GstDucatiBufferPool *output_pool; + gboolean configure; + + gint bitrate; + guint rate_preset; +}; + +struct _GstDucatiVidEncClass +{ + GstBaseVideoEncoderClass parent_class; + + const gchar *codec_name; + gboolean (*allocate_params) (GstDucatiVidEnc * self, gint params_sz, + gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz); + gboolean (*configure) (GstDucatiVidEnc * self); +}; + +GType gst_ducati_videnc_get_type (void); + +#endif |