ducatividenc: add cropping support
authorAlessandro Decina <alessandro.decina@collabora.com>
Tue, 27 Mar 2012 17:19:08 +0000 (19:19 +0200)
committerAlessandro Decina <alessandro.decina@collabora.com>
Tue, 27 Mar 2012 17:20:08 +0000 (19:20 +0200)
src/gstducatih264enc.c
src/gstducatividenc.c
src/gstducatividenc.h

index 4d905feefb0cb001b6640144b216c80576206f2c..3af25e8cbe165f0ad83c0f693a30dba0667cf3b6 100644 (file)
@@ -277,11 +277,11 @@ gst_ducati_h264enc_configure (GstDucatiVidEnc * videnc)
 
   ret = GST_DUCATIVIDENC_CLASS (parent_class)->configure (videnc);
   if (ret) {
-    const GstVideoState *state = \
+    const GstVideoState *state =
         gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (videnc));
     GstCaps *caps = gst_caps_new_simple ("video/x-h264",
-        "width", G_TYPE_INT, state->width,
-        "height", G_TYPE_INT, state->height,
+        "width", G_TYPE_INT, videnc->rect.w,
+        "height", G_TYPE_INT, videnc->rect.h,
         "framerate", GST_TYPE_FRACTION, state->fps_n, state->fps_d,
         "pixel-aspect-ratio", GST_TYPE_FRACTION, state->par_n, state->par_d,
         "stream-format", G_TYPE_STRING, "byte-stream",
index 02f29cff18f29db33af70fe3e566b8bffaf4020e..48179ddd87fb92208e723c9cb08b412204cf1f1e 100644 (file)
@@ -71,6 +71,8 @@ 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);
+static gboolean gst_ducati_videnc_event (GstBaseVideoEncoder * enc,
+    GstEvent * event);
 
 
 GST_BOILERPLATE (GstDucatiVidEnc, gst_ducati_videnc, GstBaseVideoEncoder,
@@ -139,6 +141,7 @@ gst_ducati_videnc_class_init (GstDucatiVidEncClass * klass)
   basevideoencoder_class->finish = GST_DEBUG_FUNCPTR (gst_ducati_videnc_finish);
   basevideoencoder_class->handle_frame =
       GST_DEBUG_FUNCPTR (gst_ducati_videnc_handle_frame);
+  basevideoencoder_class->event = GST_DEBUG_FUNCPTR (gst_ducati_videnc_event);
 
   klass->allocate_params = gst_ducati_videnc_allocate_params_default;
   klass->configure = gst_ducati_videnc_configure_default;
@@ -229,14 +232,14 @@ gst_ducati_videnc_get_property (GObject * object, guint prop_id,
 
 static gboolean
 gst_ducati_videnc_configure (GstDucatiVidEnc * self)
-{  
+{
   int err;
   int i;
   int max_out_size = 0;
   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;
 
@@ -251,7 +254,7 @@ gst_ducati_videnc_configure (GstDucatiVidEnc * self)
       return FALSE;
     }
   }
-  
+
   err = VIDENC2_control (self->codec,
       XDM_SETPARAMS, self->dynParams, self->status);
   if (err) {
@@ -302,11 +305,17 @@ gst_ducati_videnc_configure_default (GstDucatiVidEnc * self)
 
   state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (self));
 
+  if (self->rect.w == 0)
+    self->rect.w = state->width;
+
+  if (self->rect.h == 0)
+    self->rect.h = state->height;
+
   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->maxHeight = self->rect.h;
+  self->params->maxWidth = self->rect.w;
   self->params->dataEndianness = XDM_BYTE;
   self->params->maxInterFrameInterval = 1;
   self->params->maxBitRate = -1;
@@ -328,11 +337,13 @@ gst_ducati_videnc_configure_default (GstDucatiVidEnc * self)
   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->inputWidth = self->rect.w;
+  dynParams->inputHeight = self->rect.h;
   dynParams->targetBitRate = self->bitrate;
   dynParams->intraFrameInterval = 15;
   dynParams->captureWidth = dynParams->inputWidth;
+  dynParams->captureWidth = dynParams->inputWidth = self->rect.w;
+
   dynParams->forceFrame = IVIDEO_NA_FRAME;
   dynParams->interFrameInterval = 1;
   dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL;
@@ -370,8 +381,9 @@ gst_ducati_videnc_allocate_params (GstDucatiVidEnc * self)
 }
 
 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)
+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);
@@ -466,6 +478,7 @@ gst_ducati_videnc_start (GstBaseVideoEncoder * base_video_encoder)
   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
 
   self->configure = TRUE;
+  memset (&self->rect, 0, sizeof (GstDucatiVideoRectangle));
 
   if (!gst_ducati_videnc_open_engine (self))
     goto fail;
@@ -499,6 +512,9 @@ gst_ducati_videnc_stop (GstBaseVideoEncoder * base_video_encoder)
     self->output_pool = NULL;
   }
 
+  /* reset cropping rect */
+  memset (&self->rect, 0, sizeof (GstDucatiVideoRectangle));
+
   return TRUE;
 }
 
@@ -573,12 +589,19 @@ have_inbuf:
   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;
+  /* setting imageRegion doesn't seem to be strictly needed if activeFrameRegion
+   * is set but we set it anyway...
+   */
+  self->inBufs->imageRegion.topLeft.x = self->rect.x;
+  self->inBufs->imageRegion.topLeft.y = self->rect.y;
+  self->inBufs->imageRegion.bottomRight.x = self->rect.x + self->rect.w;
+  self->inBufs->imageRegion.bottomRight.y = self->rect.y + self->rect.h;
+  self->inBufs->activeFrameRegion.topLeft.x = self->rect.x;
+  self->inBufs->activeFrameRegion.topLeft.y = self->rect.y;
+  self->inBufs->activeFrameRegion.bottomRight.x = self->rect.x + self->rect.w;
+  self->inBufs->activeFrameRegion.bottomRight.y = self->rect.y + self->rect.h;
   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;
@@ -620,3 +643,24 @@ have_inbuf:
 
   return gst_base_video_encoder_finish_frame (base_video_encoder, frame);
 }
+
+static gboolean
+gst_ducati_videnc_event (GstBaseVideoEncoder * enc, GstEvent * event)
+{
+  gboolean handled = FALSE;
+  GstDucatiVidEnc *self = GST_DUCATIVIDENC (enc);
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_CROP:
+      gst_event_parse_crop (event, &self->rect.y, &self->rect.x,
+          &self->rect.w, &self->rect.h);
+      GST_INFO_OBJECT (self, "got crop event top %d left %d %dx%d",
+          self->rect.x, self->rect.y, self->rect.w, self->rect.h);
+      handled = TRUE;
+      break;
+    default:
+      break;
+  }
+
+  return handled;
+}
index 90f81af18194320a237064a64f622c69f68852b4..11a3012f14ac27dba2a48288da73847c053f3a9d 100644 (file)
 typedef struct _GstDucatiVidEnc GstDucatiVidEnc;
 typedef struct _GstDucatiVidEncClass GstDucatiVidEncClass;
 
+typedef struct {
+  gint x;
+  gint y;
+  gint w;
+  gint h;
+} GstDucatiVideoRectangle;
+
 struct _GstDucatiVidEnc
 {
   GstBaseVideoEncoder base_encoder;
@@ -66,6 +73,8 @@ struct _GstDucatiVidEnc
   GstDucatiBufferPool *output_pool;
   gboolean configure;
 
+  GstDucatiVideoRectangle rect;
+
   gint bitrate;
   guint rate_preset;
 };