1 /*
2 INTEL CONFIDENTIAL
3 Copyright 2009 Intel Corporation All Rights Reserved.
4 The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel’s prior express written permission.
5
6 No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
7 */
8
9 #include <va/va.h> /* libVA */
10 #include <X11/Xlib.h>
11 #include <va/va_x11.h>
12
13 #include "mixvideolog.h"
14
15 #include "mixdisplayx11.h"
16 #include "mixvideoframe.h"
17
18 #include "mixframemanager.h"
19 #include "mixvideorenderparams.h"
20 #include "mixvideorenderparams_internal.h"
21
22 #include "mixvideoformat.h"
23 #include "mixvideoformat_vc1.h"
24 #include "mixvideoformat_h264.h"
25 #include "mixvideoformat_mp42.h"
26
27 #include "mixvideoconfigparamsdec_vc1.h"
28 #include "mixvideoconfigparamsdec_h264.h"
29 #include "mixvideoconfigparamsdec_mp42.h"
30
31 #include "mixvideoformatenc.h"
32 #include "mixvideoformatenc_h264.h"
33 #include "mixvideoformatenc_mpeg4.h"
34 #include "mixvideoformatenc_preview.h"
35
36 #include "mixvideoconfigparamsenc_h264.h"
37 #include "mixvideoconfigparamsenc_mpeg4.h"
38 #include "mixvideoconfigparamsenc_preview.h"
39
40
41 #include "mixvideo.h"
42 #include "mixvideo_private.h"
43
44 #define USE_OPAQUE_POINTER
45
46 #ifdef USE_OPAQUE_POINTER
47 #define MIX_VIDEO_PRIVATE(mix) (MixVideoPrivate *)(mix->context)
48 #else
49 #define MIX_VIDEO_PRIVATE(mix) MIX_VIDEO_GET_PRIVATE(mix)
50 #endif
51
52 #define CHECK_INIT(mix, priv) \
53 if (!mix) { \
54 return MIX_RESULT_NULL_PTR; \
55 } \
56 if (!MIX_IS_VIDEO(mix)) { \
57 LOG_E( "Not MixVideo\n"); \
58 return MIX_RESULT_INVALID_PARAM; \
59 } \
60 priv = MIX_VIDEO_PRIVATE(mix); \
61 if (!priv->initialized) { \
62 LOG_E( "Not initialized\n"); \
63 return MIX_RESULT_NOT_INIT; \
64 }
65
66 #define CHECK_INIT_CONFIG(mix, priv) \
67 CHECK_INIT(mix, priv); \
68 if (!priv->configured) { \
69 LOG_E( "Not configured\n"); \
70 return MIX_RESULT_NOT_CONFIGURED; \
71 }
72
73 /*
74 * default implementation of virtual methods
75 */
76
77 MIX_RESULT mix_video_get_version_default(MixVideo * mix, guint * major,
78 guint * minor);
79
80 MIX_RESULT mix_video_initialize_default(MixVideo * mix, MixCodecMode mode,
81 MixVideoInitParams * init_params, MixDrmParams * drm_init_params);
82
83 MIX_RESULT mix_video_deinitialize_default(MixVideo * mix);
84
85 MIX_RESULT mix_video_configure_default(MixVideo * mix,
86 MixVideoConfigParams * config_params, MixDrmParams * drm_config_params);
87
88 MIX_RESULT mix_video_get_config_default(MixVideo * mix,
89 MixVideoConfigParams ** config_params);
90
91 MIX_RESULT mix_video_decode_default(MixVideo * mix, MixBuffer * bufin[],
92 gint bufincnt, MixVideoDecodeParams * decode_params);
93
94 MIX_RESULT mix_video_get_frame_default(MixVideo * mix, MixVideoFrame ** frame);
95
96 MIX_RESULT mix_video_release_frame_default(MixVideo * mix,
97 MixVideoFrame * frame);
98
99 MIX_RESULT mix_video_render_default(MixVideo * mix,
100 MixVideoRenderParams * render_params, MixVideoFrame *frame);
101
102 MIX_RESULT mix_video_encode_default(MixVideo * mix, MixBuffer * bufin[],
103 gint bufincnt, MixIOVec * iovout[], gint iovoutcnt,
104 MixVideoEncodeParams * encode_params);
105
106 MIX_RESULT mix_video_flush_default(MixVideo * mix);
107
108 MIX_RESULT mix_video_eos_default(MixVideo * mix);
109
110 MIX_RESULT mix_video_get_state_default(MixVideo * mix, MixState * state);
111
112 MIX_RESULT mix_video_get_mixbuffer_default(MixVideo * mix, MixBuffer ** buf);
113
114 MIX_RESULT mix_video_release_mixbuffer_default(MixVideo * mix, MixBuffer * buf);
115
116 MIX_RESULT mix_video_get_max_coded_buffer_size_default (MixVideo * mix, guint *max_size);
117
118
119 static void mix_video_finalize(GObject * obj);
120 MIX_RESULT mix_video_configure_decode(MixVideo * mix,
121 MixVideoConfigParamsDec * config_params_dec,
122 MixDrmParams * drm_config_params);
123
124 MIX_RESULT mix_video_configure_encode(MixVideo * mix,
125 MixVideoConfigParamsEnc * config_params_enc,
126 MixDrmParams * drm_config_params);
127
128 G_DEFINE_TYPE( MixVideo, mix_video, G_TYPE_OBJECT);
129
mix_video_init(MixVideo * self)130 static void mix_video_init(MixVideo * self) {
131
132 MixVideoPrivate *priv = MIX_VIDEO_GET_PRIVATE(self);
133
134 #ifdef USE_OPAQUE_POINTER
135 self->context = priv;
136 #else
137 self->context = NULL;
138 #endif
139
140 /* private structure initialization */
141
142 mix_video_private_initialize(priv);
143 }
144
mix_video_class_init(MixVideoClass * klass)145 static void mix_video_class_init(MixVideoClass * klass) {
146 GObjectClass *gobject_class = (GObjectClass *) klass;
147
148 gobject_class->finalize = mix_video_finalize;
149
150 /* Register and allocate the space the private structure for this object */
151 g_type_class_add_private(gobject_class, sizeof(MixVideoPrivate));
152
153 klass->get_version_func = mix_video_get_version_default;
154 klass->initialize_func = mix_video_initialize_default;
155 klass->deinitialize_func = mix_video_deinitialize_default;
156 klass->configure_func = mix_video_configure_default;
157 klass->get_config_func = mix_video_get_config_default;
158 klass->decode_func = mix_video_decode_default;
159 klass->get_frame_func = mix_video_get_frame_default;
160 klass->release_frame_func = mix_video_release_frame_default;
161 klass->render_func = mix_video_render_default;
162 klass->encode_func = mix_video_encode_default;
163 klass->flush_func = mix_video_flush_default;
164 klass->eos_func = mix_video_eos_default;
165 klass->get_state_func = mix_video_get_state_default;
166 klass->get_mix_buffer_func = mix_video_get_mixbuffer_default;
167 klass->release_mix_buffer_func = mix_video_release_mixbuffer_default;
168 klass->get_max_coded_buffer_size_func = mix_video_get_max_coded_buffer_size_default;
169 }
170
mix_video_new(void)171 MixVideo *mix_video_new(void) {
172
173 MixVideo *ret = g_object_new(MIX_TYPE_VIDEO, NULL);
174
175 return ret;
176 }
177
mix_video_finalize(GObject * obj)178 void mix_video_finalize(GObject * obj) {
179
180 /* clean up here. */
181
182 MixVideo *mix = MIX_VIDEO(obj);
183 mix_video_deinitialize(mix);
184 }
185
186 MixVideo *
mix_video_ref(MixVideo * mix)187 mix_video_ref(MixVideo * mix) {
188 return (MixVideo *) g_object_ref(G_OBJECT(mix));
189 }
190
191 /* private methods */
192
193 #define MIXUNREF(obj, unref) if(obj) { unref(obj); obj = NULL; }
194
mix_video_private_initialize(MixVideoPrivate * priv)195 void mix_video_private_initialize(MixVideoPrivate* priv) {
196 priv->objlock = NULL;
197 priv->initialized = FALSE;
198 priv->configured = FALSE;
199
200 /* libVA */
201 priv->va_display = NULL;
202 priv->va_major_version = -1;
203 priv->va_major_version = -1;
204
205 /* mix objects */
206 priv->frame_manager = NULL;
207 priv->video_format = NULL;
208 priv->video_format_enc = NULL; //for encoding
209 priv->surface_pool = NULL;
210 priv->buffer_pool = NULL;
211
212 priv->codec_mode = MIX_CODEC_MODE_DECODE;
213 priv->init_params = NULL;
214 priv->drm_params = NULL;
215 priv->config_params = NULL;
216 }
217
mix_video_private_cleanup(MixVideoPrivate * priv)218 void mix_video_private_cleanup(MixVideoPrivate* priv) {
219
220 VAStatus va_status;
221
222 if (!priv) {
223 return;
224 }
225
226 if (priv->video_format_enc) {
227 mix_videofmtenc_deinitialize(priv->video_format_enc);
228 }
229
230 MIXUNREF(priv->frame_manager, mix_framemanager_unref)
231 MIXUNREF(priv->video_format, mix_videoformat_unref)
232 MIXUNREF(priv->video_format_enc, mix_videoformatenc_unref)
233 //for encoding
234 MIXUNREF(priv->buffer_pool, mix_bufferpool_unref)
235 MIXUNREF(priv->surface_pool, mix_surfacepool_unref)
236 /* MIXUNREF(priv->init_params, mix_videoinitparams_unref) */
237 MIXUNREF(priv->drm_params, mix_drmparams_unref)
238 MIXUNREF(priv->config_params, mix_videoconfigparams_unref)
239
240 /* terminate libVA */
241 if (priv->va_display) {
242 va_status = vaTerminate(priv->va_display);
243 LOG_V( "vaTerminate\n");
244 if (va_status != VA_STATUS_SUCCESS) {
245 LOG_W( "Failed vaTerminate\n");
246 } else {
247 priv->va_display = NULL;
248 }
249 }
250
251 MIXUNREF(priv->init_params, mix_videoinitparams_unref)
252
253 priv->va_major_version = -1;
254 priv->va_major_version = -1;
255
256 if (priv->objlock) {
257 g_mutex_free(priv->objlock);
258 priv->objlock = NULL;
259 }
260
261 priv->codec_mode = MIX_CODEC_MODE_DECODE;
262 priv->initialized = FALSE;
263 priv->configured = FALSE;
264 }
265
266 /* The following methods are defined in MI-X API */
267
mix_video_get_version_default(MixVideo * mix,guint * major,guint * minor)268 MIX_RESULT mix_video_get_version_default(MixVideo * mix, guint * major,
269 guint * minor) {
270 if (!mix || !major || !minor) {
271 return MIX_RESULT_NULL_PTR;
272 }
273
274 if (!MIX_IS_VIDEO(mix)) {
275 return MIX_RESULT_INVALID_PARAM;
276 }
277
278 *major = MIXVIDEO_CURRENT - MIXVIDEO_AGE;
279 *minor = MIXVIDEO_AGE;
280
281 return MIX_RESULT_SUCCESS;
282 }
283
mix_video_initialize_default(MixVideo * mix,MixCodecMode mode,MixVideoInitParams * init_params,MixDrmParams * drm_init_params)284 MIX_RESULT mix_video_initialize_default(MixVideo * mix, MixCodecMode mode,
285 MixVideoInitParams * init_params, MixDrmParams * drm_init_params) {
286
287 MIX_RESULT ret = MIX_RESULT_FAIL;
288 MixVideoPrivate *priv = NULL;
289 MixDisplay *mix_display = NULL;
290
291 LOG_V( "Begin\n");
292
293 if (!mix || !init_params) {
294 LOG_E( "!mix || !init_params\n");
295 return MIX_RESULT_NULL_PTR;
296 }
297
298 if (mode >= MIX_CODEC_MODE_LAST) {
299 LOG_E("mode >= MIX_CODEC_MODE_LAST\n");
300 return MIX_RESULT_INVALID_PARAM;
301 }
302
303 #if 0 //we have encoding support
304 /* TODO: We need to support encoding in the future */
305 if (mode == MIX_CODEC_MODE_ENCODE) {
306 LOG_E("mode == MIX_CODEC_MODE_ENCODE\n");
307 return MIX_RESULT_NOTIMPL;
308 }
309 #endif
310
311 if (!MIX_IS_VIDEO(mix)) {
312 LOG_E( "!MIX_IS_VIDEO(mix)\n");
313 return MIX_RESULT_INVALID_PARAM;
314 }
315
316 if (!MIX_IS_VIDEOINITPARAMS(init_params)) {
317 LOG_E("!MIX_IS_VIDEOINITPARAMS(init_params\n");
318 return MIX_RESULT_INVALID_PARAM;
319 }
320
321 priv = MIX_VIDEO_PRIVATE(mix);
322
323 if (priv->initialized) {
324 LOG_W( "priv->initialized\n");
325 return MIX_RESULT_ALREADY_INIT;
326 }
327
328 /*
329 * Init thread before any threads/sync object are used.
330 * TODO: If thread is not supported, what we do?
331 */
332
333 if (!g_thread_supported()) {
334 LOG_W("!g_thread_supported()\n");
335 g_thread_init(NULL);
336 }
337
338 /* create object lock */
339 priv->objlock = g_mutex_new();
340 if (!priv->objlock) {
341 ret = MIX_RESULT_NO_MEMORY;
342 LOG_E( "!priv->objlock\n");
343 goto cleanup;
344 }
345
346 /* clone mode */
347 priv->codec_mode = mode;
348
349 /* ref init_params */
350 priv->init_params = (MixVideoInitParams *) mix_params_ref(MIX_PARAMS(
351 init_params));
352 if (!priv->init_params) {
353 ret = MIX_RESULT_NO_MEMORY;
354 LOG_E( "!priv->init_params\n");
355 goto cleanup;
356 }
357
358 /* NOTE: we don't do anything with drm_init_params */
359
360 /* libVA initialization */
361
362 {
363 VAStatus va_status;
364 Display *display = NULL;
365 ret = mix_videoinitparams_get_display(priv->init_params, &mix_display);
366 if (ret != MIX_RESULT_SUCCESS) {
367 LOG_E("Failed to get display 1\n");
368 goto cleanup;
369 }
370
371 if (MIX_IS_DISPLAYX11(mix_display)) {
372 MixDisplayX11 *mix_displayx11 = MIX_DISPLAYX11(mix_display);
373 ret = mix_displayx11_get_display(mix_displayx11, &display);
374 if (ret != MIX_RESULT_SUCCESS) {
375 LOG_E("Failed to get display 2\n");
376 goto cleanup;
377 }
378 } else {
379
380 /* TODO: add support to other MixDisplay type. For now, just return error!*/
381 LOG_E("It is not display x11\n");
382 ret = MIX_RESULT_FAIL;
383 goto cleanup;
384 }
385
386 /* Now, we can initialize libVA */
387 priv->va_display = vaGetDisplay(display);
388
389 /* Oops! Fail to get VADisplay */
390 if (!priv->va_display) {
391 ret = MIX_RESULT_FAIL;
392 LOG_E("Fail to get VADisplay\n");
393 goto cleanup;
394 }
395
396 /* Initialize libVA */
397 va_status = vaInitialize(priv->va_display, &priv->va_major_version,
398 &priv->va_minor_version);
399
400 /* Oops! Fail to initialize libVA */
401 if (va_status != VA_STATUS_SUCCESS) {
402 ret = MIX_RESULT_FAIL;
403 LOG_E("Fail to initialize libVA\n");
404 goto cleanup;
405 }
406
407 /* TODO: check the version numbers of libVA */
408
409 priv->initialized = TRUE;
410 ret = MIX_RESULT_SUCCESS;
411 }
412
413 cleanup:
414
415 if (ret != MIX_RESULT_SUCCESS) {
416 mix_video_private_cleanup(priv);
417 }
418
419 MIXUNREF(mix_display, mix_display_unref);
420
421 LOG_V( "End\n");
422
423 return ret;
424 }
425
mix_video_deinitialize_default(MixVideo * mix)426 MIX_RESULT mix_video_deinitialize_default(MixVideo * mix) {
427
428 MixVideoPrivate *priv = NULL;
429
430 LOG_V( "Begin\n");
431
432 CHECK_INIT(mix, priv);
433
434 mix_video_private_cleanup(priv);
435
436 LOG_V( "End\n");
437 return MIX_RESULT_SUCCESS;
438 }
439
mix_video_configure_decode(MixVideo * mix,MixVideoConfigParamsDec * config_params_dec,MixDrmParams * drm_config_params)440 MIX_RESULT mix_video_configure_decode(MixVideo * mix,
441 MixVideoConfigParamsDec * config_params_dec, MixDrmParams * drm_config_params) {
442
443 MIX_RESULT ret = MIX_RESULT_FAIL;
444 MixVideoPrivate *priv = NULL;
445 MixVideoConfigParamsDec *priv_config_params_dec = NULL;
446
447 gchar *mime_type = NULL;
448 guint fps_n, fps_d;
449 guint bufpoolsize = 0;
450
451 MixFrameOrderMode frame_order_mode = MIX_FRAMEORDER_MODE_DISPLAYORDER;
452
453 LOG_V( "Begin\n");
454
455 CHECK_INIT(mix, priv);
456
457 if (!config_params_dec) {
458 LOG_E( "!config_params_dec\n");
459 return MIX_RESULT_NULL_PTR;
460 }
461
462 if (!MIX_IS_VIDEOCONFIGPARAMSDEC(config_params_dec)) {
463 LOG_E("Not a MixVideoConfigParamsDec\n");
464 return MIX_RESULT_INVALID_PARAM;
465 }
466
467 /* ---------------------- begin lock --------------------- */
468 g_mutex_lock(priv->objlock);
469
470 /*
471 * MixVideo has already been configured, it should be
472 * re-configured.
473 *
474 * TODO: Allow MixVideo re-configuration
475 */
476 if (priv->configured) {
477 ret = MIX_RESULT_SUCCESS;
478 LOG_W( "Already configured\n");
479 goto cleanup;
480 }
481
482 /* Make a copy of config_params */
483 priv->config_params = (MixVideoConfigParams *) mix_params_dup(MIX_PARAMS(
484 config_params_dec));
485 if (!priv->config_params) {
486 ret = MIX_RESULT_NO_MEMORY;
487 LOG_E("Fail to duplicate config_params\n");
488 goto cleanup;
489 }
490
491 priv_config_params_dec = (MixVideoConfigParamsDec *)priv->config_params;
492
493 /* Get fps, frame order mode and mime type from config_params */
494 ret = mix_videoconfigparamsdec_get_mime_type(priv_config_params_dec, &mime_type);
495 if (ret != MIX_RESULT_SUCCESS) {
496 LOG_E("Failed to get mime type\n");
497 goto cleanup;
498 }
499
500 LOG_I( "mime : %s\n", mime_type);
501
502 #ifdef MIX_LOG_ENABLE
503 if (g_strcmp0(mime_type, "video/x-wmv") == 0) {
504
505 LOG_I( "mime : video/x-wmv\n");
506 if (MIX_IS_VIDEOCONFIGPARAMSDEC_VC1(priv_config_params_dec)) {
507 LOG_I( "VC1 config_param\n");
508 } else {
509 LOG_E("Not VC1 config_param\n");
510 }
511 }
512 #endif
513
514 ret = mix_videoconfigparamsdec_get_frame_order_mode(priv_config_params_dec,
515 &frame_order_mode);
516 if (ret != MIX_RESULT_SUCCESS) {
517 LOG_E("Failed to frame order mode\n");
518 goto cleanup;
519 }
520
521 ret = mix_videoconfigparamsdec_get_frame_rate(priv_config_params_dec, &fps_n,
522 &fps_d);
523 if (ret != MIX_RESULT_SUCCESS) {
524 LOG_E("Failed to get frame rate\n");
525 goto cleanup;
526 }
527
528 if (!fps_n) {
529 ret = MIX_RESULT_FAIL;
530 LOG_E( "fps_n is 0\n");
531 goto cleanup;
532 }
533
534 ret = mix_videoconfigparamsdec_get_buffer_pool_size(priv_config_params_dec,
535 &bufpoolsize);
536 if (ret != MIX_RESULT_SUCCESS) {
537 LOG_E("Failed to get buffer pool size\n");
538 goto cleanup;
539 }
540
541 /* create frame manager */
542 priv->frame_manager = mix_framemanager_new();
543 if (!priv->frame_manager) {
544 ret = MIX_RESULT_NO_MEMORY;
545 LOG_E("Failed to create frame manager\n");
546 goto cleanup;
547 }
548
549 /* initialize frame manager */
550
551 if (g_strcmp0(mime_type, "video/x-wmv") == 0 || g_strcmp0(mime_type,
552 "video/mpeg") == 0 || g_strcmp0(mime_type, "video/x-divx") == 0) {
553 ret = mix_framemanager_initialize(priv->frame_manager,
554 frame_order_mode, fps_n, fps_d, FALSE);
555 } else {
556 ret = mix_framemanager_initialize(priv->frame_manager,
557 frame_order_mode, fps_n, fps_d, TRUE);
558 }
559
560 if (ret != MIX_RESULT_SUCCESS) {
561 LOG_E("Failed to initialize frame manager\n");
562 goto cleanup;
563 }
564
565 /* create buffer pool */
566 priv->buffer_pool = mix_bufferpool_new();
567 if (!priv->buffer_pool) {
568 ret = MIX_RESULT_NO_MEMORY;
569 LOG_E("Failed to create buffer pool\n");
570 goto cleanup;
571 }
572
573 ret = mix_bufferpool_initialize(priv->buffer_pool, bufpoolsize);
574 if (ret != MIX_RESULT_SUCCESS) {
575 LOG_E("Failed to initialize buffer pool\n");
576 goto cleanup;
577 }
578
579 /* Finally, we can create MixVideoFormat */
580 /* What type of MixVideoFormat we need create? */
581
582 if (g_strcmp0(mime_type, "video/x-wmv") == 0
583 && MIX_IS_VIDEOCONFIGPARAMSDEC_VC1(priv_config_params_dec)) {
584
585 MixVideoFormat_VC1 *video_format = mix_videoformat_vc1_new();
586 if (!video_format) {
587 ret = MIX_RESULT_NO_MEMORY;
588 LOG_E("Failed to create VC-1 video format\n");
589 goto cleanup;
590 }
591
592 /* TODO: work specific to VC-1 */
593
594 priv->video_format = MIX_VIDEOFORMAT(video_format);
595
596 } else if (g_strcmp0(mime_type, "video/x-h264") == 0
597 && MIX_IS_VIDEOCONFIGPARAMSDEC_H264(priv_config_params_dec)) {
598
599 MixVideoFormat_H264 *video_format = mix_videoformat_h264_new();
600 if (!video_format) {
601 ret = MIX_RESULT_NO_MEMORY;
602 LOG_E("Failed to create H.264 video format\n");
603 goto cleanup;
604 }
605
606 /* TODO: work specific to H.264 */
607
608 priv->video_format = MIX_VIDEOFORMAT(video_format);
609
610 } else if (g_strcmp0(mime_type, "video/mpeg") == 0 || g_strcmp0(mime_type,
611 "video/x-divx") == 0) {
612
613 guint version = 0;
614
615 /* Is this mpeg4:2 ? */
616 if (g_strcmp0(mime_type, "video/mpeg") == 0) {
617
618 /*
619 * we don't support mpeg other than mpeg verion 4
620 */
621 if (!MIX_IS_VIDEOCONFIGPARAMSDEC_MP42(priv_config_params_dec)) {
622 ret = MIX_RESULT_NOT_SUPPORTED;
623 goto cleanup;
624 }
625
626 /* what is the mpeg version ? */
627 ret = mix_videoconfigparamsdec_mp42_get_mpegversion(
628 MIX_VIDEOCONFIGPARAMSDEC_MP42(priv_config_params_dec), &version);
629 if (ret != MIX_RESULT_SUCCESS) {
630 LOG_E("Failed to get mpeg version\n");
631 goto cleanup;
632 }
633
634 /* if it is not MPEG4 */
635 if (version != 4) {
636 ret = MIX_RESULT_NOT_SUPPORTED;
637 goto cleanup;
638 }
639
640 } else {
641
642 /* config_param shall be MixVideoConfigParamsDecMP42 */
643 if (!MIX_IS_VIDEOCONFIGPARAMSDEC_MP42(priv_config_params_dec)) {
644 ret = MIX_RESULT_NOT_SUPPORTED;
645 goto cleanup;
646 }
647
648 /* what is the divx version ? */
649 ret = mix_videoconfigparamsdec_mp42_get_divxversion(
650 MIX_VIDEOCONFIGPARAMSDEC_MP42(priv_config_params_dec), &version);
651 if (ret != MIX_RESULT_SUCCESS) {
652 LOG_E("Failed to get divx version\n");
653 goto cleanup;
654 }
655
656 /* if it is not divx 4 or 5 */
657 if (version != 4 && version != 5) {
658 ret = MIX_RESULT_NOT_SUPPORTED;
659 goto cleanup;
660 }
661 }
662
663 MixVideoFormat_MP42 *video_format = mix_videoformat_mp42_new();
664 if (!video_format) {
665 ret = MIX_RESULT_NO_MEMORY;
666 LOG_E("Failed to create MPEG-4:2 video format\n");
667 goto cleanup;
668 }
669
670 /* TODO: work specific to MPEG-4:2 */
671 priv->video_format = MIX_VIDEOFORMAT(video_format);
672
673 } else {
674
675 /* Oops! A format we don't know */
676
677 ret = MIX_RESULT_FAIL;
678 LOG_E("Unknown format, we can't handle it\n");
679 goto cleanup;
680 }
681
682 /* initialize MixVideoFormat */
683 ret = mix_videofmt_initialize(priv->video_format, priv_config_params_dec,
684 priv->frame_manager, priv->buffer_pool, &priv->surface_pool,
685 priv->va_display);
686
687 if (ret != MIX_RESULT_SUCCESS) {
688 LOG_E("Failed initialize video format\n");
689 goto cleanup;
690 }
691
692 mix_surfacepool_ref(priv->surface_pool);
693
694 /* decide MixVideoFormat from mime_type*/
695
696 priv->configured = TRUE;
697 ret = MIX_RESULT_SUCCESS;
698
699 cleanup:
700
701 if (ret != MIX_RESULT_SUCCESS) {
702 MIXUNREF(priv->config_params, mix_videoconfigparams_unref);
703 MIXUNREF(priv->frame_manager, mix_framemanager_unref);
704 MIXUNREF(priv->buffer_pool, mix_bufferpool_unref);
705 MIXUNREF(priv->video_format, mix_videoformat_unref);
706 }
707
708 if (mime_type) {
709 g_free(mime_type);
710 }
711
712 g_mutex_unlock(priv->objlock);
713 /* ---------------------- end lock --------------------- */
714
715 LOG_V( "End\n");
716
717 return ret;
718 }
719
mix_video_configure_encode(MixVideo * mix,MixVideoConfigParamsEnc * config_params_enc,MixDrmParams * drm_config_params)720 MIX_RESULT mix_video_configure_encode(MixVideo * mix,
721 MixVideoConfigParamsEnc * config_params_enc,
722 MixDrmParams * drm_config_params) {
723
724 MIX_RESULT ret = MIX_RESULT_FAIL;
725 MixVideoPrivate *priv = NULL;
726 MixVideoConfigParamsEnc *priv_config_params_enc = NULL;
727
728
729 gchar *mime_type = NULL;
730 MixEncodeTargetFormat encode_format = MIX_ENCODE_TARGET_FORMAT_H264;
731 guint bufpoolsize = 0;
732
733 MixFrameOrderMode frame_order_mode = MIX_FRAMEORDER_MODE_DECODEORDER;
734
735
736 LOG_V( "Begin\n");
737
738 CHECK_INIT(mix, priv);
739
740 if (!config_params_enc) {
741 LOG_E("!config_params_enc\n");
742 return MIX_RESULT_NULL_PTR;
743 }
744 if (!MIX_IS_VIDEOCONFIGPARAMSENC(config_params_enc)) {
745 LOG_E("Not a MixVideoConfigParams\n");
746 return MIX_RESULT_INVALID_PARAM;
747 }
748
749 /* ---------------------- begin lock --------------------- */
750 g_mutex_lock(priv->objlock);
751
752 /*
753 * MixVideo has already been configured, it should be
754 * re-configured.
755 *
756 * TODO: Allow MixVideo re-configuration
757 */
758 if (priv->configured) {
759 ret = MIX_RESULT_SUCCESS;
760 LOG_E( "Already configured\n");
761 goto cleanup;
762 }
763
764 /* Make a copy of config_params */
765 priv->config_params = (MixVideoConfigParams *) mix_params_dup(
766 MIX_PARAMS(config_params_enc));
767 if (!priv->config_params) {
768 ret = MIX_RESULT_NO_MEMORY;
769 LOG_E("Fail to duplicate config_params\n");
770 goto cleanup;
771 }
772
773 priv_config_params_enc = (MixVideoConfigParamsEnc *)priv->config_params;
774
775 /* Get fps, frame order mode and mime type from config_params */
776 ret = mix_videoconfigparamsenc_get_mime_type(priv_config_params_enc,
777 &mime_type);
778 if (ret != MIX_RESULT_SUCCESS) {
779 LOG_E("Failed to get mime type\n");
780 goto cleanup;
781 }
782
783 LOG_I( "mime : %s\n", mime_type);
784
785 ret = mix_videoconfigparamsenc_get_encode_format(priv_config_params_enc,
786 &encode_format);
787 if (ret != MIX_RESULT_SUCCESS) {
788 LOG_E("Failed to get target format\n");
789 goto cleanup;
790 }
791
792 LOG_I( "encode_format : %d\n",
793 encode_format);
794
795 ret = mix_videoconfigparamsenc_get_buffer_pool_size(
796 priv_config_params_enc, &bufpoolsize);
797 if (ret != MIX_RESULT_SUCCESS) {
798 LOG_E("Failed to get buffer pool size\n");
799 goto cleanup;
800 }
801
802 /* create frame manager */
803 priv->frame_manager = mix_framemanager_new();
804 if (!priv->frame_manager) {
805 ret = MIX_RESULT_NO_MEMORY;
806 LOG_E("Failed to create frame manager\n");
807 goto cleanup;
808 }
809
810 /* initialize frame manager */
811 /* frame rate can be any value for encoding. */
812 ret = mix_framemanager_initialize(priv->frame_manager, frame_order_mode,
813 1, 1, FALSE);
814
815 if (ret != MIX_RESULT_SUCCESS) {
816 LOG_E("Failed to initialize frame manager\n");
817 goto cleanup;
818 }
819
820 /* create buffer pool */
821 priv->buffer_pool = mix_bufferpool_new();
822 if (!priv->buffer_pool) {
823 ret = MIX_RESULT_NO_MEMORY;
824 LOG_E("Failed to create buffer pool\n");
825 goto cleanup;
826 }
827
828 ret = mix_bufferpool_initialize(priv->buffer_pool, bufpoolsize);
829 if (ret != MIX_RESULT_SUCCESS) {
830 LOG_E("Failed to initialize buffer pool\n");
831 goto cleanup;
832 }
833
834 /* Finally, we can create MixVideoFormatEnc */
835 /* What type of MixVideoFormatEnc we need create? */
836
837 if (encode_format == MIX_ENCODE_TARGET_FORMAT_H264
838 && MIX_IS_VIDEOCONFIGPARAMSENC_H264(priv_config_params_enc)) {
839
840 MixVideoFormatEnc_H264 *video_format_enc =
841 mix_videoformatenc_h264_new();
842 if (!video_format_enc) {
843 ret = MIX_RESULT_NO_MEMORY;
844 LOG_E("mix_video_configure_encode: Failed to create h264 video enc format\n");
845 goto cleanup;
846 }
847
848 /* TODO: work specific to h264 encode */
849
850 priv->video_format_enc = MIX_VIDEOFORMATENC(video_format_enc);
851
852 }
853 else if (encode_format == MIX_ENCODE_TARGET_FORMAT_MPEG4
854 && MIX_IS_VIDEOCONFIGPARAMSENC_MPEG4(priv_config_params_enc)) {
855
856 MixVideoFormatEnc_MPEG4 *video_format_enc = mix_videoformatenc_mpeg4_new();
857 if (!video_format_enc) {
858 ret = MIX_RESULT_NO_MEMORY;
859 LOG_E("mix_video_configure_encode: Failed to create mpeg-4:2 video format\n");
860 goto cleanup;
861 }
862
863 /* TODO: work specific to mpeg4 */
864
865 priv->video_format_enc = MIX_VIDEOFORMATENC(video_format_enc);
866
867 }
868 else if (encode_format == MIX_ENCODE_TARGET_FORMAT_PREVIEW
869 && MIX_IS_VIDEOCONFIGPARAMSENC_PREVIEW(priv_config_params_enc)) {
870
871 MixVideoFormatEnc_Preview *video_format_enc = mix_videoformatenc_preview_new();
872 if (!video_format_enc) {
873 ret = MIX_RESULT_NO_MEMORY;
874 LOG_E( "mix_video_configure_encode: Failed to create preview video format\n");
875 goto cleanup;
876 }
877
878 priv->video_format_enc = MIX_VIDEOFORMATENC(video_format_enc);
879
880 }
881 else {
882
883 /*unsupported format */
884 ret = MIX_RESULT_NOT_SUPPORTED;
885 LOG_E("Unknown format, we can't handle it\n");
886 goto cleanup;
887 }
888
889 /* initialize MixVideoEncFormat */
890 ret = mix_videofmtenc_initialize(priv->video_format_enc,
891 priv_config_params_enc, priv->frame_manager, NULL, &priv->surface_pool,
892 priv->va_display);
893
894 if (ret != MIX_RESULT_SUCCESS) {
895 LOG_E("Failed initialize video format\n");
896 goto cleanup;
897 }
898
899 mix_surfacepool_ref(priv->surface_pool);
900
901 priv->configured = TRUE;
902 ret = MIX_RESULT_SUCCESS;
903
904 cleanup:
905
906 if (ret != MIX_RESULT_SUCCESS) {
907 MIXUNREF(priv->frame_manager, mix_framemanager_unref);
908 MIXUNREF(priv->config_params, mix_videoconfigparams_unref);
909 MIXUNREF(priv->buffer_pool, mix_bufferpool_unref);
910 MIXUNREF(priv->video_format_enc, mix_videoformatenc_unref);
911 }
912
913 if (mime_type) {
914 g_free(mime_type);
915 }
916
917 g_mutex_unlock(priv->objlock);
918 /* ---------------------- end lock --------------------- */
919
920 LOG_V( "End\n");
921
922 return ret;
923 }
924
mix_video_configure_default(MixVideo * mix,MixVideoConfigParams * config_params,MixDrmParams * drm_config_params)925 MIX_RESULT mix_video_configure_default(MixVideo * mix,
926 MixVideoConfigParams * config_params,
927 MixDrmParams * drm_config_params) {
928
929 MIX_RESULT ret = MIX_RESULT_FAIL;
930 MixVideoPrivate *priv = NULL;
931
932 LOG_V( "Begin\n");
933
934 CHECK_INIT(mix, priv);
935 if(!config_params) {
936 LOG_E("!config_params\n");
937 return MIX_RESULT_NULL_PTR;
938 }
939
940 /*Decoder mode or Encoder mode*/
941 if (priv->codec_mode == MIX_CODEC_MODE_DECODE && MIX_IS_VIDEOCONFIGPARAMSDEC(config_params)) {
942 ret = mix_video_configure_decode(mix, (MixVideoConfigParamsDec*)config_params, NULL);
943 } else if (priv->codec_mode == MIX_CODEC_MODE_ENCODE && MIX_IS_VIDEOCONFIGPARAMSENC(config_params)) {
944 ret = mix_video_configure_encode(mix, (MixVideoConfigParamsEnc*)config_params, NULL);
945 } else {
946 LOG_E("Codec mode not supported\n");
947 }
948
949 LOG_V( "end\n");
950
951 return ret;
952 }
953
mix_video_get_config_default(MixVideo * mix,MixVideoConfigParams ** config_params)954 MIX_RESULT mix_video_get_config_default(MixVideo * mix,
955 MixVideoConfigParams ** config_params) {
956
957 MIX_RESULT ret = MIX_RESULT_FAIL;
958 MixVideoPrivate *priv = NULL;
959
960 CHECK_INIT_CONFIG(mix, priv);
961
962 if (!config_params) {
963 LOG_E( "!config_params\n");
964 return MIX_RESULT_NULL_PTR;
965 }
966
967 /* ---------------------- begin lock --------------------- */
968 g_mutex_lock(priv->objlock);
969
970 *config_params = MIX_VIDEOCONFIGPARAMS(mix_params_dup(MIX_PARAMS(priv->config_params)));
971 if(!*config_params) {
972 ret = MIX_RESULT_NO_MEMORY;
973 LOG_E("Failed to duplicate MixVideoConfigParams\n");
974 goto cleanup;
975 }
976
977 cleanup:
978
979 /* ---------------------- end lock --------------------- */
980 g_mutex_unlock(priv->objlock);
981
982 LOG_V( "End\n");
983
984 return ret;
985
986 }
987
mix_video_decode_default(MixVideo * mix,MixBuffer * bufin[],gint bufincnt,MixVideoDecodeParams * decode_params)988 MIX_RESULT mix_video_decode_default(MixVideo * mix, MixBuffer * bufin[],
989 gint bufincnt, MixVideoDecodeParams * decode_params) {
990
991 MIX_RESULT ret = MIX_RESULT_FAIL;
992 MixVideoPrivate *priv = NULL;
993
994 LOG_V( "Begin\n");
995
996 CHECK_INIT_CONFIG(mix, priv);
997 if(!bufin || !bufincnt || !decode_params) {
998 LOG_E( "!bufin || !bufincnt || !decode_params\n");
999 return MIX_RESULT_NULL_PTR;
1000 }
1001
1002 //First check that we have surfaces available for decode
1003 ret = mix_surfacepool_check_available(priv->surface_pool);
1004
1005 if (ret == MIX_RESULT_POOLEMPTY) {
1006 LOG_I( "Out of surface\n");
1007 return MIX_RESULT_OUTOFSURFACES;
1008 }
1009
1010 g_mutex_lock(priv->objlock);
1011
1012 ret = mix_videofmt_decode(priv->video_format, bufin, bufincnt, decode_params);
1013
1014 g_mutex_unlock(priv->objlock);
1015
1016 LOG_V( "End\n");
1017
1018 return ret;
1019 }
1020
mix_video_get_frame_default(MixVideo * mix,MixVideoFrame ** frame)1021 MIX_RESULT mix_video_get_frame_default(MixVideo * mix, MixVideoFrame ** frame) {
1022
1023 LOG_V( "Begin\n");
1024
1025 MIX_RESULT ret = MIX_RESULT_FAIL;
1026 MixVideoPrivate *priv = NULL;
1027
1028 CHECK_INIT_CONFIG(mix, priv);
1029
1030 if (!frame) {
1031 LOG_E( "!frame\n");
1032 return MIX_RESULT_NULL_PTR;
1033 }
1034
1035 /* ---------------------- begin lock --------------------- */
1036 g_mutex_lock(priv->objlock);
1037
1038 LOG_V("Calling frame manager dequeue\n");
1039
1040 ret = mix_framemanager_dequeue(priv->frame_manager, frame);
1041
1042 /* ---------------------- end lock --------------------- */
1043 g_mutex_unlock(priv->objlock);
1044
1045 LOG_V( "End\n");
1046
1047 return ret;
1048 }
1049
mix_video_release_frame_default(MixVideo * mix,MixVideoFrame * frame)1050 MIX_RESULT mix_video_release_frame_default(MixVideo * mix,
1051 MixVideoFrame * frame) {
1052
1053 LOG_V( "Begin\n");
1054
1055 MIX_RESULT ret = MIX_RESULT_FAIL;
1056 MixVideoPrivate *priv = NULL;
1057
1058 CHECK_INIT_CONFIG(mix, priv);
1059
1060 if (!frame) {
1061 LOG_E( "!frame\n");
1062 return MIX_RESULT_NULL_PTR;
1063 }
1064
1065 /*
1066 * We don't need lock here. MixVideoFrame has lock to
1067 * protect itself.
1068 */
1069 #if 0
1070 /* ---------------------- begin lock --------------------- */
1071 g_mutex_lock(priv->objlock);
1072 #endif
1073
1074 LOG_I("Releasing reference frame %x\n", (guint) frame);
1075 mix_videoframe_unref(frame);
1076
1077 ret = MIX_RESULT_SUCCESS;
1078
1079 #if 0
1080 /* ---------------------- end lock --------------------- */
1081 g_mutex_unlock(priv->objlock);
1082 #endif
1083
1084 LOG_V( "End\n");
1085
1086 return ret;
1087
1088 }
1089
mix_video_render_default(MixVideo * mix,MixVideoRenderParams * render_params,MixVideoFrame * frame)1090 MIX_RESULT mix_video_render_default(MixVideo * mix,
1091 MixVideoRenderParams * render_params, MixVideoFrame *frame) {
1092
1093 LOG_V( "Begin\n");
1094
1095 MIX_RESULT ret = MIX_RESULT_FAIL;
1096 MixVideoPrivate *priv = NULL;
1097
1098 MixDisplay *mix_display = NULL;
1099 MixDisplayX11 *mix_display_x11 = NULL;
1100
1101 Display *display = NULL;
1102 Drawable drawable = 0;
1103
1104 MixRect src_rect, dst_rect;
1105
1106 VARectangle *va_cliprects = NULL;
1107 guint number_of_cliprects = 0;
1108
1109 /* VASurfaceID va_surface_id; */
1110 gulong va_surface_id;
1111 VAStatus va_status;
1112
1113 CHECK_INIT_CONFIG(mix, priv);
1114
1115 if (!render_params || !frame) {
1116 LOG_E( "!render_params || !frame\n");
1117 return MIX_RESULT_NULL_PTR;
1118 }
1119
1120 /* Is this render param valid? */
1121 if (!MIX_IS_VIDEORENDERPARAMS(render_params)) {
1122 LOG_E("Not MixVideoRenderParams\n");
1123 return MIX_RESULT_INVALID_PARAM;
1124 }
1125
1126 /*
1127 * We don't need lock here. priv->va_display may be the only variable
1128 * seems need to be protected. But, priv->va_display is initialized
1129 * when mixvideo object is initialized, and it keeps
1130 * the same value thoughout the life of mixvideo.
1131 */
1132 #if 0
1133 /* ---------------------- begin lock --------------------- */
1134 g_mutex_lock(priv->objlock);
1135 #endif
1136
1137 /* get MixDisplay prop from render param */
1138 ret = mix_videorenderparams_get_display(render_params, &mix_display);
1139 if (ret != MIX_RESULT_SUCCESS) {
1140 LOG_E("Failed to get mix_display\n");
1141 goto cleanup;
1142 }
1143
1144 /* Is this MixDisplayX11 ? */
1145 /* TODO: we shall also support MixDisplay other than MixDisplayX11 */
1146 if (!MIX_IS_DISPLAYX11(mix_display)) {
1147 ret = MIX_RESULT_INVALID_PARAM;
1148 LOG_E( "Not MixDisplayX11\n");
1149 goto cleanup;
1150 }
1151
1152 /* cast MixDisplay to MixDisplayX11 */
1153 mix_display_x11 = MIX_DISPLAYX11(mix_display);
1154
1155 /* Get Drawable */
1156 ret = mix_displayx11_get_drawable(mix_display_x11, &drawable);
1157 if (ret != MIX_RESULT_SUCCESS) {
1158 LOG_E( "Failed to get drawable\n");
1159 goto cleanup;
1160 }
1161
1162 /* Get Display */
1163 ret = mix_displayx11_get_display(mix_display_x11, &display);
1164 if (ret != MIX_RESULT_SUCCESS) {
1165 LOG_E( "Failed to get display\n");
1166 goto cleanup;
1167 }
1168
1169 /* get src_rect */
1170 ret = mix_videorenderparams_get_src_rect(render_params, &src_rect);
1171 if (ret != MIX_RESULT_SUCCESS) {
1172 LOG_E("Failed to get SOURCE src_rect\n");
1173 goto cleanup;
1174 }
1175
1176 /* get dst_rect */
1177 ret = mix_videorenderparams_get_dest_rect(render_params, &dst_rect);
1178 if (ret != MIX_RESULT_SUCCESS) {
1179 LOG_E( "Failed to get dst_rect\n");
1180 goto cleanup;
1181 }
1182
1183 /* get va_cliprects */
1184 ret = mix_videorenderparams_get_cliprects_internal(render_params,
1185 &va_cliprects, &number_of_cliprects);
1186 if (ret != MIX_RESULT_SUCCESS) {
1187 LOG_E("Failed to get va_cliprects\n");
1188 goto cleanup;
1189 }
1190
1191 /* get surface id from frame */
1192 ret = mix_videoframe_get_frame_id(frame, &va_surface_id);
1193 if (ret != MIX_RESULT_SUCCESS) {
1194 LOG_E("Failed to get va_surface_id\n");
1195 goto cleanup;
1196 }
1197 guint64 timestamp = 0;
1198 mix_videoframe_get_timestamp(frame, ×tamp);
1199 LOG_V( "Displaying surface ID %d, timestamp %"G_GINT64_FORMAT"\n", (int)va_surface_id, timestamp);
1200
1201 guint32 frame_structure = 0;
1202 mix_videoframe_get_frame_structure(frame, &frame_structure);
1203 /* TODO: the last param of vaPutSurface is de-interlacing flags,
1204 what is value shall be*/
1205 va_status = vaPutSurface(priv->va_display, (VASurfaceID) va_surface_id,
1206 drawable, src_rect.x, src_rect.y, src_rect.width, src_rect.height,
1207 dst_rect.x, dst_rect.y, dst_rect.width, dst_rect.height,
1208 va_cliprects, number_of_cliprects, frame_structure);
1209
1210 if (va_status != VA_STATUS_SUCCESS) {
1211 ret = MIX_RESULT_FAIL;
1212 LOG_E("Failed vaPutSurface() : va_status = %d\n", va_status);
1213 goto cleanup;
1214 }
1215
1216 /* TODO: Is this only for X11? */
1217 XSync(display, FALSE);
1218
1219 ret = MIX_RESULT_SUCCESS;
1220
1221 cleanup:
1222
1223 MIXUNREF(mix_display, mix_display_unref)
1224 /* MIXUNREF(render_params, mix_videorenderparams_unref)*/
1225
1226 #if 0
1227 /* ---------------------- end lock --------------------- */
1228 g_mutex_unlock(priv->objlock);
1229 #endif
1230
1231 LOG_V( "End\n");
1232
1233 return ret;
1234
1235 }
1236
mix_video_encode_default(MixVideo * mix,MixBuffer * bufin[],gint bufincnt,MixIOVec * iovout[],gint iovoutcnt,MixVideoEncodeParams * encode_params)1237 MIX_RESULT mix_video_encode_default(MixVideo * mix, MixBuffer * bufin[],
1238 gint bufincnt, MixIOVec * iovout[], gint iovoutcnt,
1239 MixVideoEncodeParams * encode_params) {
1240
1241 MIX_RESULT ret = MIX_RESULT_FAIL;
1242 MixVideoPrivate *priv = NULL;
1243
1244 LOG_V( "Begin\n");
1245
1246 CHECK_INIT_CONFIG(mix, priv);
1247 if(!bufin || !bufincnt) { //we won't check encode_params here, it's just a placeholder
1248 LOG_E( "!bufin || !bufincnt\n");
1249 return MIX_RESULT_NULL_PTR;
1250 }
1251
1252 g_mutex_lock(priv->objlock);
1253
1254 ret = mix_videofmtenc_encode(priv->video_format_enc, bufin, bufincnt,
1255 iovout, iovoutcnt, encode_params);
1256
1257 g_mutex_unlock(priv->objlock);
1258
1259 LOG_V( "End\n");
1260 return ret;
1261 }
1262
mix_video_flush_default(MixVideo * mix)1263 MIX_RESULT mix_video_flush_default(MixVideo * mix) {
1264
1265 MIX_RESULT ret = MIX_RESULT_FAIL;
1266 MixVideoPrivate *priv = NULL;
1267
1268 LOG_V( "Begin\n");
1269
1270 CHECK_INIT_CONFIG(mix, priv);
1271
1272 /* ---------------------- begin lock --------------------- */
1273 g_mutex_lock(priv->objlock);
1274
1275 if (priv->codec_mode == MIX_CODEC_MODE_DECODE && priv->video_format != NULL) {
1276 ret = mix_videofmt_flush(priv->video_format);
1277
1278 ret = mix_framemanager_flush(priv->frame_manager);
1279 } else if (priv->codec_mode == MIX_CODEC_MODE_ENCODE
1280 && priv->video_format_enc != NULL) {
1281 /*No framemanager for encoder now*/
1282 ret = mix_videofmtenc_flush(priv->video_format_enc);
1283 } else {
1284 g_mutex_unlock(priv->objlock);
1285 LOG_E("Invalid video_format/video_format_enc Pointer\n");
1286 return MIX_RESULT_NULL_PTR;
1287 }
1288
1289 /* ---------------------- end lock --------------------- */
1290 g_mutex_unlock(priv->objlock);
1291
1292 LOG_V( "End\n");
1293
1294 return ret;
1295
1296 }
1297
mix_video_eos_default(MixVideo * mix)1298 MIX_RESULT mix_video_eos_default(MixVideo * mix) {
1299
1300 MIX_RESULT ret = MIX_RESULT_FAIL;
1301 MixVideoPrivate *priv = NULL;
1302
1303 LOG_V( "Begin\n");
1304
1305 CHECK_INIT_CONFIG(mix, priv);
1306
1307 /* ---------------------- begin lock --------------------- */
1308 g_mutex_lock(priv->objlock);
1309
1310 if (priv->codec_mode == MIX_CODEC_MODE_DECODE && priv->video_format != NULL) {
1311 ret = mix_videofmt_eos(priv->video_format);
1312
1313 /* frame manager will set EOS flag to be TRUE */
1314 ret = mix_framemanager_eos(priv->frame_manager);
1315 } else if (priv->codec_mode == MIX_CODEC_MODE_ENCODE
1316 && priv->video_format_enc != NULL) {
1317 /*No framemanager now*/
1318 ret = mix_videofmtenc_eos(priv->video_format_enc);
1319 } else {
1320 g_mutex_unlock(priv->objlock);
1321 LOG_E("Invalid video_format/video_format_enc Pointer\n");
1322 return MIX_RESULT_NULL_PTR;
1323 }
1324
1325 /* ---------------------- end lock --------------------- */
1326 g_mutex_unlock(priv->objlock);
1327
1328 LOG_V( "End\n");
1329
1330 return ret;
1331 }
1332
mix_video_get_state_default(MixVideo * mix,MixState * state)1333 MIX_RESULT mix_video_get_state_default(MixVideo * mix, MixState * state) {
1334
1335 MixVideoPrivate *priv = NULL;
1336
1337 LOG_V( "Begin\n");
1338
1339 CHECK_INIT_CONFIG(mix, priv);
1340
1341 if (!state) {
1342 LOG_E( "!state\n");
1343 return MIX_RESULT_NULL_PTR;
1344 }
1345
1346 *state = MIX_STATE_CONFIGURED;
1347
1348 LOG_V( "End\n");
1349
1350 return MIX_RESULT_SUCCESS;
1351 }
1352
mix_video_get_mixbuffer_default(MixVideo * mix,MixBuffer ** buf)1353 MIX_RESULT mix_video_get_mixbuffer_default(MixVideo * mix, MixBuffer ** buf) {
1354
1355 MIX_RESULT ret = MIX_RESULT_FAIL;
1356 MixVideoPrivate *priv = NULL;
1357
1358 LOG_V( "Begin\n");
1359
1360 CHECK_INIT_CONFIG(mix, priv);
1361
1362 if (!buf) {
1363 LOG_E( "!buf\n");
1364 return MIX_RESULT_INVALID_PARAM;
1365 }
1366
1367 /* ---------------------- begin lock --------------------- */
1368 g_mutex_lock(priv->objlock);
1369
1370 ret = mix_bufferpool_get(priv->buffer_pool, buf);
1371
1372 /* ---------------------- end lock --------------------- */
1373 g_mutex_unlock(priv->objlock);
1374
1375 LOG_V( "End ret = 0x%x\n", ret);
1376
1377 return ret;
1378
1379 }
1380
mix_video_release_mixbuffer_default(MixVideo * mix,MixBuffer * buf)1381 MIX_RESULT mix_video_release_mixbuffer_default(MixVideo * mix, MixBuffer * buf) {
1382
1383 MIX_RESULT ret = MIX_RESULT_FAIL;
1384 MixVideoPrivate *priv = NULL;
1385
1386 LOG_V( "Begin\n");
1387
1388 CHECK_INIT_CONFIG(mix, priv);
1389
1390 if (!buf) {
1391 LOG_E( "!buf\n");
1392 return MIX_RESULT_INVALID_PARAM;
1393 }
1394
1395 /* ---------------------- begin lock --------------------- */
1396 g_mutex_lock(priv->objlock);
1397
1398 mix_buffer_unref(buf);
1399
1400 /* ---------------------- end lock --------------------- */
1401 g_mutex_unlock(priv->objlock);
1402
1403 LOG_V( "End\n");
1404 return ret;
1405
1406 }
1407
mix_video_get_max_coded_buffer_size_default(MixVideo * mix,guint * max_size)1408 MIX_RESULT mix_video_get_max_coded_buffer_size_default (MixVideo * mix, guint *max_size)
1409 {
1410 MIX_RESULT ret = MIX_RESULT_FAIL;
1411 MixVideoPrivate *priv = NULL;
1412
1413 LOG_V( "Begin\n");
1414
1415 if (!mix || !max_size) /* TODO: add other parameter NULL checking */
1416 {
1417 LOG_E( "!mix || !bufsize\n");
1418 return MIX_RESULT_NULL_PTR;
1419 }
1420
1421 CHECK_INIT_CONFIG(mix, priv);
1422
1423 g_mutex_lock(priv->objlock);
1424
1425 ret = mix_videofmtenc_get_max_coded_buffer_size(priv->video_format_enc, max_size);
1426
1427 g_mutex_unlock(priv->objlock);
1428
1429 LOG_V( "End\n");
1430 return ret;
1431 }
1432
1433 /*
1434 * API functions
1435 */
1436
1437 #define CHECK_AND_GET_MIX_CLASS(mix, klass) \
1438 if (!mix) { \
1439 return MIX_RESULT_NULL_PTR; \
1440 } \
1441 if (!MIX_IS_VIDEO(mix)) { \
1442 LOG_E( "Not MixVideo\n"); \
1443 return MIX_RESULT_INVALID_PARAM; \
1444 } \
1445 klass = MIX_VIDEO_GET_CLASS(mix);
1446
1447
mix_video_get_version(MixVideo * mix,guint * major,guint * minor)1448 MIX_RESULT mix_video_get_version(MixVideo * mix, guint * major, guint * minor) {
1449
1450 MixVideoClass *klass = NULL;
1451 CHECK_AND_GET_MIX_CLASS(mix, klass);
1452
1453 if (klass->get_version_func) {
1454 return klass->get_version_func(mix, major, minor);
1455 }
1456 return MIX_RESULT_NOTIMPL;
1457
1458 }
1459
mix_video_initialize(MixVideo * mix,MixCodecMode mode,MixVideoInitParams * init_params,MixDrmParams * drm_init_params)1460 MIX_RESULT mix_video_initialize(MixVideo * mix, MixCodecMode mode,
1461 MixVideoInitParams * init_params, MixDrmParams * drm_init_params) {
1462
1463 MixVideoClass *klass = NULL;
1464 CHECK_AND_GET_MIX_CLASS(mix, klass);
1465
1466 if (klass->initialize_func) {
1467 return klass->initialize_func(mix, mode, init_params, drm_init_params);
1468 }
1469 return MIX_RESULT_NOTIMPL;
1470
1471 }
1472
mix_video_deinitialize(MixVideo * mix)1473 MIX_RESULT mix_video_deinitialize(MixVideo * mix) {
1474
1475 MixVideoClass *klass = NULL;
1476 CHECK_AND_GET_MIX_CLASS(mix, klass);
1477
1478 if (klass->deinitialize_func) {
1479 return klass->deinitialize_func(mix);
1480 }
1481 return MIX_RESULT_NOTIMPL;
1482 }
1483
mix_video_configure(MixVideo * mix,MixVideoConfigParams * config_params,MixDrmParams * drm_config_params)1484 MIX_RESULT mix_video_configure(MixVideo * mix,
1485 MixVideoConfigParams * config_params,
1486 MixDrmParams * drm_config_params) {
1487
1488 MixVideoClass *klass = NULL;
1489 CHECK_AND_GET_MIX_CLASS(mix, klass);
1490
1491 if (klass->configure_func) {
1492 return klass->configure_func(mix, config_params, drm_config_params);
1493 }
1494 return MIX_RESULT_NOTIMPL;
1495 }
1496
mix_video_get_config(MixVideo * mix,MixVideoConfigParams ** config_params_dec)1497 MIX_RESULT mix_video_get_config(MixVideo * mix,
1498 MixVideoConfigParams ** config_params_dec) {
1499
1500 MixVideoClass *klass = NULL;
1501 CHECK_AND_GET_MIX_CLASS(mix, klass);
1502
1503 if (klass->get_config_func) {
1504 return klass->get_config_func(mix, config_params_dec);
1505 }
1506 return MIX_RESULT_NOTIMPL;
1507
1508 }
1509
mix_video_decode(MixVideo * mix,MixBuffer * bufin[],gint bufincnt,MixVideoDecodeParams * decode_params)1510 MIX_RESULT mix_video_decode(MixVideo * mix, MixBuffer * bufin[], gint bufincnt,
1511 MixVideoDecodeParams * decode_params) {
1512
1513 MixVideoClass *klass = NULL;
1514 CHECK_AND_GET_MIX_CLASS(mix, klass);
1515
1516 if (klass->decode_func) {
1517 return klass->decode_func(mix, bufin, bufincnt,
1518 decode_params);
1519 }
1520 return MIX_RESULT_NOTIMPL;
1521
1522 }
1523
mix_video_get_frame(MixVideo * mix,MixVideoFrame ** frame)1524 MIX_RESULT mix_video_get_frame(MixVideo * mix, MixVideoFrame ** frame) {
1525
1526 MixVideoClass *klass = NULL;
1527 CHECK_AND_GET_MIX_CLASS(mix, klass);
1528
1529 if (klass->get_frame_func) {
1530 return klass->get_frame_func(mix, frame);
1531 }
1532 return MIX_RESULT_NOTIMPL;
1533
1534 }
1535
mix_video_release_frame(MixVideo * mix,MixVideoFrame * frame)1536 MIX_RESULT mix_video_release_frame(MixVideo * mix, MixVideoFrame * frame) {
1537
1538 MixVideoClass *klass = NULL;
1539 CHECK_AND_GET_MIX_CLASS(mix, klass);
1540
1541 if (klass->release_frame_func) {
1542 return klass->release_frame_func(mix, frame);
1543 }
1544 return MIX_RESULT_NOTIMPL;
1545 }
1546
mix_video_render(MixVideo * mix,MixVideoRenderParams * render_params,MixVideoFrame * frame)1547 MIX_RESULT mix_video_render(MixVideo * mix,
1548 MixVideoRenderParams * render_params, MixVideoFrame *frame) {
1549
1550 MixVideoClass *klass = NULL;
1551 CHECK_AND_GET_MIX_CLASS(mix, klass);
1552
1553 if (klass->render_func) {
1554 return klass->render_func(mix, render_params, frame);
1555 }
1556 return MIX_RESULT_NOTIMPL;
1557
1558 }
1559
mix_video_encode(MixVideo * mix,MixBuffer * bufin[],gint bufincnt,MixIOVec * iovout[],gint iovoutcnt,MixVideoEncodeParams * encode_params)1560 MIX_RESULT mix_video_encode(MixVideo * mix, MixBuffer * bufin[], gint bufincnt,
1561 MixIOVec * iovout[], gint iovoutcnt,
1562 MixVideoEncodeParams * encode_params) {
1563
1564 MixVideoClass *klass = NULL;
1565 CHECK_AND_GET_MIX_CLASS(mix, klass);
1566
1567 if (klass->encode_func) {
1568 return klass->encode_func(mix, bufin, bufincnt, iovout, iovoutcnt,
1569 encode_params);
1570 }
1571 return MIX_RESULT_NOTIMPL;
1572
1573 }
1574
mix_video_flush(MixVideo * mix)1575 MIX_RESULT mix_video_flush(MixVideo * mix) {
1576
1577 MixVideoClass *klass = NULL;
1578 CHECK_AND_GET_MIX_CLASS(mix, klass);
1579
1580 if (klass->flush_func) {
1581 return klass->flush_func(mix);
1582 }
1583 return MIX_RESULT_NOTIMPL;
1584 }
1585
mix_video_eos(MixVideo * mix)1586 MIX_RESULT mix_video_eos(MixVideo * mix) {
1587
1588 MixVideoClass *klass = NULL;
1589 CHECK_AND_GET_MIX_CLASS(mix, klass);
1590
1591 if (klass->eos_func) {
1592 return klass->eos_func(mix);
1593 }
1594 return MIX_RESULT_NOTIMPL;
1595 }
1596
mix_video_get_state(MixVideo * mix,MixState * state)1597 MIX_RESULT mix_video_get_state(MixVideo * mix, MixState * state) {
1598
1599 MixVideoClass *klass = NULL;
1600 CHECK_AND_GET_MIX_CLASS(mix, klass);
1601
1602 if (klass->get_state_func) {
1603 return klass->get_state_func(mix, state);
1604 }
1605 return MIX_RESULT_NOTIMPL;
1606 }
1607
mix_video_get_mixbuffer(MixVideo * mix,MixBuffer ** buf)1608 MIX_RESULT mix_video_get_mixbuffer(MixVideo * mix, MixBuffer ** buf) {
1609
1610 MixVideoClass *klass = NULL;
1611 CHECK_AND_GET_MIX_CLASS(mix, klass);
1612
1613 if (klass->get_mix_buffer_func) {
1614 return klass->get_mix_buffer_func(mix, buf);
1615 }
1616 return MIX_RESULT_NOTIMPL;
1617 }
1618
mix_video_release_mixbuffer(MixVideo * mix,MixBuffer * buf)1619 MIX_RESULT mix_video_release_mixbuffer(MixVideo * mix, MixBuffer * buf) {
1620
1621 MixVideoClass *klass = NULL;
1622 CHECK_AND_GET_MIX_CLASS(mix, klass);
1623
1624 if (klass->release_mix_buffer_func) {
1625 return klass->release_mix_buffer_func(mix, buf);
1626 }
1627 return MIX_RESULT_NOTIMPL;
1628 }
1629
mix_video_get_max_coded_buffer_size(MixVideo * mix,guint * bufsize)1630 MIX_RESULT mix_video_get_max_coded_buffer_size(MixVideo * mix, guint *bufsize) {
1631
1632 MixVideoClass *klass = MIX_VIDEO_GET_CLASS(mix);
1633
1634 if (klass->get_max_coded_buffer_size_func) {
1635 return klass->get_max_coded_buffer_size_func(mix, bufsize);
1636 }
1637 return MIX_RESULT_NOTIMPL;
1638 }
1639