ducatividenc: cleanup param initialization
[glsdk/gst-plugin-ducati.git] / src / gstducatividenc.c
1 /* GStreamer
2  * Copyright (c) 2011, Texas Instruments Incorporated
3  * Copyright (c) 2011, Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alessandro Decina <alessandro.decina@collabora.com>
21  */
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
27 #include "gstducati.h"
28 #include "gstducatividenc.h"
29 #include "gstducatibufferpriv.h"
31 #include <string.h>
33 #include <math.h>
35 #define GST_CAT_DEFAULT gst_ducati_debug
37 #define DEFAULT_BITRATE 2048
38 #define DEFAULT_RATE_PRESET GST_DUCATI_VIDENC_RATE_PRESET_STORAGE
39 #define DEFAULT_INTRA_INTERVAL 15
41 #define GST_TYPE_DUCATI_VIDENC_RATE_PRESET (gst_ducati_videnc_rate_preset_get_type ())
44 enum
45 {
46   LAST_SIGNAL
47 };
49 enum
50 {
51   PROP_0,
52   PROP_BITRATE,
53   PROP_RATE_PRESET,
54   PROP_INTRA_INTERVAL
55 };
57 static void gst_ducati_videnc_set_property (GObject * object, guint prop_id,
58     const GValue * value, GParamSpec * pspec);
59 static void gst_ducati_videnc_get_property (GObject * object, guint prop_id,
60     GValue * value, GParamSpec * pspec);
61 static GstDucatiBufferPriv *get_buffer_priv (GstDucatiVidEnc * self,
62     GstBuffer * buf, gint stride, gint height);
64 static gboolean gst_ducati_videnc_set_format (GstBaseVideoEncoder *
65     base_video_encoder, GstVideoState * state);
66 static gboolean gst_ducati_videnc_start (GstBaseVideoEncoder *
67     base_video_encoder);
68 static gboolean gst_ducati_videnc_stop (GstBaseVideoEncoder *
69     base_video_encoder);
70 static GstFlowReturn gst_ducati_videnc_finish (GstBaseVideoEncoder *
71     base_video_encoder);
72 static GstFlowReturn gst_ducati_videnc_handle_frame (GstBaseVideoEncoder *
73     base_video_encoder, GstVideoFrame * frame);
74 static gboolean gst_ducati_videnc_allocate_params_default (GstDucatiVidEnc *
75     self, gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz,
76     gint outargs_sz);
77 static gboolean gst_ducati_videnc_configure_default (GstDucatiVidEnc * self);
78 static gboolean gst_ducati_videnc_event (GstBaseVideoEncoder * enc,
79     GstEvent * event);
82 GST_BOILERPLATE (GstDucatiVidEnc, gst_ducati_videnc, GstBaseVideoEncoder,
83     GST_TYPE_BASE_VIDEO_ENCODER);
86 /* the values for the following enums are taken from the codec */
88 enum
89 {
90   GST_DUCATI_VIDENC_RATE_PRESET_LOW_DELAY = 1,   /**< CBR rate control for video conferencing. */
91   GST_DUCATI_VIDENC_RATE_PRESET_STORAGE = 2,     /**< VBR rate control for local storage (DVD)
92                            *   recording.
93                            */
94   GST_DUCATI_VIDENC_RATE_PRESET_TWOPASS = 3,     /**< Two pass rate control for non real time
95                            *   applications.
96                            */
97   GST_DUCATI_VIDENC_RATE_PRESET_NONE = 4,        /**< No configurable video rate control
98                             *  mechanism.
99                             */
100   GST_DUCATI_VIDENC_RATE_PRESET_USER_DEFINED = 5,/**< User defined configuration using extended
101                            *   parameters.
102                            */
103 };
105 static GType
106 gst_ducati_videnc_rate_preset_get_type (void)
108   static GType type = 0;
110   if (!type) {
111     static const GEnumValue vals[] = {
112       {GST_DUCATI_VIDENC_RATE_PRESET_LOW_DELAY, "Low Delay", "low-delay"},
113       {GST_DUCATI_VIDENC_RATE_PRESET_STORAGE, "Storage", "storage"},
114       {GST_DUCATI_VIDENC_RATE_PRESET_TWOPASS, "Two-Pass", "two-pass"},
115       {0, NULL, NULL},
116     };
118     type = g_enum_register_static ("GstDucatiVidEncRatePreset", vals);
119   }
121   return type;
124 static void
125 gst_ducati_videnc_base_init (gpointer g_class)
129 static void
130 gst_ducati_videnc_class_init (GstDucatiVidEncClass * klass)
132   GObjectClass *gobject_class;
133   GstBaseVideoEncoderClass *basevideoencoder_class;
135   gobject_class = G_OBJECT_CLASS (klass);
136   basevideoencoder_class = GST_BASE_VIDEO_ENCODER_CLASS (klass);
138   gobject_class->set_property = gst_ducati_videnc_set_property;
139   gobject_class->get_property = gst_ducati_videnc_get_property;
141   basevideoencoder_class->set_format =
142       GST_DEBUG_FUNCPTR (gst_ducati_videnc_set_format);
143   basevideoencoder_class->start = GST_DEBUG_FUNCPTR (gst_ducati_videnc_start);
144   basevideoencoder_class->stop = GST_DEBUG_FUNCPTR (gst_ducati_videnc_stop);
145   basevideoencoder_class->finish = GST_DEBUG_FUNCPTR (gst_ducati_videnc_finish);
146   basevideoencoder_class->handle_frame =
147       GST_DEBUG_FUNCPTR (gst_ducati_videnc_handle_frame);
148   basevideoencoder_class->event = GST_DEBUG_FUNCPTR (gst_ducati_videnc_event);
150   klass->allocate_params = gst_ducati_videnc_allocate_params_default;
151   klass->configure = gst_ducati_videnc_configure_default;
153   g_object_class_install_property (gobject_class, PROP_BITRATE,
154       g_param_spec_int ("bitrate", "Bitrate", "Bitrate in kbit/sec", -1,
155           100 * 1024, DEFAULT_BITRATE, G_PARAM_READWRITE));
157   g_object_class_install_property (gobject_class, PROP_RATE_PRESET,
158       g_param_spec_enum ("rate-preset", "H.264 Rate Control",
159           "H.264 Rate Control",
160           GST_TYPE_DUCATI_VIDENC_RATE_PRESET, DEFAULT_RATE_PRESET,
161           G_PARAM_READWRITE));
163   g_object_class_install_property (gobject_class, PROP_INTRA_INTERVAL,
164       g_param_spec_int ("intra-interval", "Intra-frame interval", "Interval between intra frames (keyframes)", 0,
165           INT_MAX, DEFAULT_INTRA_INTERVAL, G_PARAM_READWRITE));
168 static void
169 gst_ducati_videnc_init (GstDucatiVidEnc * self, GstDucatiVidEncClass * klass)
171   GST_DEBUG ("gst_ducati_videnc_init");
173   self->device = NULL;
174   self->engine = NULL;
175   self->codec = NULL;
176   self->params = NULL;
177   self->status = NULL;
178   self->inBufs = NULL;
179   self->outBufs = NULL;
180   self->inArgs = NULL;
181   self->outArgs = NULL;
182   self->input_pool = NULL;
183   self->output_pool = NULL;
185   self->bitrate = DEFAULT_BITRATE * 1000;
186   self->rate_preset = DEFAULT_RATE_PRESET;
187   self->intra_interval = DEFAULT_INTRA_INTERVAL;
190 static gboolean
191 gst_ducati_videnc_set_format (GstBaseVideoEncoder * base_video_encoder,
192     GstVideoState * state)
194   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
196   self->configure = TRUE;
198   return TRUE;
201 static void
202 gst_ducati_videnc_set_property (GObject * object, guint prop_id,
203     const GValue * value, GParamSpec * pspec)
205   GstDucatiVidEnc *self = GST_DUCATIVIDENC (object);
207   g_return_if_fail (GST_IS_DUCATIVIDENC (object));
208   self = GST_DUCATIVIDENC (object);
210   switch (prop_id) {
211     case PROP_BITRATE:
212       self->bitrate = g_value_get_int (value) * 1000;
213       break;
214     case PROP_RATE_PRESET:
215       self->rate_preset = g_value_get_enum (value);
216       break;
217     case PROP_INTRA_INTERVAL:
218       self->intra_interval = g_value_get_int (value);
219       break;
220     default:
221       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
222   }
225 static void
226 gst_ducati_videnc_get_property (GObject * object, guint prop_id,
227     GValue * value, GParamSpec * pspec)
229   GstDucatiVidEnc *self = GST_DUCATIVIDENC (object);
231   g_return_if_fail (GST_IS_DUCATIVIDENC (object));
232   self = GST_DUCATIVIDENC (object);
234   switch (prop_id) {
235     case PROP_BITRATE:
236       g_value_set_int (value, self->bitrate / 1000);
237       break;
238     case PROP_RATE_PRESET:
239       g_value_set_enum (value, self->rate_preset);
240       break;
241     case PROP_INTRA_INTERVAL:
242       g_value_set_int (value, self->intra_interval);
243       break;
244     default:
245       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
246   }
249 static gboolean
250 gst_ducati_videnc_configure (GstDucatiVidEnc * self)
252   int err;
253   int i;
254   int max_out_size = 0;
255   const GstVideoState *state;
257   state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (self));
259   if (!GST_DUCATIVIDENC_GET_CLASS (self)->configure (self))
260     return FALSE;
262   if (self->codec == NULL) {
263     const gchar *codec_name;
265     codec_name = GST_DUCATIVIDENC_GET_CLASS (self)->codec_name;
266     self->codec = VIDENC2_create (self->engine,
267         (String) codec_name, self->params);
268     if (self->codec == NULL) {
269       GST_ERROR_OBJECT (self, "couldn't create codec");
270       return FALSE;
271     }
272   }
274   err = VIDENC2_control (self->codec,
275       XDM_SETPARAMS, self->dynParams, self->status);
276   if (err) {
277     GST_ERROR_OBJECT (self, "XDM_SETPARAMS err=%d, extendedError=%08x",
278         err, self->status->extendedError);
280     return FALSE;
281   }
283   err = VIDENC2_control (self->codec,
284       XDM_GETBUFINFO, self->dynParams, self->status);
285   if (err) {
286     GST_ERROR_OBJECT (self, "XDM_GETBUFINFO err=%d, extendedError=%08x",
287         err, self->status->extendedError);
289     return FALSE;
290   }
292   self->outBufs->numBufs = self->status->bufInfo.minNumOutBufs;
293   for (i = 0; i < self->outBufs->numBufs; i++) {
294     int size = self->status->bufInfo.minOutBufSize[i].bytes;
295     if (size > max_out_size)
296       max_out_size = size;
297   }
299   g_assert (self->input_pool == NULL);
300   self->input_pool = gst_drm_buffer_pool_new (GST_ELEMENT (self),
301       dce_get_fd (), NULL, state->bytes_per_picture);
303   g_assert (self->output_pool == NULL);
304   self->output_pool = gst_drm_buffer_pool_new (GST_ELEMENT (self),
305       dce_get_fd (), NULL, max_out_size);
307   GST_INFO_OBJECT (self, "configured");
309   self->configure = FALSE;
311   return TRUE;
314 static gboolean
315 gst_ducati_videnc_configure_default (GstDucatiVidEnc * self)
317   VIDENC2_DynamicParams *dynParams;
318   VIDENC2_Params *params;
319   const GstVideoState *state;
320   int i;
322   state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (self));
324   if (self->rect.w == 0)
325     self->rect.w = state->width;
327   if (self->rect.h == 0)
328     self->rect.h = state->height;
330   params = (VIDENC2_Params *) self->params;
331   params->encodingPreset = 0x03;
332   params->rateControlPreset = self->rate_preset;
333   params->maxHeight = self->rect.h;
334   params->maxWidth = self->rect.w;
335   params->dataEndianness = XDM_BYTE;
336   params->maxInterFrameInterval = 1;
337   params->maxBitRate = -1;
338   params->minBitRate = 0;
339   params->inputChromaFormat = XDM_YUV_420SP;
340   params->inputContentType = IVIDEO_PROGRESSIVE;
341   params->operatingMode = IVIDEO_ENCODE_ONLY;
342   params->inputDataMode = IVIDEO_ENTIREFRAME;
343   params->outputDataMode = IVIDEO_ENTIREFRAME;
344   params->numInputDataUnits = 1;
345   params->numOutputDataUnits = 1;
346   for (i = 0; i < IVIDEO_MAX_NUM_METADATA_PLANES; i++) {
347     params->metadataType[i] = IVIDEO_METADATAPLANE_NONE;
348   }
350   dynParams = (VIDENC2_DynamicParams *) self->dynParams;
352   dynParams->refFrameRate =
353       gst_util_uint64_scale (1000, state->fps_n, state->fps_d);
354   dynParams->targetFrameRate = dynParams->refFrameRate;
355   dynParams->inputWidth = self->rect.w;
356   dynParams->inputHeight = self->rect.h;
357   dynParams->targetBitRate = self->bitrate;
358   dynParams->intraFrameInterval = self->intra_interval;
359   dynParams->captureWidth = dynParams->inputWidth;
361   dynParams->forceFrame = IVIDEO_NA_FRAME;
362   dynParams->interFrameInterval = 1;
363   dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL;
364   dynParams->sampleAspectRatioHeight = 1;
365   dynParams->sampleAspectRatioWidth = 1;
366   dynParams->generateHeader = XDM_ENCODE_AU;
367   dynParams->ignoreOutbufSizeFlag = 1;
368   dynParams->lateAcquireArg = -1;
370   self->inBufs->chromaFormat = XDM_YUV_420SP;
371   self->inBufs->numPlanes = 2;
373   return TRUE;
376 static gboolean
377 gst_ducati_videnc_open_engine (GstDucatiVidEnc * self)
379   int error_code;
381   if (self->device == NULL) {
382     self->device = dce_init ();
383     if (self->device == NULL)
384       return FALSE;
385   }
387   self->engine = Engine_open ((String) "ivahd_vidsvr", NULL, &error_code);
388   if (self->engine == NULL) {
389     GST_ERROR_OBJECT (self, "couldn't open engine");
390     return FALSE;
391   }
393   return TRUE;
396 static gboolean
397 gst_ducati_videnc_allocate_params (GstDucatiVidEnc * self)
399   return GST_DUCATIVIDENC_GET_CLASS (self)->allocate_params (self,
400       sizeof (IVIDENC2_Params), sizeof (IVIDENC2_DynamicParams),
401       sizeof (IVIDENC2_Status), sizeof (IVIDENC2_InArgs),
402       sizeof (IVIDENC2_OutArgs));
405 static gboolean
406 gst_ducati_videnc_allocate_params_default (GstDucatiVidEnc * self,
407     gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz,
408     gint outargs_sz)
410   self->params = dce_alloc (params_sz);
411   memset (self->params, 0, params_sz);
412   self->params->size = params_sz;
414   self->dynParams = dce_alloc (dynparams_sz);
415   memset (self->dynParams, 0, dynparams_sz);
416   self->dynParams->size = dynparams_sz;
418   self->status = dce_alloc (status_sz);
419   memset (self->status, 0, status_sz);
420   self->status->size = status_sz;
422   self->inBufs = dce_alloc (sizeof (IVIDEO2_BufDesc));
423   memset (self->inBufs, 0, sizeof (IVIDEO2_BufDesc));
425   self->outBufs = dce_alloc (sizeof (XDM2_BufDesc));
426   memset (self->outBufs, 0, sizeof (XDM2_BufDesc));
428   self->inArgs = dce_alloc (inargs_sz);
429   memset (self->inArgs, 0, inargs_sz);
430   self->inArgs->size = inargs_sz;
432   self->outArgs = dce_alloc (outargs_sz);
433   memset (self->outArgs, 0, outargs_sz);
434   self->outArgs->size = outargs_sz;
436   GST_INFO_OBJECT (self, "started");
438   return TRUE;
441 static gboolean
442 gst_ducati_videnc_free_params (GstDucatiVidEnc * self)
444   if (self->params) {
445     dce_free (self->params);
446     self->params = NULL;
447   }
449   if (self->dynParams) {
450     dce_free (self->dynParams);
451     self->dynParams = NULL;
452   }
454   if (self->inArgs) {
455     dce_free (self->inArgs);
456     self->inArgs = NULL;
457   }
459   if (self->outArgs) {
460     dce_free (self->outArgs);
461     self->outArgs = NULL;
462   }
464   if (self->status) {
465     dce_free (self->status);
466     self->status = NULL;
467   }
469   if (self->inBufs) {
470     dce_free (self->inBufs);
471     self->inBufs = NULL;
472   }
474   if (self->outBufs) {
475     dce_free (self->outBufs);
476     self->outBufs = NULL;
477   }
479   if (self->codec) {
480     VIDENC2_delete (self->codec);
481     self->codec = NULL;
482   }
484   return TRUE;
487 static void
488 gst_ducati_videnc_close_engine (GstDucatiVidEnc * self)
490   if (self->engine) {
491     Engine_close (self->engine);
492     self->engine = NULL;
493   }
495   if (self->device) {
496     dce_deinit (self->device);
497     self->device = NULL;
498   }
502 static gboolean
503 gst_ducati_videnc_start (GstBaseVideoEncoder * base_video_encoder)
505   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
507   self->configure = TRUE;
508   memset (&self->rect, 0, sizeof (GstDucatiVideoRectangle));
510   if (!gst_ducati_videnc_open_engine (self))
511     goto fail;
513   if (!gst_ducati_videnc_allocate_params (self))
514     goto fail;
516   return TRUE;
518 fail:
519   gst_ducati_videnc_free_params (self);
520   gst_ducati_videnc_close_engine (self);
521   return FALSE;
524 static gboolean
525 gst_ducati_videnc_stop (GstBaseVideoEncoder * base_video_encoder)
527   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
529   gst_ducati_videnc_free_params (self);
530   gst_ducati_videnc_close_engine (self);
532   if (self->input_pool) {
533     gst_drm_buffer_pool_destroy (self->input_pool);
534     self->input_pool = NULL;
535   }
537   if (self->output_pool) {
538     gst_drm_buffer_pool_destroy (self->output_pool);
539     self->output_pool = NULL;
540   }
542   /* reset cropping rect */
543   memset (&self->rect, 0, sizeof (GstDucatiVideoRectangle));
545   return TRUE;
548 static GstFlowReturn
549 gst_ducati_videnc_finish (GstBaseVideoEncoder * base_video_encoder)
551   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
553   GST_DEBUG_OBJECT (self, "finish");
555   return GST_FLOW_OK;
558 static GstFlowReturn
559 gst_ducati_videnc_handle_frame (GstBaseVideoEncoder * base_video_encoder,
560     GstVideoFrame * frame)
562   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
563   GstBuffer *inbuf, *outbuf;
564   GstDucatiBufferPriv *priv_in, *priv_out;
565   XDAS_Int32 err;
566   const GstVideoState *state;
567   int i;
569   state = gst_base_video_encoder_get_state (base_video_encoder);
571   if (G_UNLIKELY (self->configure)) {
572     if (!gst_ducati_videnc_configure (self)) {
573       GST_DEBUG_OBJECT (self, "configure failed");
574       GST_ELEMENT_ERROR (self, STREAM, ENCODE, (NULL), (NULL));
576       return GST_FLOW_ERROR;
577     }
578   }
580   inbuf = gst_buffer_ref (frame->sink_buffer);
581 have_inbuf:
582   priv_in = get_buffer_priv (self, inbuf, state->width, state->height);
583   if (priv_in == NULL) {
584     GST_DEBUG_OBJECT (self, "memcpying input");
585     gst_buffer_unref (inbuf);
586     inbuf = GST_BUFFER (gst_drm_buffer_pool_get (self->input_pool, FALSE));
587     memcpy (GST_BUFFER_DATA (inbuf), GST_BUFFER_DATA (frame->sink_buffer),
588         GST_BUFFER_SIZE (frame->sink_buffer));
589     goto have_inbuf;
590   }
592   outbuf = GST_BUFFER (gst_drm_buffer_pool_get (self->output_pool, FALSE));
593   priv_out = get_buffer_priv (self, outbuf, state->width, state->height);
595   self->inBufs->planeDesc[0].buf = (XDAS_Int8 *) omap_bo_handle (priv_in->bo);
596   self->inBufs->planeDesc[0].memType = XDM_MEMTYPE_BO;
597   self->inBufs->planeDesc[0].bufSize.tileMem.width = state->width;
598   self->inBufs->planeDesc[0].bufSize.tileMem.height = state->height;
599   self->inBufs->planeDesc[1].buf = (XDAS_Int8 *) priv_in->uv_offset;
600   self->inBufs->planeDesc[1].memType = XDM_MEMTYPE_BO_OFFSET;
601   self->inBufs->planeDesc[1].bufSize.tileMem.width = state->width;
602   self->inBufs->planeDesc[1].bufSize.tileMem.height = state->height / 2;
603   /* setting imageRegion doesn't seem to be strictly needed if activeFrameRegion
604    * is set but we set it anyway...
605    */
606   self->inBufs->imageRegion.topLeft.x = self->rect.x;
607   self->inBufs->imageRegion.topLeft.y = self->rect.y;
608   self->inBufs->imageRegion.bottomRight.x = self->rect.x + self->rect.w;
609   self->inBufs->imageRegion.bottomRight.y = self->rect.y + self->rect.h;
610   self->inBufs->activeFrameRegion.topLeft.x = self->rect.x;
611   self->inBufs->activeFrameRegion.topLeft.y = self->rect.y;
612   self->inBufs->activeFrameRegion.bottomRight.x = self->rect.x + self->rect.w;
613   self->inBufs->activeFrameRegion.bottomRight.y = self->rect.y + self->rect.h;
614   self->inBufs->imagePitch[0] = state->width;
615   self->inBufs->imagePitch[1] = state->width;
616   self->inBufs->topFieldFirstFlag = TRUE;
618   self->outBufs->numBufs = 1;
619   self->outBufs->descs[0].buf = (XDAS_Int8 *) omap_bo_handle (priv_out->bo);
620   self->outBufs->descs[0].bufSize.bytes = GST_BUFFER_SIZE (outbuf);
621   self->outBufs->descs[0].memType = XDM_MEMTYPE_BO;
624   self->inArgs->inputID = GPOINTER_TO_INT (inbuf);
626   err = VIDENC2_process (self->codec, self->inBufs, self->outBufs,
627       self->inArgs, self->outArgs);
628   if (err) {
629     GST_WARNING_OBJECT (self, "process failed: err=%d, extendedError=%08x",
630         err, self->status->extendedError);
632     err = VIDENC2_control (self->codec,
633         XDM_GETSTATUS, (IVIDENC2_DynamicParams *) self->dynParams,
634         self->status);
636     GST_WARNING_OBJECT (self, "XDM_GETSTATUS: err=%d, extendedError=%08x",
637         err, self->status->extendedError);
639     return GST_FLOW_ERROR;
640   }
642   if (!strcmp (GST_DUCATIVIDENC_GET_CLASS (self)->codec_name, "ivahd_h264enc")) {
643     if (self->outArgs->encodedFrameType == IVIDEO_IDR_FRAME)
644       frame->is_sync_point = TRUE;
645   } else {
646     if (self->outArgs->encodedFrameType == IVIDEO_I_FRAME)
647       frame->is_sync_point = TRUE;
648   }
649   frame->src_buffer = gst_buffer_new_and_alloc (self->outArgs->bytesGenerated);
650   memcpy (GST_BUFFER_DATA (frame->src_buffer),
651       GST_BUFFER_DATA (outbuf), self->outArgs->bytesGenerated);
653   gst_buffer_unref (outbuf);
655   for (i = 0; self->outArgs->freeBufID[i]; i++) {
656     GstBuffer *buf = (GstBuffer *) self->outArgs->freeBufID[i];
658     GST_LOG_OBJECT (self, "free buffer: %p", buf);
659     gst_buffer_unref (buf);
660   }
662   return gst_base_video_encoder_finish_frame (base_video_encoder, frame);
665 static gboolean
666 gst_ducati_videnc_event (GstBaseVideoEncoder * enc, GstEvent * event)
668   gboolean handled = FALSE;
669   GstDucatiVidEnc *self = GST_DUCATIVIDENC (enc);
671   switch (GST_EVENT_TYPE (event)) {
672     case GST_EVENT_CROP:
673       gst_event_parse_crop (event, &self->rect.y, &self->rect.x,
674           &self->rect.w, &self->rect.h);
675       GST_INFO_OBJECT (self, "got crop event top %d left %d %dx%d",
676           self->rect.x, self->rect.y, self->rect.w, self->rect.h);
677       handled = TRUE;
678       break;
679     default:
680       break;
681   }
683   return handled;
686 static GstDucatiBufferPriv *
687 get_buffer_priv (GstDucatiVidEnc * self, GstBuffer * buf,
688     gint stride, gint height)
690   GstDucatiBufferPriv *priv = gst_ducati_buffer_priv_get (buf);
691   if (!priv) {
692     GstVideoFormat format = GST_VIDEO_FORMAT_NV12;
693     GstDmaBuf *dmabuf = gst_buffer_get_dma_buf (buf);
695     /* if it isn't a dmabuf buffer that we can import, then there
696      * is nothing we can do with it:
697      */
698     if (!dmabuf) {
699       GST_DEBUG_OBJECT (self, "not importing non dmabuf buffer");
700       return NULL;
701     }
703     priv = gst_ducati_buffer_priv_new ();
704     priv->bo = omap_bo_from_dmabuf (self->device, gst_dma_buf_get_fd (dmabuf));
706     priv->uv_offset = gst_video_format_get_component_offset (format,
707         1, stride, height);
708     priv->size = gst_video_format_get_size (format, stride, height);
710     gst_ducati_buffer_priv_set (buf, priv);
711   }
712   return priv;