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 "gstducatih264enc.h"
30 #include <string.h>
32 #include <math.h>
34 #define GST_CAT_DEFAULT gst_ducati_debug
36 #define DEFAULT_PROFILE GST_DUCATI_H264ENC_PROFILE_HIGH
37 #define DEFAULT_LEVEL GST_DUCATI_H264ENC_LEVEL_40
38 #define DEFAULT_BITRATE 2048
39 #define DEFAULT_RATE_PRESET GST_DUCATI_H264ENC_RATE_PRESET_LOW_DELAY
41 #define GST_TYPE_DUCATI_H264ENC_PROFILE (gst_ducati_h264enc_profile_get_type ())
42 #define GST_TYPE_DUCATI_H264ENC_LEVEL (gst_ducati_h264enc_level_get_type ())
43 #define GST_TYPE_DUCATI_H264ENC_RATE_PRESET (gst_ducati_h264enc_rate_preset_get_type ())
46 enum
47 {
48 LAST_SIGNAL
49 };
51 enum
52 {
53 PROP_0,
54 PROP_PROFILE,
55 PROP_LEVEL,
56 PROP_BITRATE,
57 PROP_RATE_PRESET
58 };
60 static void gst_ducati_h264enc_set_property (GObject * object, guint prop_id,
61 const GValue * value, GParamSpec * pspec);
62 static void gst_ducati_h264enc_get_property (GObject * object, guint prop_id,
63 GValue * value, GParamSpec * pspec);
65 static gboolean gst_ducati_h264enc_set_format (GstBaseVideoEncoder *
66 base_video_encoder, GstVideoState * state);
67 static gboolean gst_ducati_h264enc_start (GstBaseVideoEncoder *
68 base_video_encoder);
69 static gboolean gst_ducati_h264enc_stop (GstBaseVideoEncoder *
70 base_video_encoder);
71 static GstFlowReturn gst_ducati_h264enc_finish (GstBaseVideoEncoder *
72 base_video_encoder);
73 static GstFlowReturn gst_ducati_h264enc_handle_frame (GstBaseVideoEncoder *
74 base_video_encoder, GstVideoFrame * frame);
76 static GstStaticPadTemplate gst_ducati_h264enc_sink_template =
77 GST_STATIC_PAD_TEMPLATE ("sink",
78 GST_PAD_SINK,
79 GST_PAD_ALWAYS,
80 GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("NV12"))
81 );
83 static GstStaticPadTemplate gst_ducati_h264enc_src_template =
84 GST_STATIC_PAD_TEMPLATE ("src",
85 GST_PAD_SRC,
86 GST_PAD_ALWAYS,
87 GST_STATIC_CAPS ("video/x-h264")
88 );
90 GST_BOILERPLATE (GstDucatiH264Enc, gst_ducati_h264enc, GstBaseVideoEncoder,
91 GST_TYPE_BASE_VIDEO_ENCODER);
94 /* the values for the following enums are taken from the codec */
96 enum
97 {
98 GST_DUCATI_H264ENC_PROFILE_BASELINE = 66, /**< BaseLine Profile */
99 GST_DUCATI_H264ENC_PROFILE_MAIN = 77, /**< Main Profile */
100 GST_DUCATI_H264ENC_PROFILE_EXTENDED = 88, /**< Extended Profile */
101 GST_DUCATI_H264ENC_PROFILE_HIGH = 100, /**< High Profile */
102 GST_DUCATI_H264ENC_PROFILE_HIGH_10 = 110, /**< High 10 Profile */
103 GST_DUCATI_H264ENC_PROFILE_HIGH_422 = 122 /**< High 4:2:2 Profile */
104 };
106 enum
107 {
108 GST_DUCATI_H264ENC_LEVEL_10 = 10, /**< Level 1.0 */
109 GST_DUCATI_H264ENC_LEVEL_1b = 9, /**< Level 1.b */
110 GST_DUCATI_H264ENC_LEVEL_11 = 11, /**< Level 1.1 */
111 GST_DUCATI_H264ENC_LEVEL_12 = 12, /**< Level 1.2 */
112 GST_DUCATI_H264ENC_LEVEL_13 = 13, /**< Level 1.3 */
113 GST_DUCATI_H264ENC_LEVEL_20 = 20, /**< Level 2.0 */
114 GST_DUCATI_H264ENC_LEVEL_21 = 21, /**< Level 2.1 */
115 GST_DUCATI_H264ENC_LEVEL_22 = 22, /**< Level 2.2 */
116 GST_DUCATI_H264ENC_LEVEL_30 = 30, /**< Level 3.0 */
117 GST_DUCATI_H264ENC_LEVEL_31 = 31, /**< Level 3.1 */
118 GST_DUCATI_H264ENC_LEVEL_32 = 32, /**< Level 3.2 */
119 GST_DUCATI_H264ENC_LEVEL_40 = 40, /**< Level 4.0 */
120 GST_DUCATI_H264ENC_LEVEL_41 = 41, /**< Level 4.1 */
121 GST_DUCATI_H264ENC_LEVEL_42 = 42, /**< Level 4.2 */
122 GST_DUCATI_H264ENC_LEVEL_50 = 50, /**< Level 5.0 */
123 GST_DUCATI_H264ENC_LEVEL_51 = 51 /**< Level 5.1 */
124 };
126 enum
127 {
128 GST_DUCATI_H264ENC_RATE_PRESET_LOW_DELAY = 1, /**< CBR rate control for video conferencing. */
129 GST_DUCATI_H264ENC_RATE_PRESET_STORAGE = 2, /**< VBR rate control for local storage (DVD)
130 * recording.
131 */
132 GST_DUCATI_H264ENC_RATE_PRESET_TWOPASS = 3, /**< Two pass rate control for non real time
133 * applications.
134 */
135 GST_DUCATI_H264ENC_RATE_PRESET_NONE = 4, /**< No configurable video rate control
136 * mechanism.
137 */
138 GST_DUCATI_H264ENC_RATE_PRESET_USER_DEFINED = 5,/**< User defined configuration using extended
139 * parameters.
140 */
141 };
143 static GType
144 gst_ducati_h264enc_profile_get_type (void)
145 {
146 static GType type = 0;
148 if (!type) {
149 static const GEnumValue vals[] = {
150 {GST_DUCATI_H264ENC_PROFILE_BASELINE, "Base Profile", "baseline"},
151 {GST_DUCATI_H264ENC_PROFILE_MAIN, "Main Profile", "main"},
152 {GST_DUCATI_H264ENC_PROFILE_EXTENDED, "Extended Profile", "extended"},
153 {GST_DUCATI_H264ENC_PROFILE_HIGH, "High Profile", "high"},
154 {GST_DUCATI_H264ENC_PROFILE_HIGH_10, "High 10 Profile", "high-10"},
155 {GST_DUCATI_H264ENC_PROFILE_HIGH_422, "High 4:2:2 Profile", "high-422"},
156 {0, NULL, NULL},
157 };
159 type = g_enum_register_static ("GstDucatiH264EncProfile", vals);
160 }
162 return type;
163 }
165 static GType
166 gst_ducati_h264enc_level_get_type (void)
167 {
168 static GType type = 0;
170 if (!type) {
171 static const GEnumValue vals[] = {
172 {GST_DUCATI_H264ENC_LEVEL_10, "Level 1", "level-1"},
173 {GST_DUCATI_H264ENC_LEVEL_1b, "Level 1b", "level-1b"},
174 {GST_DUCATI_H264ENC_LEVEL_11, "Level 11", "level-11"},
175 {GST_DUCATI_H264ENC_LEVEL_12, "Level 12", "level-12"},
176 {GST_DUCATI_H264ENC_LEVEL_13, "Level 13", "level-13"},
177 {GST_DUCATI_H264ENC_LEVEL_20, "Level 2", "level-2"},
178 {GST_DUCATI_H264ENC_LEVEL_21, "Level 21", "level-21"},
179 {GST_DUCATI_H264ENC_LEVEL_22, "Level 22", "level-22"},
180 {GST_DUCATI_H264ENC_LEVEL_30, "Level 3", "level-3"},
181 {GST_DUCATI_H264ENC_LEVEL_31, "Level 31", "level-31"},
182 {GST_DUCATI_H264ENC_LEVEL_32, "Level 32", "level-32"},
183 {GST_DUCATI_H264ENC_LEVEL_40, "Level 4", "level-4"},
184 {GST_DUCATI_H264ENC_LEVEL_41, "Level 41", "level-41"},
185 {GST_DUCATI_H264ENC_LEVEL_42, "Level 42", "level-42"},
186 {GST_DUCATI_H264ENC_LEVEL_50, "Level 5", "level-5"},
187 {GST_DUCATI_H264ENC_LEVEL_51, "Level 51", "level-51"},
188 {0, NULL, NULL},
189 };
191 type = g_enum_register_static ("GstDucatiH264EncLevel", vals);
192 }
194 return type;
195 }
197 static GType
198 gst_ducati_h264enc_rate_preset_get_type (void)
199 {
200 static GType type = 0;
202 if (!type) {
203 static const GEnumValue vals[] = {
204 {GST_DUCATI_H264ENC_RATE_PRESET_LOW_DELAY, "Low Delay", "low-delay"},
205 {GST_DUCATI_H264ENC_RATE_PRESET_STORAGE, "Storage", "storage"},
206 {GST_DUCATI_H264ENC_RATE_PRESET_TWOPASS, "Two-Pass", "two-pass"},
207 {0, NULL, NULL},
208 };
210 type = g_enum_register_static ("GstDucatiH264EncRatePreset", vals);
211 }
213 return type;
214 }
216 static void
217 gst_ducati_h264enc_base_init (gpointer g_class)
218 {
220 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
222 gst_element_class_add_pad_template (element_class,
223 gst_static_pad_template_get (&gst_ducati_h264enc_src_template));
224 gst_element_class_add_pad_template (element_class,
225 gst_static_pad_template_get (&gst_ducati_h264enc_sink_template));
227 gst_element_class_set_details_simple (element_class, "H264 Encoder",
228 "Codec/Encoder/Video",
229 "Encode raw video into H264 stream",
230 "Alessandro Decina <alessandro.decina@collabora.com>");
231 }
233 static void
234 gst_ducati_h264enc_class_init (GstDucatiH264EncClass * klass)
235 {
236 GObjectClass *gobject_class;
237 GstBaseVideoEncoderClass *basevideocoder_class;
239 gobject_class = G_OBJECT_CLASS (klass);
240 basevideocoder_class = GST_BASE_VIDEO_ENCODER_CLASS (klass);
242 gobject_class->set_property = gst_ducati_h264enc_set_property;
243 gobject_class->get_property = gst_ducati_h264enc_get_property;
245 basevideocoder_class->set_format =
246 GST_DEBUG_FUNCPTR (gst_ducati_h264enc_set_format);
247 basevideocoder_class->start = GST_DEBUG_FUNCPTR (gst_ducati_h264enc_start);
248 basevideocoder_class->stop = GST_DEBUG_FUNCPTR (gst_ducati_h264enc_stop);
249 basevideocoder_class->finish = GST_DEBUG_FUNCPTR (gst_ducati_h264enc_finish);
250 basevideocoder_class->handle_frame =
251 GST_DEBUG_FUNCPTR (gst_ducati_h264enc_handle_frame);
253 g_object_class_install_property (gobject_class, PROP_PROFILE,
254 g_param_spec_enum ("profile", "H.264 Profile", "H.264 Profile",
255 GST_TYPE_DUCATI_H264ENC_PROFILE, DEFAULT_PROFILE, G_PARAM_READWRITE));
257 g_object_class_install_property (gobject_class, PROP_LEVEL,
258 g_param_spec_enum ("level", "H.264 Level", "H.264 Level",
259 GST_TYPE_DUCATI_H264ENC_LEVEL, DEFAULT_LEVEL, G_PARAM_READWRITE));
261 g_object_class_install_property (gobject_class, PROP_BITRATE,
262 g_param_spec_int ("bitrate", "Bitrate", "Bitrate in kbit/sec", -1,
263 100 * 1024, DEFAULT_BITRATE, G_PARAM_READWRITE));
265 g_object_class_install_property (gobject_class, PROP_RATE_PRESET,
266 g_param_spec_enum ("rate-preset", "H.264 Rate Control",
267 "H.264 Rate Control",
268 GST_TYPE_DUCATI_H264ENC_RATE_PRESET, DEFAULT_RATE_PRESET,
269 G_PARAM_READWRITE));
270 }
272 static void
273 gst_ducati_h264enc_init (GstDucatiH264Enc * self, GstDucatiH264EncClass * klass)
274 {
275 GST_DEBUG ("gst_ducati_h264enc_init");
277 self->engine = NULL;
278 self->codec = NULL;
279 self->params = NULL;
280 self->status = NULL;
281 self->inBufs = NULL;
282 self->outBufs = NULL;
283 self->inArgs = NULL;
284 self->outArgs = NULL;
285 self->configure = FALSE;
286 self->input_pool = NULL;
287 self->output_pool = NULL;
289 self->profile = DEFAULT_PROFILE;
290 self->level = DEFAULT_LEVEL;
291 self->bitrate = DEFAULT_BITRATE * 1000;
292 self->rate_preset = DEFAULT_RATE_PRESET;
293 }
295 static gboolean
296 gst_ducati_h264enc_set_format (GstBaseVideoEncoder * base_video_encoder,
297 GstVideoState * state)
298 {
299 GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder);
301 self->configure = TRUE;
303 return TRUE;
304 }
306 static void
307 gst_ducati_h264enc_set_property (GObject * object, guint prop_id,
308 const GValue * value, GParamSpec * pspec)
309 {
310 GstDucatiH264Enc *self = GST_DUCATIH264ENC (object);
312 g_return_if_fail (GST_IS_DUCATIH264ENC (object));
313 self = GST_DUCATIH264ENC (object);
315 switch (prop_id) {
316 case PROP_PROFILE:
317 self->profile = g_value_get_enum (value);
318 break;
319 case PROP_LEVEL:
320 self->level = g_value_get_enum (value);
321 break;
322 case PROP_BITRATE:
323 self->bitrate = g_value_get_int (value) * 1000;
324 break;
325 case PROP_RATE_PRESET:
326 self->rate_preset = g_value_get_enum (value);
327 break;
328 default:
329 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
330 }
331 }
333 static void
334 gst_ducati_h264enc_get_property (GObject * object, guint prop_id,
335 GValue * value, GParamSpec * pspec)
336 {
337 GstDucatiH264Enc *self = GST_DUCATIH264ENC (object);
339 g_return_if_fail (GST_IS_DUCATIH264ENC (object));
340 self = GST_DUCATIH264ENC (object);
342 switch (prop_id) {
343 case PROP_PROFILE:
344 g_value_set_enum (value, self->profile);
345 break;
346 case PROP_LEVEL:
347 g_value_set_enum (value, self->level);
348 break;
349 case PROP_BITRATE:
350 g_value_set_int (value, self->bitrate / 1000);
351 break;
352 case PROP_RATE_PRESET:
353 g_value_set_enum (value, self->rate_preset);
354 break;
355 default:
356 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
357 }
358 }
360 static gboolean
361 gst_ducati_h264enc_configure (GstDucatiH264Enc * self)
362 {
363 int err, i, max_out_size = 0;
364 VIDENC2_DynamicParams *baseDynParams;
365 VIDENC2_Params *baseParams;
366 IH264ENC_Params *params;
367 IH264ENC_DynamicParams *dynParams;
368 const GstVideoState *state;
370 state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (self));
372 params = self->params;
373 baseParams = (VIDENC2_Params *) self->params;
374 baseParams->encodingPreset = 0x03; /* ??? */
375 baseParams->rateControlPreset = self->rate_preset;
376 baseParams->maxHeight = state->height;
377 baseParams->maxWidth = state->width;
378 baseParams->dataEndianness = XDM_BYTE;
379 baseParams->maxInterFrameInterval = 1;
380 baseParams->maxBitRate = self->bitrate;
381 baseParams->minBitRate = 0;
382 baseParams->inputChromaFormat = XDM_YUV_420SP;
383 baseParams->inputContentType = IVIDEO_PROGRESSIVE;
384 baseParams->operatingMode = IVIDEO_ENCODE_ONLY;
385 baseParams->profile = self->profile;
386 baseParams->level = self->level;
387 baseParams->inputDataMode = IVIDEO_ENTIREFRAME;
388 baseParams->outputDataMode = IVIDEO_ENTIREFRAME;
389 baseParams->numInputDataUnits = 1;
390 baseParams->numOutputDataUnits = 1;
391 for (i = 0; i < IVIDEO_MAX_NUM_METADATA_PLANES; i++) {
392 baseParams->metadataType[i] = IVIDEO_METADATAPLANE_NONE;
393 }
395 params->rateControlParams.rateControlParamsPreset =
396 IH264_RATECONTROLPARAMS_DEFAULT;
397 params->interCodingParams.interCodingPreset = IH264_INTERCODING_DEFAULT;
398 params->intraCodingParams.intraCodingPreset = IH264_INTRACODING_DEFAULT;
399 params->nalUnitControlParams.naluControlPreset = IH264_NALU_CONTROL_DEFAULT;
400 params->fmoCodingParams.fmoCodingPreset = IH264_FMOCODING_DEFAULT;
401 params->maxIntraFrameInterval = 0x7fffffff;
403 if (self->codec == NULL) {
404 self->codec = VIDENC2_create (self->engine,
405 (String) "ivahd_h264enc", baseParams);
406 if (self->codec == NULL) {
407 GST_ERROR_OBJECT (self, "couldn't create codec");
408 return FALSE;
409 }
410 }
412 dynParams = self->dynParams;
413 baseDynParams = (VIDENC2_DynamicParams *) self->dynParams;
414 baseDynParams->size = sizeof (IH264ENC_DynamicParams);
415 baseDynParams = &dynParams->videnc2DynamicParams;
417 baseDynParams->refFrameRate =
418 gst_util_uint64_scale (1000, state->fps_n, state->fps_d);
419 baseDynParams->targetFrameRate = baseDynParams->refFrameRate;
420 baseDynParams->inputWidth = state->width;
421 baseDynParams->inputHeight = state->height;
422 baseDynParams->targetBitRate = self->bitrate;
423 baseDynParams->intraFrameInterval = 15;
424 baseDynParams->captureWidth = baseDynParams->inputWidth;
425 baseDynParams->forceFrame = IVIDEO_NA_FRAME;
426 baseDynParams->interFrameInterval = 1;
427 baseDynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL;
428 baseDynParams->sampleAspectRatioHeight = 1;
429 baseDynParams->sampleAspectRatioWidth = 1;
430 baseDynParams->generateHeader = XDM_ENCODE_AU;
431 baseDynParams->ignoreOutbufSizeFlag = 1;
432 baseDynParams->lateAcquireArg = -1;
434 dynParams->rateControlParams.rateControlParamsPreset = 2;
435 dynParams->interCodingParams.interCodingPreset = 2;
437 err = VIDENC2_control (self->codec,
438 XDM_SETPARAMS, baseDynParams, (IVIDENC2_Status *) self->status);
439 if (err) {
440 GST_ERROR_OBJECT (self, "XDM_SETPARAMS err=%d, extendedError=%08x",
441 err, self->status->videnc2Status.extendedError);
443 return FALSE;
444 }
446 err = VIDENC2_control (self->codec,
447 XDM_GETBUFINFO, baseDynParams, (IVIDENC2_Status *) self->status);
448 if (err) {
449 GST_ERROR_OBJECT (self, "XDM_GETBUFINFO err=%d, extendedError=%08x",
450 err, self->status->videnc2Status.extendedError);
452 return FALSE;
453 }
455 self->inBufs->chromaFormat = XDM_YUV_420SP;
456 self->inBufs->numPlanes = 2;
458 self->outBufs->numBufs = self->status->videnc2Status.bufInfo.minNumOutBufs;
459 for (i = 0; i < self->outBufs->numBufs; i++) {
460 int size = self->status->videnc2Status.bufInfo.minOutBufSize[i].bytes;
461 if (size > max_out_size)
462 max_out_size = size;
463 }
465 g_assert (self->input_pool == NULL);
466 self->input_pool =
467 gst_ducati_bufferpool_new (GST_ELEMENT (self), NULL,
468 state->bytes_per_picture);
470 g_assert (self->output_pool == NULL);
471 self->output_pool =
472 gst_ducati_bufferpool_new (GST_ELEMENT (self), NULL, max_out_size);
474 GST_INFO_OBJECT (self, "configured");
476 self->configure = FALSE;
478 return TRUE;
479 }
481 static gboolean
482 gst_ducati_h264enc_alloc_dce (GstDucatiH264Enc * self)
483 {
484 self->engine = Engine_open ((String) "ivahd_vidsvr", NULL, NULL);
485 if (self->engine == NULL) {
486 GST_ERROR_OBJECT (self, "couldn't open engine");
487 return FALSE;
488 }
490 self->params = dce_alloc (sizeof (IH264ENC_Params));
491 memset (self->params, 0, sizeof (IH264ENC_Params));
492 self->params->videnc2Params.size = sizeof (IH264ENC_Params);
494 self->codec = NULL;
496 self->dynParams = dce_alloc (sizeof (IH264ENC_DynamicParams));
497 memset (self->dynParams, 0, sizeof (IH264ENC_DynamicParams));
498 self->dynParams->videnc2DynamicParams.size = sizeof (IH264ENC_DynamicParams);
500 self->status = dce_alloc (sizeof (IH264ENC_Status));
501 memset (self->status, 0, sizeof (IH264ENC_Status));
502 self->status->videnc2Status.size = sizeof (IH264ENC_Status);
504 self->inBufs = dce_alloc (sizeof (IVIDEO2_BufDesc));
505 memset (self->inBufs, 0, sizeof (IVIDEO2_BufDesc));
507 self->outBufs = dce_alloc (sizeof (XDM2_BufDesc));
508 memset (self->outBufs, 0, sizeof (XDM2_BufDesc));
510 self->inArgs = dce_alloc (sizeof (IVIDENC2_InArgs));
511 memset (self->inArgs, 0, sizeof (IVIDENC2_InArgs));
512 self->inArgs->size = sizeof (IVIDENC2_InArgs);
514 self->outArgs = dce_alloc (sizeof (IVIDENC2_OutArgs));
515 memset (self->outArgs, 0, sizeof (IVIDENC2_OutArgs));
516 self->outArgs->size = sizeof (IVIDENC2_OutArgs);
518 GST_INFO_OBJECT (self, "started");
520 return TRUE;
521 }
523 static gboolean
524 gst_ducati_h264enc_free_dce (GstDucatiH264Enc * self)
525 {
526 if (self->params) {
527 dce_free (self->params);
528 self->params = NULL;
529 }
531 if (self->dynParams) {
532 dce_free (self->dynParams);
533 self->dynParams = NULL;
534 }
536 if (self->inArgs) {
537 dce_free (self->inArgs);
538 self->inArgs = NULL;
539 }
541 if (self->outArgs) {
542 dce_free (self->outArgs);
543 self->outArgs = NULL;
544 }
546 if (self->status) {
547 dce_free (self->status);
548 self->status = NULL;
549 }
551 if (self->inBufs) {
552 dce_free (self->inBufs);
553 self->inBufs = NULL;
554 }
556 if (self->outBufs) {
557 dce_free (self->outBufs);
558 self->inBufs = NULL;
559 }
561 if (self->codec) {
562 VIDENC2_delete (self->codec);
563 self->codec = NULL;
564 }
566 if (self->engine) {
567 Engine_close (self->engine);
568 self->engine = NULL;
569 }
571 return TRUE;
572 }
574 static gboolean
575 gst_ducati_h264enc_start (GstBaseVideoEncoder * base_video_encoder)
576 {
577 GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder);
579 if (!gst_ducati_h264enc_alloc_dce (self))
580 goto fail;
582 return TRUE;
584 fail:
585 gst_ducati_h264enc_free_dce (self);
586 return FALSE;
587 }
589 static gboolean
590 gst_ducati_h264enc_stop (GstBaseVideoEncoder * base_video_encoder)
591 {
592 GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder);
594 gst_ducati_h264enc_free_dce (self);
596 if (self->input_pool) {
597 gst_ducati_bufferpool_destroy (self->input_pool);
598 self->input_pool = NULL;
599 }
601 if (self->output_pool) {
602 gst_ducati_bufferpool_destroy (self->output_pool);
603 self->output_pool = NULL;
604 }
606 return TRUE;
607 }
609 static GstFlowReturn
610 gst_ducati_h264enc_finish (GstBaseVideoEncoder * base_video_encoder)
611 {
612 GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder);
614 GST_DEBUG_OBJECT (self, "finish");
616 return GST_FLOW_OK;
617 }
619 static GstFlowReturn
620 gst_ducati_h264enc_handle_frame (GstBaseVideoEncoder * base_video_encoder,
621 GstVideoFrame * frame)
622 {
623 GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder);
624 GstBuffer *inbuf, *outbuf;
625 guint8 *y_vaddr, *uv_vaddr;
626 SSPtr y_paddr, uv_paddr, outbuf_paddr;
627 XDAS_Int32 err;
628 const GstVideoState *state;
629 int i;
631 state = gst_base_video_encoder_get_state (base_video_encoder);
633 if (G_UNLIKELY (self->configure)) {
634 if (!gst_ducati_h264enc_configure (self)) {
635 GST_DEBUG_OBJECT (self, "configure failed");
636 GST_ELEMENT_ERROR (self, STREAM, ENCODE, (NULL), (NULL));
638 return GST_FLOW_ERROR;
639 }
640 }
642 inbuf = GST_BUFFER (gst_ducati_bufferpool_get (self->input_pool, NULL));
643 memcpy (GST_BUFFER_DATA (inbuf), GST_BUFFER_DATA (frame->sink_buffer),
644 GST_BUFFER_SIZE (frame->sink_buffer));
645 outbuf = GST_BUFFER (gst_ducati_bufferpool_get (self->output_pool, NULL));
647 y_vaddr = GST_BUFFER_DATA (inbuf);
648 uv_vaddr = y_vaddr + gst_video_format_get_component_offset (state->format,
649 1, state->width, state->height);
651 y_paddr = TilerMem_VirtToPhys (y_vaddr);
652 uv_paddr = TilerMem_VirtToPhys (uv_vaddr);
654 outbuf_paddr = TilerMem_VirtToPhys (GST_BUFFER_DATA (outbuf));
656 self->inBufs->planeDesc[0].buf = (XDAS_Int8 *) y_paddr;
657 self->inBufs->planeDesc[0].memType = XDM_MEMTYPE_TILEDPAGE;
658 self->inBufs->planeDesc[0].bufSize.tileMem.width = state->width;
659 self->inBufs->planeDesc[0].bufSize.tileMem.height = state->height;
660 self->inBufs->planeDesc[1].buf = (XDAS_Int8 *) uv_paddr;
661 self->inBufs->planeDesc[1].memType = XDM_MEMTYPE_TILEDPAGE;
662 self->inBufs->planeDesc[1].bufSize.tileMem.width = state->width;
663 self->inBufs->planeDesc[1].bufSize.tileMem.height = state->height / 2;
664 self->inBufs->imagePitch[0] = state->width;
665 self->inBufs->imagePitch[1] = state->width;
666 self->inBufs->imageRegion.bottomRight.x = state->width;
667 self->inBufs->activeFrameRegion.bottomRight.x = state->width;
668 self->inBufs->imageRegion.bottomRight.y = state->height;
669 self->inBufs->activeFrameRegion.bottomRight.y = state->height;
670 self->inBufs->topFieldFirstFlag = TRUE;
672 self->outBufs->numBufs = 1;
673 self->outBufs->descs[0].buf = (XDAS_Int8 *) outbuf_paddr;
674 self->outBufs->descs[0].bufSize.bytes = GST_BUFFER_SIZE (outbuf);
676 self->inArgs->inputID = GPOINTER_TO_INT (inbuf);
678 err = VIDENC2_process (self->codec, self->inBufs, self->outBufs,
679 self->inArgs, self->outArgs);
680 if (err) {
681 GST_WARNING_OBJECT (self, "process failed: err=%d, extendedError=%08x",
682 err, self->status->videnc2Status.extendedError);
684 err = VIDENC2_control (self->codec,
685 XDM_GETSTATUS, (IVIDENC2_DynamicParams *) self->dynParams,
686 (IVIDENC2_Status *) self->status);
688 GST_WARNING_OBJECT (self, "XDM_GETSTATUS: err=%d, extendedError=%08x",
689 err, self->status->videnc2Status.extendedError);
691 return GST_FLOW_ERROR;
692 }
694 frame->src_buffer = gst_buffer_new_and_alloc (self->outArgs->bytesGenerated);
695 memcpy (GST_BUFFER_DATA (frame->src_buffer),
696 GST_BUFFER_DATA (outbuf), self->outArgs->bytesGenerated);
698 gst_buffer_unref (outbuf);
700 for (i = 0; self->outArgs->freeBufID[i]; i++) {
701 GstBuffer *buf = (GstBuffer *) self->outArgs->freeBufID[i];
703 GST_LOG_OBJECT (self, "free buffer: %p", buf);
704 gst_buffer_unref (buf);
705 }
707 return gst_base_video_encoder_finish_frame (base_video_encoder, frame);
708 }