Factor out a base encoder class from ducatih264enc
authorAlessandro Decina <alessandro.decina@collabora.co.uk>
Thu, 20 Oct 2011 13:59:56 +0000 (15:59 +0200)
committerAlessandro Decina <alessandro.decina@collabora.co.uk>
Fri, 21 Oct 2011 08:38:03 +0000 (10:38 +0200)
src/Makefile.am
src/gstducatih264enc.c
src/gstducatih264enc.h
src/gstducatividenc.c [new file with mode: 0644]
src/gstducatividenc.h [new file with mode: 0644]

index ba3975943432055bf950a677b99caabb8e54e677..bccf8e1cdd4e3b8851301fa6ccf5cf541665ac22 100644 (file)
@@ -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)
 
index 7fbdccb4ac2d70997eb3d4cc20552b2cffcc15cb..1b2e32efdb19b5b52ddc85e8928230f7553a07c6 100644 (file)
 
 #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));
 }
index 84d445f35fd80c38f7acc6688f132848576daec3..b747ea8c7b1492aaef037e4bdddfc47dab20d800 100644 (file)
 #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())
   (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 (file)
index 0000000..294cee7
--- /dev/null
@@ -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 (file)
index 0000000..90f81af
--- /dev/null
@@ -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