ducatividenc: log how many bytes the encoded data is
[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_is_sync_point_default (GstDucatiVidEnc * enc,
78     int type);
79 static gboolean gst_ducati_videnc_configure_default (GstDucatiVidEnc * self);
80 static gboolean gst_ducati_videnc_event (GstBaseVideoEncoder * enc,
81     GstEvent * event);
84 GST_BOILERPLATE (GstDucatiVidEnc, gst_ducati_videnc, GstBaseVideoEncoder,
85     GST_TYPE_BASE_VIDEO_ENCODER);
88 /* the values for the following enums are taken from the codec */
90 enum
91 {
92   GST_DUCATI_VIDENC_RATE_PRESET_LOW_DELAY = IVIDEO_LOW_DELAY,   /**< CBR rate control for video conferencing. */
93   GST_DUCATI_VIDENC_RATE_PRESET_STORAGE = IVIDEO_STORAGE,  /**< VBR rate control for local storage (DVD)
94                            *   recording.
95                            */
96   GST_DUCATI_VIDENC_RATE_PRESET_TWOPASS = IVIDEO_TWOPASS,  /**< Two pass rate control for non real time
97                            *   applications.
98                            */
99   GST_DUCATI_VIDENC_RATE_PRESET_NONE = IVIDEO_NONE,        /**< No configurable video rate control
100                             *  mechanism.
101                             */
102   GST_DUCATI_VIDENC_RATE_PRESET_USER_DEFINED = IVIDEO_USER_DEFINED,/**< User defined configuration using extended
103                            *   parameters.
104                            */
105 };
107 static GType
108 gst_ducati_videnc_rate_preset_get_type (void)
110   static GType type = 0;
112   if (!type) {
113     static const GEnumValue vals[] = {
114       {GST_DUCATI_VIDENC_RATE_PRESET_LOW_DELAY, "Low Delay", "low-delay"},
115       {GST_DUCATI_VIDENC_RATE_PRESET_STORAGE, "Storage", "storage"},
116       {GST_DUCATI_VIDENC_RATE_PRESET_TWOPASS, "Two-Pass", "two-pass"},
117       {GST_DUCATI_VIDENC_RATE_PRESET_NONE, "None", "None"},
118       {GST_DUCATI_VIDENC_RATE_PRESET_USER_DEFINED, "User defined",
119           "user-defined"},
120       {0, NULL, NULL},
121     };
123     type = g_enum_register_static ("GstDucatiVidEncRatePreset", vals);
124   }
126   return type;
129 static void
130 gst_ducati_videnc_base_init (gpointer g_class)
134 static void
135 gst_ducati_videnc_class_init (GstDucatiVidEncClass * klass)
137   GObjectClass *gobject_class;
138   GstBaseVideoEncoderClass *basevideoencoder_class;
140   gobject_class = G_OBJECT_CLASS (klass);
141   basevideoencoder_class = GST_BASE_VIDEO_ENCODER_CLASS (klass);
143   gobject_class->set_property = gst_ducati_videnc_set_property;
144   gobject_class->get_property = gst_ducati_videnc_get_property;
146   basevideoencoder_class->set_format =
147       GST_DEBUG_FUNCPTR (gst_ducati_videnc_set_format);
148   basevideoencoder_class->start = GST_DEBUG_FUNCPTR (gst_ducati_videnc_start);
149   basevideoencoder_class->stop = GST_DEBUG_FUNCPTR (gst_ducati_videnc_stop);
150   basevideoencoder_class->finish = GST_DEBUG_FUNCPTR (gst_ducati_videnc_finish);
151   basevideoencoder_class->handle_frame =
152       GST_DEBUG_FUNCPTR (gst_ducati_videnc_handle_frame);
153   basevideoencoder_class->event = GST_DEBUG_FUNCPTR (gst_ducati_videnc_event);
155   klass->allocate_params = gst_ducati_videnc_allocate_params_default;
156   klass->configure = gst_ducati_videnc_configure_default;
157   klass->is_sync_point = gst_ducati_videnc_is_sync_point_default;
159   g_object_class_install_property (gobject_class, PROP_BITRATE,
160       g_param_spec_int ("bitrate", "Bitrate", "Bitrate in kbit/sec", -1,
161           100 * 1024, DEFAULT_BITRATE, G_PARAM_READWRITE));
163   g_object_class_install_property (gobject_class, PROP_RATE_PRESET,
164       g_param_spec_enum ("rate-preset", "H.264 Rate Control",
165           "H.264 Rate Control",
166           GST_TYPE_DUCATI_VIDENC_RATE_PRESET, DEFAULT_RATE_PRESET,
167           G_PARAM_READWRITE));
169   g_object_class_install_property (gobject_class, PROP_INTRA_INTERVAL,
170       g_param_spec_int ("intra-interval", "Intra-frame interval",
171           "Interval between intra frames (keyframes)", 0, INT_MAX,
172           DEFAULT_INTRA_INTERVAL, G_PARAM_READWRITE));
175 static void
176 gst_ducati_videnc_init (GstDucatiVidEnc * self, GstDucatiVidEncClass * klass)
178   GST_DEBUG ("gst_ducati_videnc_init");
180   self->device = NULL;
181   self->engine = NULL;
182   self->codec = NULL;
183   self->params = NULL;
184   self->status = NULL;
185   self->inBufs = NULL;
186   self->outBufs = NULL;
187   self->inArgs = NULL;
188   self->outArgs = NULL;
189   self->input_pool = NULL;
190   self->output_pool = NULL;
192   self->bitrate = DEFAULT_BITRATE * 1000;
193   self->rate_preset = DEFAULT_RATE_PRESET;
194   self->intra_interval = DEFAULT_INTRA_INTERVAL;
197 static gboolean
198 gst_ducati_videnc_set_format (GstBaseVideoEncoder * base_video_encoder,
199     GstVideoState * state)
201   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
203   self->configure = TRUE;
205   return TRUE;
208 static void
209 gst_ducati_videnc_set_property (GObject * object, guint prop_id,
210     const GValue * value, GParamSpec * pspec)
212   GstDucatiVidEnc *self = GST_DUCATIVIDENC (object);
214   g_return_if_fail (GST_IS_DUCATIVIDENC (object));
215   self = GST_DUCATIVIDENC (object);
217   switch (prop_id) {
218     case PROP_BITRATE:
219       self->bitrate = g_value_get_int (value) * 1000;
220       break;
221     case PROP_RATE_PRESET:
222       self->rate_preset = g_value_get_enum (value);
223       break;
224     case PROP_INTRA_INTERVAL:
225       self->intra_interval = g_value_get_int (value);
226       break;
227     default:
228       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
229   }
232 static void
233 gst_ducati_videnc_get_property (GObject * object, guint prop_id,
234     GValue * value, GParamSpec * pspec)
236   GstDucatiVidEnc *self = GST_DUCATIVIDENC (object);
238   g_return_if_fail (GST_IS_DUCATIVIDENC (object));
239   self = GST_DUCATIVIDENC (object);
241   switch (prop_id) {
242     case PROP_BITRATE:
243       g_value_set_int (value, self->bitrate / 1000);
244       break;
245     case PROP_RATE_PRESET:
246       g_value_set_enum (value, self->rate_preset);
247       break;
248     case PROP_INTRA_INTERVAL:
249       g_value_set_int (value, self->intra_interval);
250       break;
251     default:
252       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
253   }
256 static gboolean
257 gst_ducati_videnc_configure (GstDucatiVidEnc * self)
259   int err;
260   int i;
261   int max_out_size = 0;
262   const GstVideoState *state;
264   state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (self));
266   if (!GST_DUCATIVIDENC_GET_CLASS (self)->configure (self))
267     return FALSE;
269   if (self->codec == NULL) {
270     const gchar *codec_name;
272     codec_name = GST_DUCATIVIDENC_GET_CLASS (self)->codec_name;
273     self->codec = VIDENC2_create (self->engine,
274         (String) codec_name, self->params);
275     if (self->codec == NULL) {
276       GST_ERROR_OBJECT (self, "couldn't create codec");
277       return FALSE;
278     }
279   }
281   err = VIDENC2_control (self->codec,
282       XDM_SETPARAMS, self->dynParams, self->status);
283   if (err) {
284     GST_ERROR_OBJECT (self, "XDM_SETPARAMS err=%d, extendedError=%08x",
285         err, self->status->extendedError);
286     gst_ducati_log_extended_error_info (self->status->extendedError);
288     return FALSE;
289   }
291   err = VIDENC2_control (self->codec,
292       XDM_GETBUFINFO, self->dynParams, self->status);
293   if (err) {
294     GST_ERROR_OBJECT (self, "XDM_GETBUFINFO err=%d, extendedError=%08x",
295         err, self->status->extendedError);
297     return FALSE;
298   }
300   self->outBufs->numBufs = self->status->bufInfo.minNumOutBufs;
301   for (i = 0; i < self->outBufs->numBufs; i++) {
302     int size = self->status->bufInfo.minOutBufSize[i].bytes;
303     if (size > max_out_size)
304       max_out_size = size;
305   }
307   g_assert (self->input_pool == NULL);
308   self->input_pool = gst_drm_buffer_pool_new (GST_ELEMENT (self),
309       dce_get_fd (), NULL, state->bytes_per_picture);
311   g_assert (self->output_pool == NULL);
312   self->output_pool = gst_drm_buffer_pool_new (GST_ELEMENT (self),
313       dce_get_fd (), NULL, max_out_size);
315   GST_INFO_OBJECT (self, "configured");
317   self->configure = FALSE;
319   return TRUE;
322 static gboolean
323 gst_ducati_videnc_configure_default (GstDucatiVidEnc * self)
325   VIDENC2_DynamicParams *dynParams;
326   VIDENC2_Params *params;
327   const GstVideoState *state;
328   int i;
330   state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (self));
332   if (self->rect.w == 0)
333     self->rect.w = state->width;
335   if (self->rect.h == 0)
336     self->rect.h = state->height;
338   params = (VIDENC2_Params *) self->params;
339   params->encodingPreset = 0x03;
340   params->rateControlPreset = self->rate_preset;
341   params->maxHeight = self->rect.h;
342   params->maxWidth = self->rect.w;
343   params->dataEndianness = XDM_BYTE;
344   params->maxInterFrameInterval = 1;
345   params->maxBitRate = -1;
346   params->minBitRate = 0;
347   params->inputChromaFormat = XDM_YUV_420SP;
348   params->inputContentType = IVIDEO_PROGRESSIVE;
349   params->operatingMode = IVIDEO_ENCODE_ONLY;
350   params->inputDataMode = IVIDEO_ENTIREFRAME;
351   params->outputDataMode = IVIDEO_ENTIREFRAME;
352   params->numInputDataUnits = 1;
353   params->numOutputDataUnits = 1;
354   for (i = 0; i < IVIDEO_MAX_NUM_METADATA_PLANES; i++) {
355     params->metadataType[i] = IVIDEO_METADATAPLANE_NONE;
356   }
358   dynParams = (VIDENC2_DynamicParams *) self->dynParams;
360   dynParams->refFrameRate =
361       gst_util_uint64_scale (1000, state->fps_n, state->fps_d);
362   dynParams->targetFrameRate = dynParams->refFrameRate;
363   dynParams->inputWidth = self->rect.w;
364   dynParams->inputHeight = self->rect.h;
365   dynParams->targetBitRate = self->bitrate;
366   dynParams->intraFrameInterval = self->intra_interval;
367   dynParams->captureWidth = dynParams->inputWidth;
369   dynParams->forceFrame = IVIDEO_NA_FRAME;
370   dynParams->interFrameInterval = 1;
371   dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL;
372   dynParams->sampleAspectRatioHeight = 1;
373   dynParams->sampleAspectRatioWidth = 1;
374   dynParams->generateHeader = XDM_ENCODE_AU;
375   dynParams->ignoreOutbufSizeFlag = 1;
376   dynParams->lateAcquireArg = -1;
378   self->inBufs->chromaFormat = XDM_YUV_420SP;
379   self->inBufs->numPlanes = 2;
381   return TRUE;
384 static gboolean
385 gst_ducati_videnc_open_engine (GstDucatiVidEnc * self)
387   int error_code;
389   if (self->device == NULL) {
390     self->device = dce_init ();
391     if (self->device == NULL)
392       return FALSE;
393   }
395   self->engine = Engine_open ((String) "ivahd_vidsvr", NULL, &error_code);
396   if (self->engine == NULL) {
397     GST_ERROR_OBJECT (self, "couldn't open engine");
398     return FALSE;
399   }
401   return TRUE;
404 static gboolean
405 gst_ducati_videnc_allocate_params (GstDucatiVidEnc * self)
407   return GST_DUCATIVIDENC_GET_CLASS (self)->allocate_params (self,
408       sizeof (IVIDENC2_Params), sizeof (IVIDENC2_DynamicParams),
409       sizeof (IVIDENC2_Status), sizeof (IVIDENC2_InArgs),
410       sizeof (IVIDENC2_OutArgs));
413 static gboolean
414 gst_ducati_videnc_allocate_params_default (GstDucatiVidEnc * self,
415     gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz,
416     gint outargs_sz)
418   self->params = dce_alloc (params_sz);
419   memset (self->params, 0, params_sz);
420   self->params->size = params_sz;
422   self->dynParams = dce_alloc (dynparams_sz);
423   memset (self->dynParams, 0, dynparams_sz);
424   self->dynParams->size = dynparams_sz;
426   self->status = dce_alloc (status_sz);
427   memset (self->status, 0, status_sz);
428   self->status->size = status_sz;
430   self->inBufs = dce_alloc (sizeof (IVIDEO2_BufDesc));
431   memset (self->inBufs, 0, sizeof (IVIDEO2_BufDesc));
433   self->outBufs = dce_alloc (sizeof (XDM2_BufDesc));
434   memset (self->outBufs, 0, sizeof (XDM2_BufDesc));
436   self->inArgs = dce_alloc (inargs_sz);
437   memset (self->inArgs, 0, inargs_sz);
438   self->inArgs->size = inargs_sz;
440   self->outArgs = dce_alloc (outargs_sz);
441   memset (self->outArgs, 0, outargs_sz);
442   self->outArgs->size = outargs_sz;
444   GST_INFO_OBJECT (self, "started");
446   return TRUE;
449 static gboolean
450 gst_ducati_videnc_free_params (GstDucatiVidEnc * self)
452   if (self->params) {
453     dce_free (self->params);
454     self->params = NULL;
455   }
457   if (self->dynParams) {
458     dce_free (self->dynParams);
459     self->dynParams = NULL;
460   }
462   if (self->inArgs) {
463     dce_free (self->inArgs);
464     self->inArgs = NULL;
465   }
467   if (self->outArgs) {
468     dce_free (self->outArgs);
469     self->outArgs = NULL;
470   }
472   if (self->status) {
473     dce_free (self->status);
474     self->status = NULL;
475   }
477   if (self->inBufs) {
478     dce_free (self->inBufs);
479     self->inBufs = NULL;
480   }
482   if (self->outBufs) {
483     dce_free (self->outBufs);
484     self->outBufs = NULL;
485   }
487   if (self->codec) {
488     VIDENC2_delete (self->codec);
489     self->codec = NULL;
490   }
492   return TRUE;
495 static void
496 gst_ducati_videnc_close_engine (GstDucatiVidEnc * self)
498   if (self->engine) {
499     Engine_close (self->engine);
500     self->engine = NULL;
501   }
503   if (self->device) {
504     dce_deinit (self->device);
505     self->device = NULL;
506   }
510 static gboolean
511 gst_ducati_videnc_start (GstBaseVideoEncoder * base_video_encoder)
513   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
515   self->configure = TRUE;
516   memset (&self->rect, 0, sizeof (GstDucatiVideoRectangle));
518   if (!gst_ducati_videnc_open_engine (self))
519     goto fail;
521   if (!gst_ducati_videnc_allocate_params (self))
522     goto fail;
524   return TRUE;
526 fail:
527   gst_ducati_videnc_free_params (self);
528   gst_ducati_videnc_close_engine (self);
529   return FALSE;
532 static gboolean
533 gst_ducati_videnc_stop (GstBaseVideoEncoder * base_video_encoder)
535   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
537   gst_ducati_videnc_free_params (self);
538   gst_ducati_videnc_close_engine (self);
540   if (self->input_pool) {
541     gst_drm_buffer_pool_destroy (self->input_pool);
542     self->input_pool = NULL;
543   }
545   if (self->output_pool) {
546     gst_drm_buffer_pool_destroy (self->output_pool);
547     self->output_pool = NULL;
548   }
550   /* reset cropping rect */
551   memset (&self->rect, 0, sizeof (GstDucatiVideoRectangle));
553   return TRUE;
556 static GstFlowReturn
557 gst_ducati_videnc_finish (GstBaseVideoEncoder * base_video_encoder)
559   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
561   GST_DEBUG_OBJECT (self, "finish");
563   return GST_FLOW_OK;
566 static GstFlowReturn
567 gst_ducati_videnc_handle_frame (GstBaseVideoEncoder * base_video_encoder,
568     GstVideoFrame * frame)
570   GstDucatiVidEnc *self = GST_DUCATIVIDENC (base_video_encoder);
571   GstBuffer *inbuf, *outbuf;
572   GstDucatiBufferPriv *priv_in, *priv_out;
573   XDAS_Int32 err;
574   const GstVideoState *state;
575   int i;
577   state = gst_base_video_encoder_get_state (base_video_encoder);
579   if (G_UNLIKELY (self->configure)) {
580     if (!gst_ducati_videnc_configure (self)) {
581       GST_DEBUG_OBJECT (self, "configure failed");
582       GST_ELEMENT_ERROR (self, STREAM, ENCODE, (NULL), (NULL));
584       return GST_FLOW_ERROR;
585     }
586   }
588   inbuf = gst_buffer_ref (frame->sink_buffer);
589 have_inbuf:
590   priv_in = get_buffer_priv (self, inbuf, state->width, state->height);
591   if (priv_in == NULL) {
592     GST_DEBUG_OBJECT (self, "memcpying input");
593     gst_buffer_unref (inbuf);
594     inbuf = GST_BUFFER (gst_drm_buffer_pool_get (self->input_pool, FALSE));
595     memcpy (GST_BUFFER_DATA (inbuf), GST_BUFFER_DATA (frame->sink_buffer),
596         GST_BUFFER_SIZE (frame->sink_buffer));
597     goto have_inbuf;
598   }
600   outbuf = GST_BUFFER (gst_drm_buffer_pool_get (self->output_pool, FALSE));
601   priv_out = get_buffer_priv (self, outbuf, state->width, state->height);
603   self->inBufs->planeDesc[0].buf = (XDAS_Int8 *) omap_bo_handle (priv_in->bo);
604   self->inBufs->planeDesc[0].memType = XDM_MEMTYPE_BO;
605   self->inBufs->planeDesc[0].bufSize.tileMem.width = state->width;
606   self->inBufs->planeDesc[0].bufSize.tileMem.height = state->height;
607   self->inBufs->planeDesc[1].buf = (XDAS_Int8 *) priv_in->uv_offset;
608   self->inBufs->planeDesc[1].memType = XDM_MEMTYPE_BO_OFFSET;
609   self->inBufs->planeDesc[1].bufSize.tileMem.width = state->width;
610   self->inBufs->planeDesc[1].bufSize.tileMem.height = state->height / 2;
611   /* setting imageRegion doesn't seem to be strictly needed if activeFrameRegion
612    * is set but we set it anyway...
613    */
614   self->inBufs->imageRegion.topLeft.x = self->rect.x;
615   self->inBufs->imageRegion.topLeft.y = self->rect.y;
616   self->inBufs->imageRegion.bottomRight.x = self->rect.x + self->rect.w;
617   self->inBufs->imageRegion.bottomRight.y = self->rect.y + self->rect.h;
618   self->inBufs->activeFrameRegion.topLeft.x = self->rect.x;
619   self->inBufs->activeFrameRegion.topLeft.y = self->rect.y;
620   self->inBufs->activeFrameRegion.bottomRight.x = self->rect.x + self->rect.w;
621   self->inBufs->activeFrameRegion.bottomRight.y = self->rect.y + self->rect.h;
622   self->inBufs->imagePitch[0] = state->width;
623   self->inBufs->imagePitch[1] = state->width;
624   self->inBufs->topFieldFirstFlag = TRUE;
626   self->outBufs->numBufs = 1;
627   self->outBufs->descs[0].buf = (XDAS_Int8 *) omap_bo_handle (priv_out->bo);
628   self->outBufs->descs[0].bufSize.bytes = GST_BUFFER_SIZE (outbuf);
629   self->outBufs->descs[0].memType = XDM_MEMTYPE_BO;
632   self->inArgs->inputID = GPOINTER_TO_INT (inbuf);
634   err = VIDENC2_process (self->codec, self->inBufs, self->outBufs,
635       self->inArgs, self->outArgs);
636   if (err) {
637     GST_WARNING_OBJECT (self, "process failed: err=%d, extendedError=%08x",
638         err, self->outArgs->extendedError);
639     gst_ducati_log_extended_error_info (self->outArgs->extendedError);
641     err = VIDENC2_control (self->codec,
642         XDM_GETSTATUS, (IVIDENC2_DynamicParams *) self->dynParams,
643         self->status);
645     GST_WARNING_OBJECT (self, "XDM_GETSTATUS: err=%d, extendedError=%08x",
646         err, self->status->extendedError);
648     return GST_FLOW_ERROR;
649   }
651   frame->is_sync_point = GST_DUCATIVIDENC_GET_CLASS (self)->is_sync_point (self,
652       self->outArgs->encodedFrameType);
653   frame->src_buffer = gst_buffer_new_and_alloc (self->outArgs->bytesGenerated);
654   memcpy (GST_BUFFER_DATA (frame->src_buffer),
655       GST_BUFFER_DATA (outbuf), self->outArgs->bytesGenerated);
656   GST_DEBUG_OBJECT (self, "Encoded frame in %u bytes",
657       self->outArgs->bytesGenerated);
659   gst_buffer_unref (outbuf);
661   for (i = 0; self->outArgs->freeBufID[i]; i++) {
662     GstBuffer *buf = (GstBuffer *) self->outArgs->freeBufID[i];
664     GST_LOG_OBJECT (self, "free buffer: %p", buf);
665     gst_buffer_unref (buf);
666   }
668   return gst_base_video_encoder_finish_frame (base_video_encoder, frame);
671 static gboolean
672 gst_ducati_videnc_is_sync_point_default (GstDucatiVidEnc * enc, int type)
674   return type == IVIDEO_I_FRAME;
677 static gboolean
678 gst_ducati_videnc_event (GstBaseVideoEncoder * enc, GstEvent * event)
680   gboolean handled = FALSE;
681   GstDucatiVidEnc *self = GST_DUCATIVIDENC (enc);
683   switch (GST_EVENT_TYPE (event)) {
684     case GST_EVENT_CROP:
685       gst_event_parse_crop (event, &self->rect.y, &self->rect.x,
686           &self->rect.w, &self->rect.h);
687       GST_INFO_OBJECT (self, "got crop event top %d left %d %dx%d",
688           self->rect.x, self->rect.y, self->rect.w, self->rect.h);
689       handled = TRUE;
690       break;
691     default:
692       break;
693   }
695   return handled;
698 static GstDucatiBufferPriv *
699 get_buffer_priv (GstDucatiVidEnc * self, GstBuffer * buf,
700     gint stride, gint height)
702   GstDucatiBufferPriv *priv = gst_ducati_buffer_priv_get (buf);
703   if (!priv) {
704     GstVideoFormat format = GST_VIDEO_FORMAT_NV12;
705     GstDmaBuf *dmabuf = gst_buffer_get_dma_buf (buf);
707     /* if it isn't a dmabuf buffer that we can import, then there
708      * is nothing we can do with it:
709      */
710     if (!dmabuf) {
711       GST_DEBUG_OBJECT (self, "not importing non dmabuf buffer");
712       return NULL;
713     }
715     priv = gst_ducati_buffer_priv_new ();
716     priv->bo = omap_bo_from_dmabuf (self->device, gst_dma_buf_get_fd (dmabuf));
718     priv->uv_offset = gst_video_format_get_component_offset (format,
719         1, stride, height);
720     priv->size = gst_video_format_get_size (format, stride, height);
722     gst_ducati_buffer_priv_set (buf, priv);
723   }
724   return priv;