1 /* 2 * 3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /* 19 * @file ExynosVideoDecoder.c 20 * @brief 21 * @author Jinsung Yang (jsgood.yang (at) samsung.com) 22 * @version 1.0.0 23 * @history 24 * 2012.01.15: Initial Version 25 */ 26 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <unistd.h> 30 #include <string.h> 31 #include <fcntl.h> 32 33 #include <sys/types.h> 34 #include <sys/stat.h> 35 #include <sys/ioctl.h> 36 #include <sys/mman.h> 37 #include <pthread.h> 38 39 #include <sys/poll.h> 40 41 #include "ion.h" 42 #include "ExynosVideoApi.h" 43 #include "ExynosVideoDec.h" 44 #include "OMX_Core.h" 45 46 /* #define LOG_NDEBUG 0 */ 47 #define LOG_TAG "ExynosVideoDecoder" 48 #include <utils/Log.h> 49 50 #define MAX_OUTPUTBUFFER_COUNT 32 51 52 /* 53 * [Common] __CodingType_To_V4L2PixelFormat 54 */ 55 static unsigned int __CodingType_To_V4L2PixelFormat(ExynosVideoCodingType codingType) 56 { 57 unsigned int pixelformat = V4L2_PIX_FMT_H264; 58 59 switch (codingType) { 60 case VIDEO_CODING_AVC: 61 pixelformat = V4L2_PIX_FMT_H264; 62 break; 63 case VIDEO_CODING_MPEG4: 64 pixelformat = V4L2_PIX_FMT_MPEG4; 65 break; 66 case VIDEO_CODING_VP8: 67 pixelformat = V4L2_PIX_FMT_VP8; 68 break; 69 case VIDEO_CODING_H263: 70 pixelformat = V4L2_PIX_FMT_H263; 71 break; 72 case VIDEO_CODING_VC1: 73 pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G; 74 break; 75 case VIDEO_CODING_VC1_RCV: 76 pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L; 77 break; 78 case VIDEO_CODING_MPEG2: 79 pixelformat = V4L2_PIX_FMT_MPEG2; 80 break; 81 default: 82 pixelformat = V4L2_PIX_FMT_H264; 83 break; 84 } 85 86 return pixelformat; 87 } 88 89 /* 90 * [Common] __ColorFormatType_To_V4L2PixelFormat 91 */ 92 static unsigned int __ColorFormatType_To_V4L2PixelFormat(ExynosVideoColorFormatType colorFormatType) 93 { 94 unsigned int pixelformat = V4L2_PIX_FMT_NV12M; 95 96 switch (colorFormatType) { 97 case VIDEO_COLORFORMAT_NV12_TILED: 98 pixelformat = V4L2_PIX_FMT_NV12MT_16X16; 99 break; 100 case VIDEO_COLORFORMAT_NV21: 101 pixelformat = V4L2_PIX_FMT_NV21M; 102 break; 103 case VIDEO_COLORFORMAT_NV12: 104 default: 105 pixelformat = V4L2_PIX_FMT_NV12M; 106 break; 107 } 108 109 return pixelformat; 110 } 111 112 /* 113 * [Decoder OPS] Init 114 */ 115 static void *MFC_Decoder_Init(int nMemoryType) 116 { 117 ExynosVideoDecContext *pCtx = NULL; 118 pthread_mutex_t *pMutex = NULL; 119 int needCaps = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING); 120 121 pCtx = (ExynosVideoDecContext *)malloc(sizeof(*pCtx)); 122 if (pCtx == NULL) { 123 ALOGE("%s: Failed to allocate decoder context buffer", __func__); 124 goto EXIT_ALLOC_FAIL; 125 } 126 127 memset(pCtx, 0, sizeof(*pCtx)); 128 129 pCtx->hDec = exynos_v4l2_open_devname(VIDEO_DECODER_NAME, O_RDWR, 0); 130 if (pCtx->hDec < 0) { 131 ALOGE("%s: Failed to open decoder device", __func__); 132 goto EXIT_OPEN_FAIL; 133 } 134 135 if (!exynos_v4l2_querycap(pCtx->hDec, needCaps)) { 136 ALOGE("%s: Failed to querycap", __func__); 137 goto EXIT_QUERYCAP_FAIL; 138 } 139 140 pCtx->bStreamonInbuf = VIDEO_FALSE; 141 pCtx->bStreamonOutbuf = VIDEO_FALSE; 142 143 pCtx->nMemoryType = nMemoryType; 144 145 pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); 146 if (pMutex == NULL) { 147 ALOGE("%s: Failed to allocate mutex about input buffer", __func__); 148 goto EXIT_QUERYCAP_FAIL; 149 } 150 if (pthread_mutex_init(pMutex, NULL) != 0) { 151 free(pMutex); 152 goto EXIT_QUERYCAP_FAIL; 153 } 154 pCtx->pInMutex = (void*)pMutex; 155 156 pMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); 157 if (pMutex == NULL) { 158 ALOGE("%s: Failed to allocate mutex about output buffer", __func__); 159 goto EXIT_QUERYCAP_FAIL; 160 } 161 if (pthread_mutex_init(pMutex, NULL) != 0) { 162 free(pMutex); 163 goto EXIT_QUERYCAP_FAIL; 164 } 165 pCtx->pOutMutex = (void*)pMutex; 166 167 pCtx->hIONHandle = (void*)ion_client_create(); 168 pCtx->nPrivateDataShareFD = ion_alloc((ion_client)pCtx->hIONHandle, 169 sizeof(PrivateDataShareBuffer) * VIDEO_BUFFER_MAX_NUM, 0, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED); 170 pCtx->nPrivateDataShareAddress = 171 ion_map(pCtx->nPrivateDataShareFD, sizeof(PrivateDataShareBuffer) * VIDEO_BUFFER_MAX_NUM, 0); 172 memset(pCtx->nPrivateDataShareAddress, -1, sizeof(PrivateDataShareBuffer) * VIDEO_BUFFER_MAX_NUM); 173 174 return (void *)pCtx; 175 176 EXIT_QUERYCAP_FAIL: 177 if (pCtx->pInMutex != NULL) { 178 pthread_mutex_destroy(pCtx->pInMutex); 179 free(pCtx->pInMutex); 180 } 181 182 if (pCtx->pOutMutex != NULL) { 183 pthread_mutex_destroy(pCtx->pOutMutex); 184 free(pCtx->pOutMutex); 185 } 186 187 close(pCtx->hDec); 188 189 EXIT_OPEN_FAIL: 190 free(pCtx); 191 192 EXIT_ALLOC_FAIL: 193 return NULL; 194 } 195 196 /* 197 * [Decoder OPS] Finalize 198 */ 199 static ExynosVideoErrorType MFC_Decoder_Finalize(void *pHandle) 200 { 201 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 202 ExynosVideoPlane *pVideoPlane = NULL; 203 pthread_mutex_t *pMutex = NULL; 204 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 205 int i, j; 206 207 if (pCtx == NULL) { 208 ALOGE("%s: Video context info must be supplied", __func__); 209 ret = VIDEO_ERROR_BADPARAM; 210 goto EXIT; 211 } 212 213 ion_unmap(pCtx->nPrivateDataShareAddress, sizeof(PrivateDataShareBuffer) * VIDEO_BUFFER_MAX_NUM); 214 ion_free(pCtx->nPrivateDataShareFD); 215 ion_client_destroy((ion_client)pCtx->hIONHandle); 216 217 if (pCtx->pOutMutex != NULL) { 218 pMutex = (pthread_mutex_t*)pCtx->pOutMutex; 219 pthread_mutex_destroy(pMutex); 220 free(pMutex); 221 pCtx->pOutMutex = NULL; 222 } 223 224 if (pCtx->pInMutex != NULL) { 225 pMutex = (pthread_mutex_t*)pCtx->pInMutex; 226 pthread_mutex_destroy(pMutex); 227 free(pMutex); 228 pCtx->pInMutex = NULL; 229 } 230 231 if (pCtx->bShareInbuf == VIDEO_FALSE) { 232 for (i = 0; i < pCtx->nInbufs; i++) { 233 for (j = 0; j < VIDEO_DECODER_INBUF_PLANES; j++) { 234 pVideoPlane = &pCtx->pInbuf[i].planes[j]; 235 if (pVideoPlane->addr != NULL) { 236 munmap(pVideoPlane->addr, pVideoPlane->allocSize); 237 pVideoPlane->addr = NULL; 238 pVideoPlane->allocSize = 0; 239 pVideoPlane->dataSize = 0; 240 } 241 242 pCtx->pInbuf[i].pGeometry = NULL; 243 pCtx->pInbuf[i].bQueued = VIDEO_FALSE; 244 pCtx->pInbuf[i].bRegistered = VIDEO_FALSE; 245 } 246 } 247 } 248 249 if (pCtx->bShareOutbuf == VIDEO_FALSE) { 250 for (i = 0; i < pCtx->nOutbufs; i++) { 251 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) { 252 pVideoPlane = &pCtx->pOutbuf[i].planes[j]; 253 if (pVideoPlane->addr != NULL) { 254 munmap(pVideoPlane->addr, pVideoPlane->allocSize); 255 pVideoPlane->addr = NULL; 256 pVideoPlane->allocSize = 0; 257 pVideoPlane->dataSize = 0; 258 } 259 260 pCtx->pOutbuf[i].pGeometry = NULL; 261 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; 262 pCtx->pOutbuf[i].bRegistered = VIDEO_FALSE; 263 } 264 } 265 } 266 267 if (pCtx->pInbuf != NULL) 268 free(pCtx->pInbuf); 269 270 if (pCtx->pOutbuf != NULL) 271 free(pCtx->pOutbuf); 272 273 if (pCtx->hDec > 0) 274 close(pCtx->hDec); 275 276 free(pCtx); 277 278 EXIT: 279 return ret; 280 } 281 282 /* 283 * [Decoder OPS] Set Frame Tag 284 */ 285 static ExynosVideoErrorType MFC_Decoder_Set_FrameTag( 286 void *pHandle, 287 int frameTag) 288 { 289 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 290 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 291 292 if (pCtx == NULL) { 293 ALOGE("%s: Video context info must be supplied", __func__); 294 ret = VIDEO_ERROR_BADPARAM; 295 goto EXIT; 296 } 297 298 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, frameTag) != 0) { 299 ret = VIDEO_ERROR_APIFAIL; 300 goto EXIT; 301 } 302 303 EXIT: 304 return ret; 305 } 306 307 /* 308 * [Decoder OPS] Get Frame Tag 309 */ 310 static int MFC_Decoder_Get_FrameTag(void *pHandle) 311 { 312 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 313 int frameTag = -1; 314 315 if (pCtx == NULL) { 316 ALOGE("%s: Video context info must be supplied", __func__); 317 goto EXIT; 318 } 319 320 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG, &frameTag); 321 322 EXIT: 323 return frameTag; 324 } 325 326 /* 327 * [Decoder OPS] Get Buffer Count 328 */ 329 static int MFC_Decoder_Get_ActualBufferCount(void *pHandle) 330 { 331 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 332 int bufferCount = -1; 333 334 if (pCtx == NULL) { 335 ALOGE("%s: Video context info must be supplied", __func__); 336 goto EXIT; 337 } 338 339 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, &bufferCount); 340 341 EXIT: 342 return bufferCount; 343 } 344 345 /* 346 * [Decoder OPS] Set Display Delay 347 */ 348 static ExynosVideoErrorType MFC_Decoder_Set_DisplayDelay( 349 void *pHandle, 350 int delay) 351 { 352 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 353 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 354 355 if (pCtx == NULL) { 356 ALOGE("%s: Video context info must be supplied", __func__); 357 ret = VIDEO_ERROR_BADPARAM; 358 goto EXIT; 359 } 360 361 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY, delay) != 0) { 362 ret = VIDEO_ERROR_APIFAIL; 363 goto EXIT; 364 } 365 366 EXIT: 367 return ret; 368 } 369 370 /* 371 * [Decoder OPS] Set I-Frame Decoding 372 */ 373 static ExynosVideoErrorType MFC_Decoder_Set_IFrameDecoding( 374 void *pHandle) 375 { 376 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 377 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 378 379 if (pCtx == NULL) { 380 ALOGE("%s: Video context info must be supplied", __func__); 381 ret = VIDEO_ERROR_BADPARAM; 382 goto EXIT; 383 } 384 385 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_I_FRAME_DECODING, 1) != 0) { 386 ret = VIDEO_ERROR_APIFAIL; 387 goto EXIT; 388 } 389 390 EXIT: 391 return ret; 392 } 393 394 /* 395 * [Decoder OPS] Enable Packed PB 396 */ 397 static ExynosVideoErrorType MFC_Decoder_Enable_PackedPB(void *pHandle) 398 { 399 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 400 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 401 402 if (pCtx == NULL) { 403 ALOGE("%s: Video context info must be supplied", __func__); 404 ret = VIDEO_ERROR_BADPARAM; 405 goto EXIT; 406 } 407 408 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB, 1) != 0) { 409 ret = VIDEO_ERROR_APIFAIL; 410 goto EXIT; 411 } 412 413 EXIT: 414 return ret; 415 } 416 417 /* 418 * [Decoder OPS] Enable Loop Filter 419 */ 420 static ExynosVideoErrorType MFC_Decoder_Enable_LoopFilter(void *pHandle) 421 { 422 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 423 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 424 425 if (pCtx == NULL) { 426 ALOGE("%s: Video context info must be supplied", __func__); 427 ret = VIDEO_ERROR_BADPARAM; 428 goto EXIT; 429 } 430 431 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 1) != 0) { 432 ret = VIDEO_ERROR_APIFAIL; 433 goto EXIT; 434 } 435 436 EXIT: 437 return ret; 438 } 439 440 /* 441 * [Decoder OPS] Enable Slice Mode 442 */ 443 static ExynosVideoErrorType MFC_Decoder_Enable_SliceMode(void *pHandle) 444 { 445 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 446 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 447 448 if (pCtx == NULL) { 449 ALOGE("%s: Video context info must be supplied", __func__); 450 ret = VIDEO_ERROR_BADPARAM; 451 goto EXIT; 452 } 453 454 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE, 1) != 0) { 455 ret = VIDEO_ERROR_APIFAIL; 456 goto EXIT; 457 } 458 459 EXIT: 460 return ret; 461 } 462 463 /* 464 * [Decoder OPS] Enable SEI Parsing 465 */ 466 static ExynosVideoErrorType MFC_Decoder_Enable_SEIParsing(void *pHandle) 467 { 468 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 469 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 470 471 if (pCtx == NULL) { 472 ALOGE("%s: Video context info must be supplied", __func__); 473 ret = VIDEO_ERROR_BADPARAM; 474 goto EXIT; 475 } 476 477 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING, 1) != 0) { 478 ret = VIDEO_ERROR_APIFAIL; 479 goto EXIT; 480 } 481 482 EXIT: 483 return ret; 484 } 485 486 /* 487 * [Decoder OPS] Get Frame Packing information 488 */ 489 static ExynosVideoErrorType MFC_Decoder_Get_FramePackingInfo( 490 void *pHandle, 491 ExynosVideoFramePacking *pFramePacking) 492 { 493 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 494 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 495 496 struct v4l2_ext_control ext_ctrl[FRAME_PACK_SEI_INFO_NUM]; 497 struct v4l2_ext_controls ext_ctrls; 498 499 int seiAvailable, seiInfo, seiGridPos, i; 500 unsigned int seiArgmtId; 501 502 503 if ((pCtx == NULL) || (pFramePacking == NULL)) { 504 ALOGE("%s: Video context info or FramePacking pointer must be supplied", __func__); 505 ret = VIDEO_ERROR_BADPARAM; 506 goto EXIT; 507 } 508 509 memset(pFramePacking, 0, sizeof(*pFramePacking)); 510 memset(ext_ctrl, 0, (sizeof(struct v4l2_ext_control) * FRAME_PACK_SEI_INFO_NUM)); 511 512 ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; 513 ext_ctrls.count = FRAME_PACK_SEI_INFO_NUM; 514 ext_ctrls.controls = ext_ctrl; 515 ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL; 516 ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID; 517 ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO; 518 ext_ctrl[3].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS; 519 520 if (exynos_v4l2_g_ext_ctrl(pCtx->hDec, &ext_ctrls) != 0) { 521 ret = VIDEO_ERROR_APIFAIL; 522 goto EXIT; 523 } 524 525 seiAvailable = ext_ctrl[0].value; 526 seiArgmtId = ext_ctrl[1].value; 527 seiInfo = ext_ctrl[2].value; 528 seiGridPos = ext_ctrl[3].value; 529 530 pFramePacking->available = seiAvailable; 531 pFramePacking->arrangement_id = seiArgmtId; 532 533 pFramePacking->arrangement_cancel_flag = OPERATE_BIT(seiInfo, 0x1, 0); 534 pFramePacking->arrangement_type = OPERATE_BIT(seiInfo, 0x3f, 1); 535 pFramePacking->quincunx_sampling_flag = OPERATE_BIT(seiInfo, 0x1, 8); 536 pFramePacking->content_interpretation_type = OPERATE_BIT(seiInfo, 0x3f, 9); 537 pFramePacking->spatial_flipping_flag = OPERATE_BIT(seiInfo, 0x1, 15); 538 pFramePacking->frame0_flipped_flag = OPERATE_BIT(seiInfo, 0x1, 16); 539 pFramePacking->field_views_flag = OPERATE_BIT(seiInfo, 0x1, 17); 540 pFramePacking->current_frame_is_frame0_flag = OPERATE_BIT(seiInfo, 0x1, 18); 541 542 pFramePacking->frame0_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 0); 543 pFramePacking->frame0_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 4); 544 pFramePacking->frame1_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 8); 545 pFramePacking->frame1_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 12); 546 547 EXIT: 548 return ret; 549 } 550 551 /* 552 * [Decoder Buffer OPS] Enable Cacheable (Input) 553 */ 554 static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Inbuf(void *pHandle) 555 { 556 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 557 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 558 559 if (pCtx == NULL) { 560 ALOGE("%s: Video context info must be supplied", __func__); 561 ret = VIDEO_ERROR_BADPARAM; 562 goto EXIT; 563 } 564 565 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 2) != 0) { 566 ret = VIDEO_ERROR_APIFAIL; 567 goto EXIT; 568 } 569 570 EXIT: 571 return ret; 572 } 573 574 /* 575 * [Decoder Buffer OPS] Enable Cacheable (Output) 576 */ 577 static ExynosVideoErrorType MFC_Decoder_Enable_Cacheable_Outbuf(void *pHandle) 578 { 579 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 580 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 581 582 if (pCtx == NULL) { 583 ALOGE("%s: Video context info must be supplied", __func__); 584 ret = VIDEO_ERROR_BADPARAM; 585 goto EXIT; 586 } 587 588 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_CACHEABLE, 1) != 0) { 589 ret = VIDEO_ERROR_APIFAIL; 590 goto EXIT; 591 } 592 593 EXIT: 594 return ret; 595 } 596 597 /* 598 * [Decoder Buffer OPS] Set Shareable Buffer (Input) 599 */ 600 static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Inbuf(void *pHandle) 601 { 602 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 603 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 604 605 if (pCtx == NULL) { 606 ALOGE("%s: Video context info must be supplied", __func__); 607 ret = VIDEO_ERROR_BADPARAM; 608 goto EXIT; 609 } 610 611 pCtx->bShareInbuf = VIDEO_TRUE; 612 613 EXIT: 614 return ret; 615 } 616 617 /* 618 * [Decoder Buffer OPS] Set Shareable Buffer (Output) 619 */ 620 static ExynosVideoErrorType MFC_Decoder_Set_Shareable_Outbuf(void *pHandle) 621 { 622 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 623 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 624 625 if (pCtx == NULL) { 626 ALOGE("%s: Video context info must be supplied", __func__); 627 ret = VIDEO_ERROR_BADPARAM; 628 goto EXIT; 629 } 630 631 pCtx->bShareOutbuf = VIDEO_TRUE; 632 633 EXIT: 634 return ret; 635 } 636 637 /* 638 * [Decoder Buffer OPS] Get Buffer (Input) 639 */ 640 static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Inbuf( 641 void *pHandle, 642 int nIndex, 643 ExynosVideoBuffer **pBuffer) 644 { 645 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 646 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 647 648 if (pCtx == NULL) { 649 ALOGE("%s: Video context info must be supplied", __func__); 650 *pBuffer = NULL; 651 ret = VIDEO_ERROR_BADPARAM; 652 goto EXIT; 653 } 654 655 if (pCtx->nInbufs <= nIndex) { 656 *pBuffer = NULL; 657 ret = VIDEO_ERROR_BADPARAM; 658 goto EXIT; 659 } 660 661 *pBuffer = (ExynosVideoBuffer *)&pCtx->pInbuf[nIndex]; 662 663 EXIT: 664 return ret; 665 } 666 667 /* 668 * [Decoder Buffer OPS] Get Buffer (Output) 669 */ 670 static ExynosVideoErrorType MFC_Decoder_Get_Buffer_Outbuf( 671 void *pHandle, 672 int nIndex, 673 ExynosVideoBuffer **pBuffer) 674 { 675 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 676 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 677 678 if (pCtx == NULL) { 679 ALOGE("%s: Video context info must be supplied", __func__); 680 *pBuffer = NULL; 681 ret = VIDEO_ERROR_BADPARAM; 682 goto EXIT; 683 } 684 685 if (pCtx->nOutbufs <= nIndex) { 686 *pBuffer = NULL; 687 ret = VIDEO_ERROR_BADPARAM; 688 goto EXIT; 689 } 690 691 *pBuffer = (ExynosVideoBuffer *)&pCtx->pOutbuf[nIndex]; 692 693 EXIT: 694 return ret; 695 } 696 697 /* 698 * [Decoder Buffer OPS] Set Geometry (Input) 699 */ 700 static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Inbuf( 701 void *pHandle, 702 ExynosVideoGeometry *bufferConf) 703 { 704 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 705 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 706 707 struct v4l2_format fmt; 708 709 if (pCtx == NULL) { 710 ALOGE("%s: Video context info must be supplied", __func__); 711 ret = VIDEO_ERROR_BADPARAM; 712 goto EXIT; 713 } 714 715 if (bufferConf == NULL) { 716 ALOGE("%s: Buffer geometry must be supplied", __func__); 717 ret = VIDEO_ERROR_BADPARAM; 718 goto EXIT; 719 } 720 721 memset(&fmt, 0, sizeof(fmt)); 722 723 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 724 fmt.fmt.pix_mp.pixelformat = __CodingType_To_V4L2PixelFormat(bufferConf->eCompressionFormat); 725 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = bufferConf->nSizeImage; 726 727 if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) { 728 ret = VIDEO_ERROR_APIFAIL; 729 goto EXIT; 730 } 731 732 memcpy(&pCtx->inbufGeometry, bufferConf, sizeof(pCtx->inbufGeometry)); 733 734 EXIT: 735 return ret; 736 } 737 738 /* 739 * [Decoder Buffer OPS] Set Geometry (Output) 740 */ 741 static ExynosVideoErrorType MFC_Decoder_Set_Geometry_Outbuf( 742 void *pHandle, 743 ExynosVideoGeometry *bufferConf) 744 { 745 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 746 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 747 748 struct v4l2_format fmt; 749 750 if (pCtx == NULL) { 751 ALOGE("%s: Video context info must be supplied", __func__); 752 ret = VIDEO_ERROR_BADPARAM; 753 goto EXIT; 754 } 755 756 if (bufferConf == NULL) { 757 ALOGE("%s: Buffer geometry must be supplied", __func__); 758 ret = VIDEO_ERROR_BADPARAM; 759 goto EXIT; 760 } 761 762 memset(&fmt, 0, sizeof(fmt)); 763 764 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 765 fmt.fmt.pix_mp.pixelformat = __ColorFormatType_To_V4L2PixelFormat(bufferConf->eColorFormat); 766 767 if (exynos_v4l2_s_fmt(pCtx->hDec, &fmt) != 0) { 768 ret = VIDEO_ERROR_APIFAIL; 769 goto EXIT; 770 } 771 772 memcpy(&pCtx->outbufGeometry, bufferConf, sizeof(pCtx->outbufGeometry)); 773 774 EXIT: 775 return ret; 776 } 777 778 /* 779 * [Decoder Buffer OPS] Get Geometry (Output) 780 */ 781 static ExynosVideoErrorType MFC_Decoder_Get_Geometry_Outbuf( 782 void *pHandle, 783 ExynosVideoGeometry *bufferConf) 784 { 785 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 786 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 787 788 struct v4l2_format fmt; 789 struct v4l2_crop crop; 790 791 if (pCtx == NULL) { 792 ALOGE("%s: Video context info must be supplied", __func__); 793 ret = VIDEO_ERROR_BADPARAM; 794 goto EXIT; 795 } 796 797 if (bufferConf == NULL) { 798 ALOGE("%s: Buffer geometry must be supplied", __func__); 799 ret = VIDEO_ERROR_BADPARAM; 800 goto EXIT; 801 } 802 803 memset(&fmt, 0, sizeof(fmt)); 804 memset(&crop, 0, sizeof(crop)); 805 806 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 807 if (exynos_v4l2_g_fmt(pCtx->hDec, &fmt) != 0) { 808 ret = VIDEO_ERROR_APIFAIL; 809 goto EXIT; 810 } 811 812 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 813 if (exynos_v4l2_g_crop(pCtx->hDec, &crop) != 0) { 814 ret = VIDEO_ERROR_APIFAIL; 815 goto EXIT; 816 } 817 818 bufferConf->nFrameWidth = fmt.fmt.pix_mp.width; 819 bufferConf->nFrameHeight = fmt.fmt.pix_mp.height; 820 821 bufferConf->cropRect.nTop = crop.c.top; 822 bufferConf->cropRect.nLeft = crop.c.left; 823 bufferConf->cropRect.nWidth = crop.c.width; 824 bufferConf->cropRect.nHeight = crop.c.height; 825 826 EXIT: 827 return ret; 828 } 829 830 /* 831 * [Decoder Buffer OPS] Setup (Input) 832 */ 833 static ExynosVideoErrorType MFC_Decoder_Setup_Inbuf( 834 void *pHandle, 835 unsigned int nBufferCount) 836 { 837 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 838 ExynosVideoPlane *pVideoPlane = NULL; 839 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 840 841 struct v4l2_requestbuffers req; 842 struct v4l2_buffer buf; 843 struct v4l2_plane planes[VIDEO_DECODER_INBUF_PLANES]; 844 int i; 845 846 if (pCtx == NULL) { 847 ALOGE("%s: Video context info must be supplied", __func__); 848 ret = VIDEO_ERROR_BADPARAM; 849 goto EXIT; 850 } 851 852 if (nBufferCount == 0) { 853 ALOGE("%s: Buffer count must be greater than 0", __func__); 854 ret = VIDEO_ERROR_BADPARAM; 855 goto EXIT; 856 } 857 858 ALOGV("%s: setting up inbufs (%d) shared=%s\n", __func__, nBufferCount, 859 pCtx->bShareInbuf ? "true" : "false"); 860 861 memset(&req, 0, sizeof(req)); 862 863 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 864 req.count = nBufferCount; 865 866 if (pCtx->bShareInbuf == VIDEO_TRUE) 867 req.memory = pCtx->nMemoryType; 868 else 869 req.memory = V4L2_MEMORY_MMAP; 870 871 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) { 872 ret = VIDEO_ERROR_APIFAIL; 873 goto EXIT; 874 } 875 876 if (req.count != nBufferCount) { 877 ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count); 878 ret = VIDEO_ERROR_NOMEM; 879 goto EXIT; 880 } 881 882 pCtx->nInbufs = (int)req.count; 883 884 pCtx->pInbuf = malloc(sizeof(*pCtx->pInbuf) * pCtx->nInbufs); 885 if (pCtx->pInbuf == NULL) { 886 ALOGE("Failed to allocate input buffer context"); 887 ret = VIDEO_ERROR_NOMEM; 888 goto EXIT; 889 } 890 memset(pCtx->pInbuf, 0, sizeof(*pCtx->pInbuf) * pCtx->nInbufs); 891 892 memset(&buf, 0, sizeof(buf)); 893 894 if (pCtx->bShareInbuf == VIDEO_FALSE) { 895 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 896 buf.memory = V4L2_MEMORY_MMAP; 897 buf.m.planes = planes; 898 buf.length = VIDEO_DECODER_INBUF_PLANES; 899 900 for (i = 0; i < pCtx->nInbufs; i++) { 901 buf.index = i; 902 if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) { 903 ret = VIDEO_ERROR_APIFAIL; 904 goto EXIT; 905 } 906 907 pVideoPlane = &pCtx->pInbuf[i].planes[0]; 908 909 pVideoPlane->addr = mmap(NULL, 910 buf.m.planes[0].length, PROT_READ | PROT_WRITE, 911 MAP_SHARED, pCtx->hDec, buf.m.planes[0].m.mem_offset); 912 913 if (pVideoPlane->addr == MAP_FAILED) { 914 ret = VIDEO_ERROR_MAPFAIL; 915 goto EXIT; 916 } 917 918 pVideoPlane->allocSize = buf.m.planes[0].length; 919 pVideoPlane->dataSize = 0; 920 921 pCtx->pInbuf[i].pGeometry = &pCtx->inbufGeometry; 922 pCtx->pInbuf[i].bQueued = VIDEO_FALSE; 923 pCtx->pInbuf[i].bRegistered = VIDEO_TRUE; 924 } 925 } 926 927 return ret; 928 929 EXIT: 930 if ((pCtx != NULL) && (pCtx->pInbuf != NULL)) { 931 if (pCtx->bShareInbuf == VIDEO_FALSE) { 932 for (i = 0; i < pCtx->nInbufs; i++) { 933 pVideoPlane = &pCtx->pInbuf[i].planes[0]; 934 if (pVideoPlane->addr == MAP_FAILED) { 935 pVideoPlane->addr = NULL; 936 break; 937 } 938 939 munmap(pVideoPlane->addr, pVideoPlane->allocSize); 940 } 941 } 942 943 free(pCtx->pInbuf); 944 } 945 946 return ret; 947 } 948 949 /* 950 * [Decoder Buffer OPS] Setup (Output) 951 */ 952 static ExynosVideoErrorType MFC_Decoder_Setup_Outbuf( 953 void *pHandle, 954 unsigned int nBufferCount) 955 { 956 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 957 ExynosVideoPlane *pVideoPlane = NULL; 958 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 959 960 struct v4l2_requestbuffers req; 961 struct v4l2_buffer buf; 962 struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES]; 963 int i, j; 964 965 if (pCtx == NULL) { 966 ALOGE("%s: Video context info must be supplied", __func__); 967 ret = VIDEO_ERROR_BADPARAM; 968 goto EXIT; 969 } 970 971 if (nBufferCount == 0) { 972 nBufferCount = MAX_OUTPUTBUFFER_COUNT; 973 ALOGV("%s: Change buffer count %d", __func__, nBufferCount); 974 } 975 976 ALOGV("%s: setting up outbufs (%d) shared=%s\n", __func__, nBufferCount, 977 pCtx->bShareOutbuf ? "true" : "false"); 978 979 memset(&req, 0, sizeof(req)); 980 981 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 982 req.count = nBufferCount; 983 984 if (pCtx->bShareOutbuf == VIDEO_TRUE) 985 req.memory = pCtx->nMemoryType; 986 else 987 req.memory = V4L2_MEMORY_MMAP; 988 989 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) { 990 ret = VIDEO_ERROR_APIFAIL; 991 goto EXIT; 992 } 993 994 if (req.count != nBufferCount) { 995 ALOGE("%s: asked for %d, got %d\n", __func__, nBufferCount, req.count); 996 ret = VIDEO_ERROR_NOMEM; 997 goto EXIT; 998 } 999 1000 pCtx->nOutbufs = req.count; 1001 1002 pCtx->pOutbuf = malloc(sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs); 1003 if (pCtx->pOutbuf == NULL) { 1004 ALOGE("Failed to allocate output buffer context"); 1005 ret = VIDEO_ERROR_NOMEM; 1006 goto EXIT; 1007 } 1008 memset(pCtx->pOutbuf, 0, sizeof(*pCtx->pOutbuf) * pCtx->nOutbufs); 1009 1010 memset(&buf, 0, sizeof(buf)); 1011 1012 if (pCtx->bShareOutbuf == VIDEO_FALSE) { 1013 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1014 buf.memory = V4L2_MEMORY_MMAP; 1015 buf.m.planes = planes; 1016 buf.length = VIDEO_DECODER_OUTBUF_PLANES; 1017 1018 for (i = 0; i < pCtx->nOutbufs; i++) { 1019 buf.index = i; 1020 if (exynos_v4l2_querybuf(pCtx->hDec, &buf) != 0) { 1021 ret = VIDEO_ERROR_APIFAIL; 1022 goto EXIT; 1023 } 1024 1025 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) { 1026 pVideoPlane = &pCtx->pOutbuf[i].planes[j]; 1027 pVideoPlane->addr = mmap(NULL, 1028 buf.m.planes[j].length, PROT_READ | PROT_WRITE, 1029 MAP_SHARED, pCtx->hDec, buf.m.planes[j].m.mem_offset); 1030 1031 if (pVideoPlane->addr == MAP_FAILED) { 1032 ret = VIDEO_ERROR_MAPFAIL; 1033 goto EXIT; 1034 } 1035 1036 pVideoPlane->allocSize = buf.m.planes[j].length; 1037 pVideoPlane->dataSize = 0; 1038 } 1039 1040 pCtx->pOutbuf[i].pGeometry = &pCtx->outbufGeometry; 1041 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; 1042 pCtx->pOutbuf[i].bSlotUsed = VIDEO_FALSE; 1043 pCtx->pOutbuf[i].nIndexUseCnt = 0; 1044 pCtx->pOutbuf[i].bRegistered = VIDEO_TRUE; 1045 } 1046 } 1047 1048 return ret; 1049 1050 EXIT: 1051 if ((pCtx != NULL) && (pCtx->pOutbuf != NULL)) { 1052 if (pCtx->bShareOutbuf == VIDEO_FALSE) { 1053 for (i = 0; i < pCtx->nOutbufs; i++) { 1054 for (j = 0; j < VIDEO_DECODER_OUTBUF_PLANES; j++) { 1055 pVideoPlane = &pCtx->pOutbuf[i].planes[j]; 1056 if (pVideoPlane->addr == MAP_FAILED) { 1057 pVideoPlane->addr = NULL; 1058 break; 1059 } 1060 1061 munmap(pVideoPlane->addr, pVideoPlane->allocSize); 1062 } 1063 } 1064 } 1065 1066 free(pCtx->pOutbuf); 1067 pCtx->pOutbuf = NULL; 1068 } 1069 1070 return ret; 1071 } 1072 1073 /* 1074 * [Decoder Buffer OPS] Run (Input) 1075 */ 1076 static ExynosVideoErrorType MFC_Decoder_Run_Inbuf(void *pHandle) 1077 { 1078 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1079 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1080 1081 if (pCtx == NULL) { 1082 ALOGE("%s: Video context info must be supplied", __func__); 1083 ret = VIDEO_ERROR_BADPARAM; 1084 goto EXIT; 1085 } 1086 1087 if (pCtx->bStreamonInbuf == VIDEO_FALSE) { 1088 if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) { 1089 ALOGE("%s: Failed to streamon for input buffer", __func__); 1090 ret = VIDEO_ERROR_APIFAIL; 1091 goto EXIT; 1092 } 1093 pCtx->bStreamonInbuf = VIDEO_TRUE; 1094 } 1095 1096 EXIT: 1097 return ret; 1098 } 1099 1100 /* 1101 * [Decoder Buffer OPS] Run (Output) 1102 */ 1103 static ExynosVideoErrorType MFC_Decoder_Run_Outbuf(void *pHandle) 1104 { 1105 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1106 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1107 1108 if (pCtx == NULL) { 1109 ALOGE("%s: Video context info must be supplied", __func__); 1110 ret = VIDEO_ERROR_BADPARAM; 1111 goto EXIT; 1112 } 1113 1114 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) { 1115 if (exynos_v4l2_streamon(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) { 1116 ALOGE("%s: Failed to streamon for output buffer", __func__); 1117 ret = VIDEO_ERROR_APIFAIL; 1118 goto EXIT; 1119 } 1120 pCtx->bStreamonOutbuf = VIDEO_TRUE; 1121 } 1122 1123 EXIT: 1124 return ret; 1125 } 1126 1127 /* 1128 * [Decoder Buffer OPS] Stop (Input) 1129 */ 1130 static ExynosVideoErrorType MFC_Decoder_Stop_Inbuf(void *pHandle) 1131 { 1132 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1133 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1134 int i = 0; 1135 1136 if (pCtx == NULL) { 1137 ALOGE("%s: Video context info must be supplied", __func__); 1138 ret = VIDEO_ERROR_BADPARAM; 1139 goto EXIT; 1140 } 1141 1142 if (pCtx->bStreamonInbuf == VIDEO_TRUE) { 1143 if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) != 0) { 1144 ALOGE("%s: Failed to streamoff for input buffer", __func__); 1145 ret = VIDEO_ERROR_APIFAIL; 1146 goto EXIT; 1147 } 1148 pCtx->bStreamonInbuf = VIDEO_FALSE; 1149 } 1150 1151 for (i = 0; i < pCtx->nInbufs; i++) { 1152 pCtx->pInbuf[i].bQueued = VIDEO_FALSE; 1153 } 1154 1155 EXIT: 1156 return ret; 1157 } 1158 1159 /* 1160 * [Decoder Buffer OPS] Stop (Output) 1161 */ 1162 static ExynosVideoErrorType MFC_Decoder_Stop_Outbuf(void *pHandle) 1163 { 1164 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1165 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1166 int i = 0; 1167 1168 if (pCtx == NULL) { 1169 ALOGE("%s: Video context info must be supplied", __func__); 1170 ret = VIDEO_ERROR_BADPARAM; 1171 goto EXIT; 1172 } 1173 1174 if (pCtx->bStreamonOutbuf == VIDEO_TRUE) { 1175 if (exynos_v4l2_streamoff(pCtx->hDec, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) != 0) { 1176 ALOGE("%s: Failed to streamoff for output buffer", __func__); 1177 ret = VIDEO_ERROR_APIFAIL; 1178 goto EXIT; 1179 } 1180 pCtx->bStreamonOutbuf = VIDEO_FALSE; 1181 } 1182 1183 for (i = 0; i < pCtx->nOutbufs; i++) { 1184 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; 1185 pCtx->pOutbuf[i].bSlotUsed = VIDEO_FALSE; 1186 pCtx->pOutbuf[i].nIndexUseCnt = 0; 1187 } 1188 1189 EXIT: 1190 return ret; 1191 } 1192 1193 /* 1194 * [Decoder Buffer OPS] Wait (Input) 1195 */ 1196 static ExynosVideoErrorType MFC_Decoder_Wait_Inbuf(void *pHandle) 1197 { 1198 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1199 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1200 1201 struct pollfd poll_events; 1202 int poll_state; 1203 1204 if (pCtx == NULL) { 1205 ALOGE("%s: Video context info must be supplied", __func__); 1206 ret = VIDEO_ERROR_BADPARAM; 1207 goto EXIT; 1208 } 1209 1210 poll_events.fd = pCtx->hDec; 1211 poll_events.events = POLLOUT | POLLERR; 1212 poll_events.revents = 0; 1213 1214 do { 1215 poll_state = poll((struct pollfd*)&poll_events, 1, VIDEO_DECODER_POLL_TIMEOUT); 1216 if (poll_state > 0) { 1217 if (poll_events.revents & POLLOUT) { 1218 break; 1219 } else { 1220 ALOGE("%s: Poll return error", __func__); 1221 ret = VIDEO_ERROR_POLL; 1222 break; 1223 } 1224 } else if (poll_state < 0) { 1225 ALOGE("%s: Poll state error", __func__); 1226 ret = VIDEO_ERROR_POLL; 1227 break; 1228 } 1229 } while (poll_state == 0); 1230 1231 EXIT: 1232 return ret; 1233 } 1234 1235 static ExynosVideoErrorType MFC_Decoder_Register_Inbuf( 1236 void *pHandle, 1237 ExynosVideoPlane *planes, 1238 int nPlanes) 1239 { 1240 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1241 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1242 int nIndex, plane; 1243 1244 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_DECODER_INBUF_PLANES)) { 1245 ALOGE("%s: params must be supplied", __func__); 1246 ret = VIDEO_ERROR_BADPARAM; 1247 goto EXIT; 1248 } 1249 1250 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) { 1251 if (pCtx->pInbuf[nIndex].bRegistered == VIDEO_FALSE) { 1252 for (plane = 0; plane < nPlanes; plane++) { 1253 pCtx->pInbuf[nIndex].planes[plane].addr = planes[plane].addr; 1254 pCtx->pInbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize; 1255 pCtx->pInbuf[nIndex].planes[plane].fd = planes[plane].fd; 1256 ALOGV("%s: registered buf %d (addr=%p alloc_sz=%ld fd=%d)\n", __func__, nIndex, 1257 planes[plane].addr, planes[plane].allocSize, planes[plane].fd); 1258 } 1259 pCtx->pInbuf[nIndex].bRegistered = VIDEO_TRUE; 1260 break; 1261 } 1262 } 1263 1264 if (nIndex == pCtx->nInbufs) { 1265 ALOGE("%s: can not find non-registered input buffer", __func__); 1266 ret = VIDEO_ERROR_NOBUFFERS; 1267 } 1268 1269 EXIT: 1270 return ret; 1271 } 1272 1273 static ExynosVideoErrorType MFC_Decoder_Register_Outbuf( 1274 void *pHandle, 1275 ExynosVideoPlane *planes, 1276 int nPlanes) 1277 { 1278 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1279 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1280 int nIndex, plane; 1281 1282 if ((pCtx == NULL) || (planes == NULL) || (nPlanes != VIDEO_DECODER_OUTBUF_PLANES)) { 1283 ALOGE("%s: params must be supplied", __func__); 1284 ret = VIDEO_ERROR_BADPARAM; 1285 goto EXIT; 1286 } 1287 1288 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) { 1289 if (pCtx->pOutbuf[nIndex].bRegistered == VIDEO_FALSE) { 1290 for (plane = 0; plane < nPlanes; plane++) { 1291 pCtx->pOutbuf[nIndex].planes[plane].addr = planes[plane].addr; 1292 pCtx->pOutbuf[nIndex].planes[plane].allocSize = planes[plane].allocSize; 1293 pCtx->pOutbuf[nIndex].planes[plane].fd = planes[plane].fd; 1294 } 1295 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_TRUE; 1296 ALOGV("%s: registered buf %d 0:(addr=%p alloc_sz=%d fd=%d) 1:(addr=%p alloc_sz=%d fd=%d)\n", 1297 __func__, nIndex, planes[0].addr, planes[0].allocSize, planes[0].fd, 1298 planes[1].addr, planes[1].allocSize, planes[1].fd); 1299 break; 1300 } 1301 } 1302 1303 if (nIndex == pCtx->nOutbufs) { 1304 ALOGE("%s: can not find non-registered output buffer", __func__); 1305 ret = VIDEO_ERROR_NOBUFFERS; 1306 } 1307 1308 EXIT: 1309 return ret; 1310 } 1311 1312 static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Inbuf(void *pHandle) 1313 { 1314 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1315 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1316 int nIndex; 1317 1318 if (pCtx == NULL) { 1319 ALOGE("%s: Video context info must be supplied", __func__); 1320 ret = VIDEO_ERROR_BADPARAM; 1321 goto EXIT; 1322 } 1323 1324 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) { 1325 pCtx->pInbuf[nIndex].planes[0].addr = NULL; 1326 pCtx->pInbuf[nIndex].bRegistered = VIDEO_FALSE; 1327 } 1328 1329 EXIT: 1330 return ret; 1331 } 1332 1333 static ExynosVideoErrorType MFC_Decoder_Clear_RegisteredBuffer_Outbuf(void *pHandle) 1334 { 1335 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1336 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1337 int nIndex; 1338 1339 if (pCtx == NULL) { 1340 ALOGE("%s: Video context info must be supplied", __func__); 1341 ret = VIDEO_ERROR_BADPARAM; 1342 goto EXIT; 1343 } 1344 1345 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) { 1346 pCtx->pOutbuf[nIndex].planes[0].addr = NULL; 1347 pCtx->pOutbuf[nIndex].bRegistered = VIDEO_FALSE; 1348 } 1349 1350 EXIT: 1351 return ret; 1352 } 1353 1354 /* 1355 * [Decoder Buffer OPS] Find (Input) 1356 */ 1357 static int MFC_Decoder_Find_Inbuf( 1358 void *pHandle, 1359 unsigned char *pBuffer) 1360 { 1361 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1362 int nIndex = -1; 1363 1364 if (pCtx == NULL) { 1365 ALOGE("%s: Video context info must be supplied", __func__); 1366 goto EXIT; 1367 } 1368 1369 for (nIndex = 0; nIndex < pCtx->nInbufs; nIndex++) { 1370 if (pCtx->pInbuf[nIndex].bQueued == VIDEO_FALSE) { 1371 if ((pBuffer == NULL) || 1372 (pCtx->pInbuf[nIndex].planes[0].addr == pBuffer)) 1373 break; 1374 } 1375 } 1376 1377 if (nIndex == pCtx->nInbufs) 1378 nIndex = -1; 1379 1380 EXIT: 1381 return nIndex; 1382 } 1383 1384 /* 1385 * [Decoder Buffer OPS] Find (Outnput) 1386 */ 1387 static int MFC_Decoder_Find_Outbuf( 1388 void *pHandle, 1389 unsigned char *pBuffer) 1390 { 1391 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1392 int nIndex = -1; 1393 1394 if (pCtx == NULL) { 1395 ALOGE("%s: Video context info must be supplied", __func__); 1396 goto EXIT; 1397 } 1398 1399 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) { 1400 if (pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) { 1401 if ((pBuffer == NULL) || 1402 (pCtx->pOutbuf[nIndex].planes[0].addr == pBuffer)) 1403 break; 1404 } 1405 } 1406 1407 if (nIndex == pCtx->nOutbufs) 1408 nIndex = -1; 1409 1410 EXIT: 1411 return nIndex; 1412 } 1413 1414 /* 1415 * [Decoder Buffer OPS] Enqueue (Input) 1416 */ 1417 static ExynosVideoErrorType MFC_Decoder_Enqueue_Inbuf( 1418 void *pHandle, 1419 unsigned char *pBuffer[], 1420 unsigned int dataSize[], 1421 int nPlanes, 1422 void *pPrivate) 1423 { 1424 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1425 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1426 pthread_mutex_t *pMutex = NULL; 1427 1428 struct v4l2_plane planes[VIDEO_DECODER_INBUF_PLANES]; 1429 struct v4l2_buffer buf; 1430 int index, i; 1431 1432 if (pCtx == NULL) { 1433 ALOGE("%s: Video context info must be supplied", __func__); 1434 ret = VIDEO_ERROR_BADPARAM; 1435 goto EXIT; 1436 } 1437 1438 if (VIDEO_DECODER_INBUF_PLANES < nPlanes) { 1439 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__, 1440 VIDEO_DECODER_INBUF_PLANES, nPlanes); 1441 ret = VIDEO_ERROR_BADPARAM; 1442 goto EXIT; 1443 } 1444 1445 memset(&buf, 0, sizeof(buf)); 1446 1447 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1448 buf.m.planes = planes; 1449 buf.length = VIDEO_DECODER_INBUF_PLANES; 1450 1451 pMutex = (pthread_mutex_t*)pCtx->pInMutex; 1452 pthread_mutex_lock(pMutex); 1453 index = MFC_Decoder_Find_Inbuf(pCtx, pBuffer[0]); 1454 if (index == -1) { 1455 pthread_mutex_unlock(pMutex); 1456 ALOGE("%s: Failed to get index", __func__); 1457 ret = VIDEO_ERROR_NOBUFFERS; 1458 goto EXIT; 1459 } 1460 1461 buf.index = index; 1462 pCtx->pInbuf[buf.index].bQueued = VIDEO_TRUE; 1463 1464 if (pCtx->bShareInbuf == VIDEO_TRUE) { 1465 buf.memory = pCtx->nMemoryType; 1466 for (i = 0; i < nPlanes; i++) { 1467 /* V4L2_MEMORY_USERPTR */ 1468 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i]; 1469 /* V4L2_MEMORY_DMABUF */ 1470 buf.m.planes[i].m.fd = pCtx->pInbuf[index].planes[i].fd; 1471 buf.m.planes[i].length = pCtx->pInbuf[index].planes[i].allocSize; 1472 buf.m.planes[i].bytesused = dataSize[i]; 1473 ALOGV("%s: shared inbuf(%d) plane(%d) addr=%p fd=%d len=%d used=%d\n", __func__, 1474 index, i, 1475 buf.m.planes[i].m.userptr, 1476 buf.m.planes[i].m.fd, 1477 buf.m.planes[i].length, 1478 buf.m.planes[i].bytesused); 1479 } 1480 } else { 1481 buf.memory = V4L2_MEMORY_MMAP; 1482 for (i = 0; i < nPlanes; i++) 1483 buf.m.planes[i].bytesused = dataSize[i]; 1484 } 1485 1486 if ((((OMX_BUFFERHEADERTYPE *)pPrivate)->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { 1487 buf.flags |= V4L2_BUF_FLAG_LAST_FRAME; 1488 ALOGV("%s: OMX_BUFFERFLAG_EOS => LAST_FRAME: 0x%x", __func__, 1489 !!(buf.flags & V4L2_BUF_FLAG_LAST_FRAME)); 1490 } 1491 1492 pCtx->pInbuf[buf.index].pPrivate = pPrivate; 1493 1494 pthread_mutex_unlock(pMutex); 1495 1496 if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) { 1497 ALOGE("%s: Failed to enqueue input buffer", __func__); 1498 pthread_mutex_lock(pMutex); 1499 pCtx->pInbuf[buf.index].pPrivate = NULL; 1500 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; 1501 pthread_mutex_unlock(pMutex); 1502 ret = VIDEO_ERROR_APIFAIL; 1503 goto EXIT; 1504 } 1505 1506 EXIT: 1507 return ret; 1508 } 1509 1510 /* 1511 * [Decoder Buffer OPS] Enqueue (Output) 1512 */ 1513 static ExynosVideoErrorType MFC_Decoder_Enqueue_Outbuf( 1514 void *pHandle, 1515 unsigned char *pBuffer[], 1516 unsigned int dataSize[], 1517 int nPlanes, 1518 void *pPrivate) 1519 { 1520 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1521 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1522 pthread_mutex_t *pMutex = NULL; 1523 1524 struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES]; 1525 struct v4l2_buffer buf; 1526 int i, index; 1527 1528 if (pCtx == NULL) { 1529 ALOGE("%s: Video context info must be supplied", __func__); 1530 ret = VIDEO_ERROR_BADPARAM; 1531 goto EXIT; 1532 } 1533 1534 if (VIDEO_DECODER_OUTBUF_PLANES < nPlanes) { 1535 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__, 1536 VIDEO_DECODER_OUTBUF_PLANES, nPlanes); 1537 ret = VIDEO_ERROR_BADPARAM; 1538 goto EXIT; 1539 } 1540 1541 memset(&buf, 0, sizeof(buf)); 1542 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1543 buf.m.planes = planes; 1544 buf.length = VIDEO_DECODER_OUTBUF_PLANES; 1545 1546 pMutex = (pthread_mutex_t*)pCtx->pOutMutex; 1547 pthread_mutex_lock(pMutex); 1548 index = MFC_Decoder_Find_Outbuf(pCtx, pBuffer[0]); 1549 if (index == -1) { 1550 pthread_mutex_unlock(pMutex); 1551 ALOGE("%s: Failed to get index", __func__); 1552 ret = VIDEO_ERROR_NOBUFFERS; 1553 goto EXIT; 1554 } 1555 buf.index = index; 1556 pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE; 1557 1558 if (pCtx->bShareOutbuf == VIDEO_TRUE) { 1559 buf.memory = pCtx->nMemoryType; 1560 for (i = 0; i < nPlanes; i++) { 1561 /* V4L2_MEMORY_USERPTR */ 1562 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i]; 1563 /* V4L2_MEMORY_DMABUF */ 1564 buf.m.planes[i].m.fd = pCtx->pOutbuf[index].planes[i].fd; 1565 buf.m.planes[i].length = pCtx->pOutbuf[index].planes[i].allocSize; 1566 buf.m.planes[i].bytesused = dataSize[i]; 1567 ALOGV("%s: shared outbuf(%d) plane=%d addr=%p fd=%d len=%d used=%d\n", __func__, 1568 index, i, 1569 buf.m.planes[i].m.userptr, 1570 buf.m.planes[i].m.fd, 1571 buf.m.planes[i].length, 1572 buf.m.planes[i].bytesused); 1573 } 1574 } else { 1575 ALOGV("%s: non-shared outbuf(%d)\n", __func__, index); 1576 buf.memory = V4L2_MEMORY_MMAP; 1577 } 1578 1579 pCtx->pOutbuf[buf.index].pPrivate = pPrivate; 1580 1581 pthread_mutex_unlock(pMutex); 1582 1583 if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) { 1584 ALOGE("%s: Failed to enqueue output buffer", __func__); 1585 pthread_mutex_lock(pMutex); 1586 pCtx->pOutbuf[buf.index].pPrivate = NULL; 1587 pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE; 1588 pthread_mutex_unlock(pMutex); 1589 ret = VIDEO_ERROR_APIFAIL; 1590 goto EXIT; 1591 } 1592 1593 EXIT: 1594 return ret; 1595 } 1596 1597 /* 1598 * [Decoder Buffer OPS] Dequeue (Input) 1599 */ 1600 static ExynosVideoBuffer *MFC_Decoder_Dequeue_Inbuf(void *pHandle) 1601 { 1602 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1603 ExynosVideoBuffer *pInbuf = NULL; 1604 pthread_mutex_t *pMutex = NULL; 1605 1606 struct v4l2_buffer buf; 1607 1608 if (pCtx == NULL) { 1609 ALOGE("%s: Video context info must be supplied", __func__); 1610 goto EXIT; 1611 } 1612 1613 if (pCtx->bStreamonInbuf == VIDEO_FALSE) { 1614 pInbuf = NULL; 1615 goto EXIT; 1616 } 1617 1618 memset(&buf, 0, sizeof(buf)); 1619 1620 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1621 1622 if (pCtx->bShareInbuf == VIDEO_TRUE) 1623 buf.memory = pCtx->nMemoryType; 1624 else 1625 buf.memory = V4L2_MEMORY_MMAP; 1626 1627 if (exynos_v4l2_dqbuf(pCtx->hDec, &buf) != 0) { 1628 pInbuf = NULL; 1629 goto EXIT; 1630 } 1631 1632 pMutex = (pthread_mutex_t*)pCtx->pInMutex; 1633 pthread_mutex_lock(pMutex); 1634 1635 pInbuf = &pCtx->pInbuf[buf.index]; 1636 pCtx->pInbuf[buf.index].bQueued = VIDEO_FALSE; 1637 1638 if (pCtx->bStreamonInbuf == VIDEO_FALSE) 1639 pInbuf = NULL; 1640 1641 pthread_mutex_unlock(pMutex); 1642 1643 EXIT: 1644 return pInbuf; 1645 } 1646 1647 /* 1648 * [Decoder Buffer OPS] Dequeue (Output) 1649 */ 1650 static ExynosVideoBuffer *MFC_Decoder_Dequeue_Outbuf(void *pHandle) 1651 { 1652 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1653 ExynosVideoBuffer *pOutbuf = NULL; 1654 pthread_mutex_t *pMutex = NULL; 1655 1656 struct v4l2_buffer buf; 1657 int value, state; 1658 1659 if (pCtx == NULL) { 1660 ALOGE("%s: Video context info must be supplied", __func__); 1661 goto EXIT; 1662 } 1663 1664 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) { 1665 pOutbuf = NULL; 1666 goto EXIT; 1667 } 1668 1669 memset(&buf, 0, sizeof(buf)); 1670 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1671 1672 if (pCtx->bShareOutbuf == VIDEO_TRUE) 1673 buf.memory = pCtx->nMemoryType; 1674 else 1675 buf.memory = V4L2_MEMORY_MMAP; 1676 1677 /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */ 1678 if (exynos_v4l2_dqbuf(pCtx->hDec, &buf) != 0) { 1679 pOutbuf = NULL; 1680 goto EXIT; 1681 } 1682 1683 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) { 1684 pOutbuf = NULL; 1685 goto EXIT; 1686 } 1687 1688 pMutex = (pthread_mutex_t*)pCtx->pOutMutex; 1689 pthread_mutex_lock(pMutex); 1690 1691 pOutbuf = &pCtx->pOutbuf[buf.index]; 1692 1693 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS, &value); 1694 1695 switch (value) { 1696 case 0: 1697 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_ONLY; 1698 break; 1699 case 1: 1700 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_DECODING; 1701 break; 1702 case 2: 1703 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY; 1704 break; 1705 case 3: 1706 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE, &state); 1707 if (state == 1) /* Resolution is changed */ 1708 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL; 1709 else /* Decoding is finished */ 1710 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_FINISHED; 1711 break; 1712 default: 1713 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; 1714 break; 1715 } 1716 1717 switch (buf.flags & (0x7 << 3)) { 1718 case V4L2_BUF_FLAG_KEYFRAME: 1719 pOutbuf->frameType = VIDEO_FRAME_I; 1720 break; 1721 case V4L2_BUF_FLAG_PFRAME: 1722 pOutbuf->frameType = VIDEO_FRAME_P; 1723 break; 1724 case V4L2_BUF_FLAG_BFRAME: 1725 pOutbuf->frameType = VIDEO_FRAME_B; 1726 break; 1727 default: 1728 pOutbuf->frameType = VIDEO_FRAME_OTHERS; 1729 break; 1730 }; 1731 1732 pOutbuf->bQueued = VIDEO_FALSE; 1733 1734 pthread_mutex_unlock(pMutex); 1735 1736 EXIT: 1737 return pOutbuf; 1738 } 1739 1740 static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Inbuf(void *pHandle) 1741 { 1742 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1743 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1744 int i; 1745 1746 if (pCtx == NULL) { 1747 ALOGE("%s: Video context info must be supplied", __func__); 1748 ret = VIDEO_ERROR_BADPARAM; 1749 goto EXIT; 1750 } 1751 1752 for (i = 0; i < pCtx->nInbufs; i++) { 1753 pCtx->pInbuf[i].bQueued = VIDEO_FALSE; 1754 } 1755 1756 EXIT: 1757 return ret; 1758 } 1759 1760 static ExynosVideoErrorType MFC_Decoder_Clear_Queued_Outbuf(void *pHandle) 1761 { 1762 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1763 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1764 int i; 1765 1766 if (pCtx == NULL) { 1767 ALOGE("%s: Video context info must be supplied", __func__); 1768 ret = VIDEO_ERROR_BADPARAM; 1769 goto EXIT; 1770 } 1771 1772 for (i = 0; i < pCtx->nOutbufs; i++) { 1773 pCtx->pOutbuf[i].bQueued = VIDEO_FALSE; 1774 } 1775 1776 EXIT: 1777 return ret; 1778 } 1779 1780 /* 1781 * [Decoder Buffer OPS] Cleanup Buffer (Input) 1782 */ 1783 static ExynosVideoErrorType MFC_Decoder_Cleanup_Buffer_Inbuf(void *pHandle) 1784 { 1785 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1786 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1787 1788 struct v4l2_requestbuffers req; 1789 int nBufferCount = 0; 1790 1791 if (pCtx == NULL) { 1792 ALOGE("%s: Video context info must be supplied", __func__); 1793 ret = VIDEO_ERROR_BADPARAM; 1794 goto EXIT; 1795 } 1796 1797 nBufferCount = 0; /* for clean-up */ 1798 1799 memset(&req, 0, sizeof(req)); 1800 1801 req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1802 req.count = nBufferCount; 1803 1804 if (pCtx->bShareInbuf == VIDEO_TRUE) 1805 req.memory = pCtx->nMemoryType; 1806 else 1807 req.memory = V4L2_MEMORY_MMAP; 1808 1809 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) { 1810 ret = VIDEO_ERROR_APIFAIL; 1811 goto EXIT; 1812 } 1813 1814 pCtx->nInbufs = (int)req.count; 1815 1816 if (pCtx->pInbuf != NULL) { 1817 free(pCtx->pInbuf); 1818 pCtx->pInbuf = NULL; 1819 } 1820 1821 EXIT: 1822 return ret; 1823 } 1824 1825 /* 1826 * [Decoder Buffer OPS] Cleanup Buffer (Output) 1827 */ 1828 static ExynosVideoErrorType MFC_Decoder_Cleanup_Buffer_Outbuf(void *pHandle) 1829 { 1830 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1831 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1832 1833 struct v4l2_requestbuffers req; 1834 int nBufferCount = 0; 1835 1836 if (pCtx == NULL) { 1837 ALOGE("%s: Video context info must be supplied", __func__); 1838 ret = VIDEO_ERROR_BADPARAM; 1839 goto EXIT; 1840 } 1841 1842 nBufferCount = 0; /* for clean-up */ 1843 1844 memset(&req, 0, sizeof(req)); 1845 1846 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1847 req.count = nBufferCount; 1848 1849 if (pCtx->bShareOutbuf == VIDEO_TRUE) 1850 req.memory = pCtx->nMemoryType; 1851 else 1852 req.memory = V4L2_MEMORY_MMAP; 1853 1854 if (exynos_v4l2_reqbufs(pCtx->hDec, &req) != 0) { 1855 ret = VIDEO_ERROR_APIFAIL; 1856 goto EXIT; 1857 } 1858 1859 pCtx->nOutbufs = (int)req.count; 1860 1861 if (pCtx->pOutbuf != NULL) { 1862 free(pCtx->pOutbuf); 1863 pCtx->pOutbuf = NULL; 1864 } 1865 1866 EXIT: 1867 return ret; 1868 } 1869 1870 /* 1871 * [Decoder Buffer OPS] FindIndex (Output) 1872 */ 1873 static int MFC_Decoder_FindEmpty_Outbuf(void *pHandle) 1874 { 1875 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1876 int nIndex = -1; 1877 1878 if (pCtx == NULL) { 1879 ALOGE("%s: Video context info must be supplied", __func__); 1880 goto EXIT; 1881 } 1882 1883 for (nIndex = 0; nIndex < pCtx->nOutbufs; nIndex++) { 1884 if ((pCtx->pOutbuf[nIndex].bQueued == VIDEO_FALSE) && 1885 (pCtx->pOutbuf[nIndex].bSlotUsed == VIDEO_FALSE)) 1886 break; 1887 } 1888 1889 if (nIndex == pCtx->nOutbufs) 1890 nIndex = -1; 1891 1892 EXIT: 1893 return nIndex; 1894 } 1895 1896 /* 1897 * [Decoder Buffer OPS] BufferIndexFree (Output) 1898 */ 1899 void MFC_Decoder_BufferIndexFree_Outbuf(void *pHandle, PrivateDataShareBuffer *pPDSB, int index) 1900 { 1901 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1902 int i, j; 1903 1904 ALOGV("De-queue buf.index:%d", index); 1905 ALOGV("pOutbuf fd:%d", pCtx->pOutbuf[index].planes[0].fd); 1906 1907 if (pCtx->pOutbuf[index].nIndexUseCnt == 0) { 1908 pCtx->pOutbuf[index].bSlotUsed = VIDEO_FALSE; 1909 } 1910 1911 for (i = 0; pPDSB->dpbFD[i].fd > -1; i++) { 1912 ALOGV("pPDSB->dpbFD[%d].fd:%d", i, pPDSB->dpbFD[i].fd); 1913 for (j = 0; pCtx->nOutbufs > j; j++) 1914 if (pPDSB->dpbFD[i].fd == pCtx->pOutbuf[j].planes[0].fd) { 1915 if (pCtx->pOutbuf[j].bQueued == VIDEO_FALSE) { 1916 if (pCtx->pOutbuf[j].nIndexUseCnt > 0) 1917 pCtx->pOutbuf[j].nIndexUseCnt--; 1918 } else if(pCtx->pOutbuf[j].bQueued == VIDEO_TRUE) { 1919 if (pCtx->pOutbuf[j].nIndexUseCnt > 1) { 1920 /* The buffer being used as the reference buffer came again. */ 1921 pCtx->pOutbuf[j].nIndexUseCnt--; 1922 } else { 1923 /* Reference DPB buffer is internally reused. */ 1924 } 1925 } 1926 ALOGV("dec FD:%d, pCtx->pOutbuf[%d].nIndexUseCnt:%d", pPDSB->dpbFD[i].fd, j, pCtx->pOutbuf[j].nIndexUseCnt); 1927 if ((pCtx->pOutbuf[j].nIndexUseCnt == 0) && 1928 (pCtx->pOutbuf[j].bQueued == VIDEO_FALSE)) { 1929 pCtx->pOutbuf[j].bSlotUsed = VIDEO_FALSE; 1930 } 1931 } 1932 } 1933 memset((char *)pPDSB, -1, sizeof(PrivateDataShareBuffer)); 1934 1935 return; 1936 } 1937 1938 /* 1939 * [Decoder Buffer OPS] ExtensionEnqueue (Output) 1940 */ 1941 static ExynosVideoErrorType MFC_Decoder_ExtensionEnqueue_Outbuf( 1942 void *pHandle, 1943 unsigned char *pBuffer[], 1944 unsigned int *pFd[], 1945 unsigned int allocLen[], 1946 unsigned int dataSize[], 1947 int nPlanes, 1948 void *pPrivate) 1949 { 1950 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 1951 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 1952 pthread_mutex_t *pMutex = NULL; 1953 1954 struct v4l2_plane planes[VIDEO_DECODER_OUTBUF_PLANES]; 1955 struct v4l2_buffer buf; 1956 int state, index, i; 1957 1958 if (pCtx == NULL) { 1959 ALOGE("%s: Video context info must be supplied", __func__); 1960 ret = VIDEO_ERROR_BADPARAM; 1961 goto EXIT; 1962 } 1963 1964 if (VIDEO_DECODER_OUTBUF_PLANES < nPlanes) { 1965 ALOGE("%s: Number of max planes : %d, nPlanes : %d", __func__, 1966 VIDEO_DECODER_OUTBUF_PLANES, nPlanes); 1967 ret = VIDEO_ERROR_BADPARAM; 1968 goto EXIT; 1969 } 1970 1971 memset(&buf, 0, sizeof(buf)); 1972 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1973 buf.m.planes = planes; 1974 buf.length = VIDEO_DECODER_OUTBUF_PLANES; 1975 1976 pMutex = (pthread_mutex_t*)pCtx->pOutMutex; 1977 pthread_mutex_lock(pMutex); 1978 1979 index = MFC_Decoder_Find_Outbuf(pCtx, pBuffer[0]); 1980 if (index == -1) { 1981 ALOGV("%s: Failed to find index", __func__); 1982 index = MFC_Decoder_FindEmpty_Outbuf(pCtx); 1983 if (index == -1) { 1984 pthread_mutex_unlock(pMutex); 1985 ALOGE("%s: Failed to get index", __func__); 1986 ret = VIDEO_ERROR_NOBUFFERS; 1987 goto EXIT; 1988 } 1989 } 1990 1991 buf.index = index; 1992 ALOGV("En-queue index:%d pCtx->pOutbuf[buf.index].bQueued:%d, pFd[0]:%d", 1993 index, pCtx->pOutbuf[buf.index].bQueued, pFd[0]); 1994 pCtx->pOutbuf[buf.index].bQueued = VIDEO_TRUE; 1995 pCtx->pOutbuf[buf.index].bSlotUsed = VIDEO_TRUE; 1996 1997 buf.memory = pCtx->nMemoryType; 1998 for (i = 0; i < nPlanes; i++) { 1999 /* V4L2_MEMORY_USERPTR */ 2000 buf.m.planes[i].m.userptr = (unsigned long)pBuffer[i]; 2001 /* V4L2_MEMORY_DMABUF */ 2002 buf.m.planes[i].m.fd = pFd[i]; 2003 buf.m.planes[i].length = allocLen[i]; 2004 buf.m.planes[i].bytesused = dataSize[i]; 2005 2006 /* Temporary storage for Dequeue */ 2007 pCtx->pOutbuf[buf.index].planes[i].addr = (unsigned long)pBuffer[i]; 2008 pCtx->pOutbuf[buf.index].planes[i].fd = (unsigned int)pFd[i]; 2009 pCtx->pOutbuf[buf.index].planes[i].allocSize = allocLen[i]; 2010 2011 ALOGV("%s: shared outbuf(%d) plane=%d addr=0x%x fd=%d len=%d used=%d\n", 2012 __func__, index, i, 2013 (void*)buf.m.planes[i].m.userptr, buf.m.planes[i].m.fd, 2014 buf.m.planes[i].length, buf.m.planes[i].bytesused); 2015 } 2016 2017 pCtx->pOutbuf[buf.index].pPrivate = pPrivate; 2018 pCtx->pOutbuf[buf.index].nIndexUseCnt++; 2019 2020 pthread_mutex_unlock(pMutex); 2021 2022 if (exynos_v4l2_qbuf(pCtx->hDec, &buf) != 0) { 2023 pthread_mutex_lock(pMutex); 2024 pCtx->pOutbuf[buf.index].nIndexUseCnt--; 2025 pCtx->pOutbuf[buf.index].pPrivate = NULL; 2026 pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE; 2027 if (pCtx->pOutbuf[buf.index].nIndexUseCnt == 0) 2028 pCtx->pOutbuf[buf.index].bSlotUsed = VIDEO_FALSE; 2029 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE, &state); 2030 pthread_mutex_unlock(pMutex); 2031 2032 if (state == 1) { 2033 /* The case of Resolution is changed */ 2034 ret = VIDEO_ERROR_WRONGBUFFERSIZE; 2035 } else { 2036 ALOGE("%s: Failed to enqueue output buffer", __func__); 2037 ret = VIDEO_ERROR_APIFAIL; 2038 } 2039 goto EXIT; 2040 } 2041 2042 EXIT: 2043 return ret; 2044 } 2045 2046 /* 2047 * [Decoder Buffer OPS] ExtensionDequeue (Output) 2048 */ 2049 static ExynosVideoErrorType MFC_Decoder_ExtensionDequeue_Outbuf( 2050 void *pHandle, 2051 ExynosVideoBuffer *pVideoBuffer) 2052 { 2053 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 2054 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 2055 pthread_mutex_t *pMutex = NULL; 2056 ExynosVideoBuffer *pOutbuf = NULL; 2057 PrivateDataShareBuffer *pPDSB = NULL; 2058 struct v4l2_buffer buf; 2059 int value, state, i, j; 2060 2061 if (pCtx == NULL) { 2062 ALOGE("%s: Video context info must be supplied", __func__); 2063 ret = VIDEO_ERROR_BADPARAM; 2064 goto EXIT; 2065 } 2066 2067 if (pCtx->bStreamonOutbuf == VIDEO_FALSE) { 2068 pOutbuf = NULL; 2069 ret = VIDEO_ERROR_APIFAIL; 2070 goto EXIT; 2071 } 2072 2073 memset(&buf, 0, sizeof(buf)); 2074 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2075 2076 if (pCtx->bShareOutbuf == VIDEO_TRUE) 2077 buf.memory = pCtx->nMemoryType; 2078 else 2079 buf.memory = V4L2_MEMORY_MMAP; 2080 2081 /* HACK: pOutbuf return -1 means DECODING_ONLY for almost cases */ 2082 if (exynos_v4l2_dqbuf(pCtx->hDec, &buf) != 0) { 2083 pOutbuf = NULL; 2084 ret = VIDEO_ERROR_APIFAIL; 2085 goto EXIT; 2086 } 2087 2088 pMutex = (pthread_mutex_t*)pCtx->pOutMutex; 2089 pthread_mutex_lock(pMutex); 2090 2091 pOutbuf = &pCtx->pOutbuf[buf.index]; 2092 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS, &value); 2093 2094 switch (value) { 2095 case 0: 2096 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_ONLY; 2097 break; 2098 case 1: 2099 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_DECODING; 2100 break; 2101 case 2: 2102 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DISPLAY_ONLY; 2103 break; 2104 case 3: 2105 exynos_v4l2_g_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE, &state); 2106 if (state == 1) /* Resolution is changed */ 2107 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_CHANGE_RESOL; 2108 else /* Decoding is finished */ 2109 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_DECODING_FINISHED; 2110 break; 2111 default: 2112 pOutbuf->displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; 2113 break; 2114 } 2115 2116 switch (buf.flags & (0x7 << 3)) { 2117 case V4L2_BUF_FLAG_KEYFRAME: 2118 pOutbuf->frameType = VIDEO_FRAME_I; 2119 break; 2120 case V4L2_BUF_FLAG_PFRAME: 2121 pOutbuf->frameType = VIDEO_FRAME_P; 2122 break; 2123 case V4L2_BUF_FLAG_BFRAME: 2124 pOutbuf->frameType = VIDEO_FRAME_B; 2125 break; 2126 default: 2127 pOutbuf->frameType = VIDEO_FRAME_OTHERS; 2128 break; 2129 }; 2130 2131 pPDSB = ((PrivateDataShareBuffer *)pCtx->nPrivateDataShareAddress) + buf.index; 2132 if (pCtx->pOutbuf[buf.index].bQueued == VIDEO_TRUE) { 2133 memcpy(pVideoBuffer, pOutbuf, sizeof(ExynosVideoBuffer)); 2134 memcpy((char *)(&(pVideoBuffer->PDSB)), (char *)pPDSB, sizeof(PrivateDataShareBuffer)); 2135 } else { 2136 ret = VIDEO_ERROR_NOBUFFERS; 2137 ALOGV("%s :: %d", __FUNCTION__, __LINE__); 2138 } 2139 2140 pCtx->pOutbuf[buf.index].bQueued = VIDEO_FALSE; 2141 MFC_Decoder_BufferIndexFree_Outbuf(pHandle, pPDSB, buf.index); 2142 2143 pthread_mutex_unlock(pMutex); 2144 2145 EXIT: 2146 return ret; 2147 } 2148 2149 /* 2150 * [Decoder Buffer OPS] Enable Dynamic DPB 2151 */ 2152 static ExynosVideoErrorType MFC_Decoder_Enable_DynamicDPB(void *pHandle) 2153 { 2154 ExynosVideoDecContext *pCtx = (ExynosVideoDecContext *)pHandle; 2155 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 2156 2157 if (pCtx == NULL) { 2158 ALOGE("%s: Video context info must be supplied", __func__); 2159 ret = VIDEO_ERROR_BADPARAM; 2160 goto EXIT; 2161 } 2162 2163 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC_SET_DYNAMIC_DPB_MODE, 1) != 0) { 2164 ret = VIDEO_ERROR_APIFAIL; 2165 goto EXIT; 2166 } 2167 2168 if (exynos_v4l2_s_ctrl(pCtx->hDec, V4L2_CID_MPEG_MFC_SET_USER_SHARED_HANDLE, pCtx->nPrivateDataShareFD) != 0) { 2169 ret = VIDEO_ERROR_APIFAIL; 2170 goto EXIT; 2171 } 2172 2173 EXIT: 2174 return ret; 2175 } 2176 2177 /* 2178 * [Decoder OPS] Common 2179 */ 2180 static ExynosVideoDecOps defDecOps = { 2181 .nSize = 0, 2182 .Init = MFC_Decoder_Init, 2183 .Finalize = MFC_Decoder_Finalize, 2184 .Set_DisplayDelay = MFC_Decoder_Set_DisplayDelay, 2185 .Set_IFrameDecoding = MFC_Decoder_Set_IFrameDecoding, 2186 .Enable_PackedPB = MFC_Decoder_Enable_PackedPB, 2187 .Enable_LoopFilter = MFC_Decoder_Enable_LoopFilter, 2188 .Enable_SliceMode = MFC_Decoder_Enable_SliceMode, 2189 .Get_ActualBufferCount = MFC_Decoder_Get_ActualBufferCount, 2190 .Set_FrameTag = MFC_Decoder_Set_FrameTag, 2191 .Get_FrameTag = MFC_Decoder_Get_FrameTag, 2192 .Enable_SEIParsing = MFC_Decoder_Enable_SEIParsing, 2193 .Get_FramePackingInfo = MFC_Decoder_Get_FramePackingInfo, 2194 }; 2195 2196 /* 2197 * [Decoder Buffer OPS] Input 2198 */ 2199 static ExynosVideoDecBufferOps defInbufOps = { 2200 .nSize = 0, 2201 .Enable_Cacheable = MFC_Decoder_Enable_Cacheable_Inbuf, 2202 .Set_Shareable = MFC_Decoder_Set_Shareable_Inbuf, 2203 .Get_Buffer = NULL, 2204 .Set_Geometry = MFC_Decoder_Set_Geometry_Inbuf, 2205 .Get_Geometry = NULL, 2206 .Setup = MFC_Decoder_Setup_Inbuf, 2207 .Run = MFC_Decoder_Run_Inbuf, 2208 .Stop = MFC_Decoder_Stop_Inbuf, 2209 .Enqueue = MFC_Decoder_Enqueue_Inbuf, 2210 .Enqueue_All = NULL, 2211 .Dequeue = MFC_Decoder_Dequeue_Inbuf, 2212 .Register = MFC_Decoder_Register_Inbuf, 2213 .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Inbuf, 2214 .Clear_Queue = MFC_Decoder_Clear_Queued_Inbuf, 2215 .Cleanup_Buffer = MFC_Decoder_Cleanup_Buffer_Inbuf, 2216 }; 2217 2218 /* 2219 * [Decoder Buffer OPS] Output 2220 */ 2221 static ExynosVideoDecBufferOps defOutbufOps = { 2222 .nSize = 0, 2223 .Enable_Cacheable = MFC_Decoder_Enable_Cacheable_Outbuf, 2224 .Set_Shareable = MFC_Decoder_Set_Shareable_Outbuf, 2225 .Get_Buffer = MFC_Decoder_Get_Buffer_Outbuf, 2226 .Set_Geometry = MFC_Decoder_Set_Geometry_Outbuf, 2227 .Get_Geometry = MFC_Decoder_Get_Geometry_Outbuf, 2228 .Setup = MFC_Decoder_Setup_Outbuf, 2229 .Run = MFC_Decoder_Run_Outbuf, 2230 .Stop = MFC_Decoder_Stop_Outbuf, 2231 .Enqueue = MFC_Decoder_Enqueue_Outbuf, 2232 .Enqueue_All = NULL, 2233 .Dequeue = MFC_Decoder_Dequeue_Outbuf, 2234 .Register = MFC_Decoder_Register_Outbuf, 2235 .Clear_RegisteredBuffer = MFC_Decoder_Clear_RegisteredBuffer_Outbuf, 2236 .Clear_Queue = MFC_Decoder_Clear_Queued_Outbuf, 2237 .Cleanup_Buffer = MFC_Decoder_Cleanup_Buffer_Outbuf, 2238 .ExtensionEnqueue = MFC_Decoder_ExtensionEnqueue_Outbuf, 2239 .ExtensionDequeue = MFC_Decoder_ExtensionDequeue_Outbuf, 2240 .Enable_DynamicDPB = MFC_Decoder_Enable_DynamicDPB, 2241 }; 2242 2243 int Exynos_Video_Register_Decoder( 2244 ExynosVideoDecOps *pDecOps, 2245 ExynosVideoDecBufferOps *pInbufOps, 2246 ExynosVideoDecBufferOps *pOutbufOps) 2247 { 2248 ExynosVideoErrorType ret = VIDEO_ERROR_NONE; 2249 2250 if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) { 2251 ret = VIDEO_ERROR_BADPARAM; 2252 goto EXIT; 2253 } 2254 2255 defDecOps.nSize = sizeof(defDecOps); 2256 defInbufOps.nSize = sizeof(defInbufOps); 2257 defOutbufOps.nSize = sizeof(defOutbufOps); 2258 2259 memcpy((char *)pDecOps + sizeof(pDecOps->nSize), (char *)&defDecOps + sizeof(defDecOps.nSize), 2260 pDecOps->nSize - sizeof(pDecOps->nSize)); 2261 2262 memcpy((char *)pInbufOps + sizeof(pInbufOps->nSize), (char *)&defInbufOps + sizeof(defInbufOps.nSize), 2263 pInbufOps->nSize - sizeof(pInbufOps->nSize)); 2264 2265 memcpy((char *)pOutbufOps + sizeof(pOutbufOps->nSize), (char *)&defOutbufOps + sizeof(defOutbufOps.nSize), 2266 pOutbufOps->nSize - sizeof(pOutbufOps->nSize)); 2267 2268 EXIT: 2269 return ret; 2270 } 2271