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 Intels 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 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 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 171 MixVideo *mix_video_new(void) { 172 173 MixVideo *ret = g_object_new(MIX_TYPE_VIDEO, NULL); 174 175 return ret; 176 } 177 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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