ducatividenc: log extended error info, and use the correct one from _process
[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);
279     gst_ducati_log_extended_error_info (self->status->extendedError);
281     return FALSE;
282   }
284   err = VIDENC2_control (self->codec,
285       XDM_GETBUFINFO, self->dynParams, self->status);
286   if (err) {
287     GST_ERROR_OBJECT (self, "XDM_GETBUFINFO err=%d, extendedError=%08x",
288         err, self->status->extendedError);
290     return FALSE;
291   }
293   self->outBufs->numBufs = self->status->bufInfo.minNumOutBufs;
294   for (i = 0; i < self->outBufs->numBufs; i++) {
295     int size = self->status->bufInfo.minOutBufSize[i].bytes;
296     if (size > max_out_size)
297       max_out_size = size;
298   }
300   g_assert (self->input_pool == NULL);
301   self->input_pool = gst_drm_buffer_pool_new (GST_ELEMENT (self),
302       dce_get_fd (), NULL, state->bytes_per_picture);
304   g_assert (self->output_pool == NULL);
305   self->output_pool = gst_drm_buffer_pool_new (GST_ELEMENT (self),
306       dce_get_fd (), NULL, max_out_size);
308   GST_INFO_OBJECT (self, "configured");
310   self->configure = FALSE;
312   return TRUE;
315 static gboolean
316 gst_ducati_videnc_configure_default (GstDucatiVidEnc * self)
318   VIDENC2_DynamicParams *dynParams;
319   VIDENC2_Params *params;
320   const GstVideoState *state;
321   int i;
323   state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (self));
325   if (self->rect.w == 0)
326     self->rect.w = state->width;
328   if (self->rect.h == 0)
329     self->rect.h = state->height;
331   params = (VIDENC2_Params *) self->params;
332   params->encodingPreset = 0x03;
333   params->rateControlPreset = self->rate_preset;
334   params->maxHeight = self->rect.h;
335   params->maxWidth = self->rect.w;
336   params->dataEndianness = XDM_BYTE;
337   params->maxInterFrameInterval = 1;
338   params->maxBitRate = -1;
339   params->minBitRate = 0;
340   params->inputChromaFormat = XDM_YUV_420SP;
341   params->inputContentType = IVIDEO_PROGRESSIVE;
342   params->operatingMode = IVIDEO_ENCODE_ONLY;
343   params->inputDataMode = IVIDEO_ENTIREFRAME;
344   params->outputDataMode = IVIDEO_ENTIREFRAME;
345   params->numInputDataUnits = 1;
346   params->numOutputDataUnits = 1;
347   for (i = 0; i < IVIDEO_MAX_NUM_METADATA_PLANES; i++) {
348     params->metadataType[i] = IVIDEO_METADATAPLANE_NONE;
349   }
351   dynParams = (VIDENC2_DynamicParams *) self->dynParams;
353   dynParams->refFrameRate =
354       gst_util_uint64_scale (1000, state->fps_n, state->fps_d);
355   dynParams->targetFrameRate = dynParams->refFrameRate;
356   dynParams->inputWidth = self->rect.w;
357   dynParams->inputHeight = self->rect.h;
358   dynParams->targetBitRate = self->bitrate;
359   dynParams->intraFrameInterval = self->intra_interval;
360   dynParams->captureWidth = dynParams->inputWidth;
362   dynParams->forceFrame = IVIDEO_NA_FRAME;
363   dynParams->interFrameInterval = 1;
364   dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL;
365   dynParams->sampleAspectRatioHeight = 1;
366   dynParams->sampleAspectRatioWidth = 1;
367   dynParams->generateHeader = XDM_ENCODE_AU;
368   dynParams->ignoreOutbufSizeFlag = 1;
369   dynParams->lateAcquireArg = -1;
371   self->inBufs->chromaFormat = XDM_YUV_420SP;
372   self->inBufs->numPlanes = 2;
374   return TRUE;
377 static gboolean
378 gst_ducati_videnc_open_engine (GstDucatiVidEnc * self)
380   int error_code;
382   if (self->device == NULL) {
383     self->device = dce_init ();
384     if (self->device == NULL)
385       return FALSE;
386   }
388   self->engine = Engine_open ((String) "ivahd_vidsvr", NULL, &error_code);
389   if (self->engine == NULL) {
390     GST_ERROR_OBJECT (self, "couldn't open engine");
391     return FALSE;
392   }
394   return TRUE;
397 static gboolean
398 gst_ducati_videnc_allocate_params (GstDucatiVidEnc * self)
400   return GST_DUCATIVIDENC_GET_CLASS (self)->allocate_params (self,
401       sizeof (IVIDENC2_Params), sizeof (IVIDENC2_DynamicParams),
402       sizeof (IVIDENC2_Status), sizeof (IVIDENC2_InArgs),
403       sizeof (IVIDENC2_OutArgs));
406 static gboolean
407 gst_ducati_videnc_allocate_params_default (GstDucatiVidEnc * self,
408     gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz,
409     gint outargs_sz)
411   self->params = dce_alloc (params_sz);
412   memset (self->params, 0, params_sz);
413   self->params->size = params_sz;
415   self->dynParams = dce_alloc (dynparams_sz);
416   memset (self->dynParams, 0, dynparams_sz);
417   self->dynParams->size = dynparams_sz;
419   self->status = dce_alloc (status_sz);
420   memset (self->status, 0, status_sz);
421   self->status->size = status_sz;
423   self->inBufs = dce_alloc (sizeof (IVIDEO2_BufDesc));
424   memset (self->inBufs, 0, sizeof (IVIDEO2_BufDesc));
426   self->outBufs = dce_alloc (sizeof (XDM2_BufDesc));
427   memset (self->outBufs, 0, sizeof (XDM2_BufDesc));
429   self->inArgs = dce_alloc (inargs_sz);
430   memset (self->inArgs, 0, inargs_sz);
431   self->inArgs->size = inargs_sz;
433   self->outArgs = dce_alloc (outargs_sz);
434   memset (self->outArgs, 0, outargs_sz);
435   self->outArgs->size = outargs_sz;
437   GST_INFO_OBJECT (self, "started");
439   return TRUE;
442 static gboolean
443 gst_ducati_videnc_free_params (GstDucatiVidEnc * self)
445   if (self->params) {
446     dce_free (self->params);
447     self->params = NULL;
448   }
450   if (self->dynParams) {
451     dce_free (self->dynParams);
452     self->dynParams = NULL;
453   }
455   if (self->inArgs) {
456     dce_free (self->inArgs);
457     self->inArgs = NULL;
458   }
460   if (self->outArgs) {
461     dce_free (self->outArgs);
462     self->outArgs = NULL;
463   }
465   if (self->status) {
466     dce_free (self->status);
467     self->status = NULL;
468   }
470   if (self->inBufs) {
471     dce_free (self->inBufs);
472     self->inBufs = NULL;
473   }
475   if (self->outBufs) {
476     dce_free (self->outBufs);
477     self->outBufs = NULL;
478   }
480   if (self->codec) {
481     VIDENC2_delete (self->codec);
482     self->codec = NULL;
483   }
485   return TRUE;
488 static void
489 gst_ducati_videnc_close_engine (GstDucatiVidEnc * self)
491   if (self->engine) {
492     Engine_close (self->engine);
493     self->engine = NULL;
494   }
496   if (self->device) {
497     dce_deinit (self->device);
498     self->device = NULL;
499   }
503 static gboolean
504 gst_ducati_videnc_start (GstBaseVideoEncoder * base_video_encoder)
506   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
508   self->configure = TRUE;
509   memset (&self->rect, 0, sizeof (GstDucatiVideoRectangle));
511   if (!gst_ducati_videnc_open_engine (self))
512     goto fail;
514   if (!gst_ducati_videnc_allocate_params (self))
515     goto fail;
517   return TRUE;
519 fail:
520   gst_ducati_videnc_free_params (self);
521   gst_ducati_videnc_close_engine (self);
522   return FALSE;
525 static gboolean
526 gst_ducati_videnc_stop (GstBaseVideoEncoder * base_video_encoder)
528   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
530   gst_ducati_videnc_free_params (self);
531   gst_ducati_videnc_close_engine (self);
533   if (self->input_pool) {
534     gst_drm_buffer_pool_destroy (self->input_pool);
535     self->input_pool = NULL;
536   }
538   if (self->output_pool) {
539     gst_drm_buffer_pool_destroy (self->output_pool);
540     self->output_pool = NULL;
541   }
543   /* reset cropping rect */
544   memset (&self->rect, 0, sizeof (GstDucatiVideoRectangle));
546   return TRUE;
549 static GstFlowReturn
550 gst_ducati_videnc_finish (GstBaseVideoEncoder * base_video_encoder)
552   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
554   GST_DEBUG_OBJECT (self, "finish");
556   return GST_FLOW_OK;
559 static GstFlowReturn
560 gst_ducati_videnc_handle_frame (GstBaseVideoEncoder * base_video_encoder,
561     GstVideoFrame * frame)
563   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
564   GstBuffer *inbuf, *outbuf;
565   GstDucatiBufferPriv *priv_in, *priv_out;
566   XDAS_Int32 err;
567   const GstVideoState *state;
568   int i;
570   state = gst_base_video_encoder_get_state (base_video_encoder);
572   if (G_UNLIKELY (self->configure)) {
573     if (!gst_ducati_videnc_configure (self)) {
574       GST_DEBUG_OBJECT (self, "configure failed");
575       GST_ELEMENT_ERROR (self, STREAM, ENCODE, (NULL), (NULL));
577       return GST_FLOW_ERROR;
578     }
579   }
581   inbuf = gst_buffer_ref (frame->sink_buffer);
582 have_inbuf:
583   priv_in = get_buffer_priv (self, inbuf, state->width, state->height);
584   if (priv_in == NULL) {
585     GST_DEBUG_OBJECT (self, "memcpying input");
586     gst_buffer_unref (inbuf);
587     inbuf = GST_BUFFER (gst_drm_buffer_pool_get (self->input_pool, FALSE));
588     memcpy (GST_BUFFER_DATA (inbuf), GST_BUFFER_DATA (frame->sink_buffer),
589         GST_BUFFER_SIZE (frame->sink_buffer));
590     goto have_inbuf;
591   }
593   outbuf = GST_BUFFER (gst_drm_buffer_pool_get (self->output_pool, FALSE));
594   priv_out = get_buffer_priv (self, outbuf, state->width, state->height);
596   self->inBufs->planeDesc[0].buf = (XDAS_Int8 *) omap_bo_handle (priv_in->bo);
597   self->inBufs->planeDesc[0].memType = XDM_MEMTYPE_BO;
598   self->inBufs->planeDesc[0].bufSize.tileMem.width = state->width;
599   self->inBufs->planeDesc[0].bufSize.tileMem.height = state->height;
600   self->inBufs->planeDesc[1].buf = (XDAS_Int8 *) priv_in->uv_offset;
601   self->inBufs->planeDesc[1].memType = XDM_MEMTYPE_BO_OFFSET;
602   self->inBufs->planeDesc[1].bufSize.tileMem.width = state->width;
603   self->inBufs->planeDesc[1].bufSize.tileMem.height = state->height / 2;
604   /* setting imageRegion doesn't seem to be strictly needed if activeFrameRegion
605    * is set but we set it anyway...
606    */
607   self->inBufs->imageRegion.topLeft.x = self->rect.x;
608   self->inBufs->imageRegion.topLeft.y = self->rect.y;
609   self->inBufs->imageRegion.bottomRight.x = self->rect.x + self->rect.w;
610   self->inBufs->imageRegion.bottomRight.y = self->rect.y + self->rect.h;
611   self->inBufs->activeFrameRegion.topLeft.x = self->rect.x;
612   self->inBufs->activeFrameRegion.topLeft.y = self->rect.y;
613   self->inBufs->activeFrameRegion.bottomRight.x = self->rect.x + self->rect.w;
614   self->inBufs->activeFrameRegion.bottomRight.y = self->rect.y + self->rect.h;
615   self->inBufs->imagePitch[0] = state->width;
616   self->inBufs->imagePitch[1] = state->width;
617   self->inBufs->topFieldFirstFlag = TRUE;
619   self->outBufs->numBufs = 1;
620   self->outBufs->descs[0].buf = (XDAS_Int8 *) omap_bo_handle (priv_out->bo);
621   self->outBufs->descs[0].bufSize.bytes = GST_BUFFER_SIZE (outbuf);
622   self->outBufs->descs[0].memType = XDM_MEMTYPE_BO;
625   self->inArgs->inputID = GPOINTER_TO_INT (inbuf);
627   err = VIDENC2_process (self->codec, self->inBufs, self->outBufs,
628       self->inArgs, self->outArgs);
629   if (err) {
630     GST_WARNING_OBJECT (self, "process failed: err=%d, extendedError=%08x",
631         err, self->outArgs->extendedError);
632     gst_ducati_log_extended_error_info (self->outArgs->extendedError);
634     err = VIDENC2_control (self->codec,
635         XDM_GETSTATUS, (IVIDENC2_DynamicParams *) self->dynParams,
636         self->status);
638     GST_WARNING_OBJECT (self, "XDM_GETSTATUS: err=%d, extendedError=%08x",
639         err, self->status->extendedError);
641     return GST_FLOW_ERROR;
642   }
644   if (!strcmp (GST_DUCATIVIDENC_GET_CLASS (self)->codec_name, "ivahd_h264enc")) {
645     if (self->outArgs->encodedFrameType == IVIDEO_IDR_FRAME)
646       frame->is_sync_point = TRUE;
647   } else {
648     if (self->outArgs->encodedFrameType == IVIDEO_I_FRAME)
649       frame->is_sync_point = TRUE;
650   }
651   frame->src_buffer = gst_buffer_new_and_alloc (self->outArgs->bytesGenerated);
652   memcpy (GST_BUFFER_DATA (frame->src_buffer),
653       GST_BUFFER_DATA (outbuf), self->outArgs->bytesGenerated);
655   gst_buffer_unref (outbuf);
657   for (i = 0; self->outArgs->freeBufID[i]; i++) {
658     GstBuffer *buf = (GstBuffer *) self->outArgs->freeBufID[i];
660     GST_LOG_OBJECT (self, "free buffer: %p", buf);
661     gst_buffer_unref (buf);
662   }
664   return gst_base_video_encoder_finish_frame (base_video_encoder, frame);
667 static gboolean
668 gst_ducati_videnc_event (GstBaseVideoEncoder * enc, GstEvent * event)
670   gboolean handled = FALSE;
671   GstDucatiVidEnc *self = GST_DUCATIVIDENC (enc);
673   switch (GST_EVENT_TYPE (event)) {
674     case GST_EVENT_CROP:
675       gst_event_parse_crop (event, &self->rect.y, &self->rect.x,
676           &self->rect.w, &self->rect.h);
677       GST_INFO_OBJECT (self, "got crop event top %d left %d %dx%d",
678           self->rect.x, self->rect.y, self->rect.w, self->rect.h);
679       handled = TRUE;
680       break;
681     default:
682       break;
683   }
685   return handled;
688 static GstDucatiBufferPriv *
689 get_buffer_priv (GstDucatiVidEnc * self, GstBuffer * buf,
690     gint stride, gint height)
692   GstDucatiBufferPriv *priv = gst_ducati_buffer_priv_get (buf);
693   if (!priv) {
694     GstVideoFormat format = GST_VIDEO_FORMAT_NV12;
695     GstDmaBuf *dmabuf = gst_buffer_get_dma_buf (buf);
697     /* if it isn't a dmabuf buffer that we can import, then there
698      * is nothing we can do with it:
699      */
700     if (!dmabuf) {
701       GST_DEBUG_OBJECT (self, "not importing non dmabuf buffer");
702       return NULL;
703     }
705     priv = gst_ducati_buffer_priv_new ();
706     priv->bo = omap_bo_from_dmabuf (self->device, gst_dma_buf_get_fd (dmabuf));
708     priv->uv_offset = gst_video_format_get_component_offset (format,
709         1, stride, height);
710     priv->size = gst_video_format_get_size (format, stride, height);
712     gst_ducati_buffer_priv_set (buf, priv);
713   }
714   return priv;