1 /* 2 * Copyright (c) 2009-2011 Intel Corporation. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "VideoDecoderBase.h" 18 #include "VideoDecoderTrace.h" 19 #include <string.h> 20 #include <va/va_android.h> 21 #include <va/va_tpi.h> 22 #ifdef __SSE4_1__ 23 #include "use_util_sse4.h" 24 #endif 25 26 #define INVALID_PTS ((uint64_t)-1) 27 #define MAXIMUM_POC 0x7FFFFFFF 28 #define MINIMUM_POC 0x80000000 29 #define ANDROID_DISPLAY_HANDLE 0x18C34078 30 VideoDecoderBase(const char * mimeType,_vbp_parser_type type)31 VideoDecoderBase::VideoDecoderBase(const char *mimeType, _vbp_parser_type type) 32 : mInitialized(false), 33 mLowDelay(false), 34 mStoreMetaData(false), 35 mDisplay(NULL), 36 mVADisplay(NULL), 37 mVAContext(VA_INVALID_ID), 38 mVAConfig(VA_INVALID_ID), 39 mVAStarted(false), 40 mCurrentPTS(INVALID_PTS), 41 mAcquiredBuffer(NULL), 42 mLastReference(NULL), 43 mForwardReference(NULL), 44 mDecodingFrame(false), 45 mSizeChanged(false), 46 mShowFrame(true), 47 mOutputWindowSize(OUTPUT_WINDOW_SIZE), 48 mRotationDegrees(0), 49 mErrReportEnabled(false), 50 mWiDiOn(false), 51 mRawOutput(false), 52 mManageReference(true), 53 mOutputMethod(OUTPUT_BY_PCT), 54 mNumSurfaces(0), 55 mSurfaceBuffers(NULL), 56 mOutputHead(NULL), 57 mOutputTail(NULL), 58 mSurfaces(NULL), 59 mVASurfaceAttrib(NULL), 60 mSurfaceUserPtr(NULL), 61 mSurfaceAcquirePos(0), 62 mNextOutputPOC(MINIMUM_POC), 63 mParserType(type), 64 mParserHandle(NULL), 65 mSignalBufferSize(0) { 66 67 memset(&mVideoFormatInfo, 0, sizeof(VideoFormatInfo)); 68 memset(&mConfigBuffer, 0, sizeof(mConfigBuffer)); 69 for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) { 70 mSignalBufferPre[i] = NULL; 71 } 72 pthread_mutex_init(&mLock, NULL); 73 pthread_mutex_init(&mFormatLock, NULL); 74 mVideoFormatInfo.mimeType = strdup(mimeType); 75 mUseGEN = false; 76 mMetaDataBuffersNum = 0; 77 mLibHandle = NULL; 78 mParserOpen = NULL; 79 mParserClose = NULL; 80 mParserParse = NULL; 81 mParserQuery = NULL; 82 mParserFlush = NULL; 83 mParserUpdate = NULL; 84 } 85 ~VideoDecoderBase()86 VideoDecoderBase::~VideoDecoderBase() { 87 pthread_mutex_destroy(&mLock); 88 pthread_mutex_destroy(&mFormatLock); 89 stop(); 90 free(mVideoFormatInfo.mimeType); 91 } 92 start(VideoConfigBuffer * buffer)93 Decode_Status VideoDecoderBase::start(VideoConfigBuffer *buffer) { 94 if (buffer == NULL) { 95 return DECODE_INVALID_DATA; 96 } 97 98 if (mParserHandle != NULL) { 99 WTRACE("Decoder has already started."); 100 return DECODE_SUCCESS; 101 } 102 mLibHandle = dlopen("libmixvbp.so", RTLD_NOW); 103 if (mLibHandle == NULL) { 104 return DECODE_NO_PARSER; 105 } 106 mParserOpen = (OpenFunc)dlsym(mLibHandle, "vbp_open"); 107 mParserClose = (CloseFunc)dlsym(mLibHandle, "vbp_close"); 108 mParserParse = (ParseFunc)dlsym(mLibHandle, "vbp_parse"); 109 mParserQuery = (QueryFunc)dlsym(mLibHandle, "vbp_query"); 110 mParserFlush = (FlushFunc)dlsym(mLibHandle, "vbp_flush"); 111 if (mParserOpen == NULL || mParserClose == NULL || mParserParse == NULL 112 || mParserQuery == NULL || mParserFlush == NULL) { 113 return DECODE_NO_PARSER; 114 } 115 #if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING) 116 mParserUpdate = (UpdateFunc)dlsym(mLibHandle, "vbp_update"); 117 if (mParserUpdate == NULL) { 118 return DECODE_NO_PARSER; 119 } 120 #endif 121 if ((int32_t)mParserType != VBP_INVALID) { 122 ITRACE("mParserType = %d", mParserType); 123 if (mParserOpen(mParserType, &mParserHandle) != VBP_OK) { 124 ETRACE("Failed to open VBP parser."); 125 return DECODE_NO_PARSER; 126 } 127 } 128 // keep a copy of configure buffer, meta data only. It can be used to override VA setup parameter. 129 mConfigBuffer = *buffer; 130 mConfigBuffer.data = NULL; 131 mConfigBuffer.size = 0; 132 133 mVideoFormatInfo.width = buffer->width; 134 mVideoFormatInfo.height = buffer->height; 135 if (buffer->flag & USE_NATIVE_GRAPHIC_BUFFER) { 136 mVideoFormatInfo.surfaceWidth = buffer->graphicBufferWidth; 137 mVideoFormatInfo.surfaceHeight = buffer->graphicBufferHeight; 138 } 139 mLowDelay = buffer->flag & WANT_LOW_DELAY; 140 mStoreMetaData = buffer->flag & WANT_STORE_META_DATA; 141 mRawOutput = buffer->flag & WANT_RAW_OUTPUT; 142 if (mRawOutput) { 143 WTRACE("Output is raw data."); 144 } 145 146 return DECODE_SUCCESS; 147 } 148 149 reset(VideoConfigBuffer * buffer)150 Decode_Status VideoDecoderBase::reset(VideoConfigBuffer *buffer) { 151 if (buffer == NULL) { 152 return DECODE_INVALID_DATA; 153 } 154 155 // if VA is already started, terminate VA as graphic buffers are reallocated by omxcodec 156 terminateVA(); 157 158 // reset the mconfigBuffer to pass it for startVA. 159 mConfigBuffer = *buffer; 160 mConfigBuffer.data = NULL; 161 mConfigBuffer.size = 0; 162 163 mVideoFormatInfo.width = buffer->width; 164 mVideoFormatInfo.height = buffer->height; 165 if (buffer->flag & USE_NATIVE_GRAPHIC_BUFFER) { 166 mVideoFormatInfo.surfaceWidth = buffer->graphicBufferWidth; 167 mVideoFormatInfo.surfaceHeight = buffer->graphicBufferHeight; 168 } 169 mVideoFormatInfo.actualBufferNeeded = mConfigBuffer.surfaceNumber; 170 mLowDelay = buffer->flag & WANT_LOW_DELAY; 171 mStoreMetaData = buffer->flag & WANT_STORE_META_DATA; 172 mMetaDataBuffersNum = 0; 173 mRawOutput = buffer->flag & WANT_RAW_OUTPUT; 174 if (mRawOutput) { 175 WTRACE("Output is raw data."); 176 } 177 return DECODE_SUCCESS; 178 } 179 180 181 stop(void)182 void VideoDecoderBase::stop(void) { 183 terminateVA(); 184 185 mCurrentPTS = INVALID_PTS; 186 mAcquiredBuffer = NULL; 187 mLastReference = NULL; 188 mForwardReference = NULL; 189 mDecodingFrame = false; 190 mSizeChanged = false; 191 192 // private variables 193 mLowDelay = false; 194 mStoreMetaData = false; 195 mRawOutput = false; 196 mNumSurfaces = 0; 197 mSurfaceAcquirePos = 0; 198 mNextOutputPOC = MINIMUM_POC; 199 mVideoFormatInfo.valid = false; 200 if (mParserHandle){ 201 mParserClose(mParserHandle); 202 mParserHandle = NULL; 203 } 204 if (mLibHandle) { 205 dlclose(mLibHandle); 206 mLibHandle = NULL; 207 } 208 } 209 flush(void)210 void VideoDecoderBase::flush(void) { 211 if (mVAStarted == false) { 212 // nothing to flush at this stage 213 return; 214 } 215 216 endDecodingFrame(true); 217 218 VideoSurfaceBuffer *p = mOutputHead; 219 // check if there's buffer with DRC flag in the output queue 220 while (p) { 221 if (p->renderBuffer.flag & IS_RESOLUTION_CHANGE) { 222 mSizeChanged = true; 223 break; 224 } 225 p = p->next; 226 } 227 // avoid setting mSurfaceAcquirePos to 0 as it may cause tearing 228 // (surface is still being rendered) 229 mSurfaceAcquirePos = (mSurfaceAcquirePos + 1) % mNumSurfaces; 230 mNextOutputPOC = MINIMUM_POC; 231 mCurrentPTS = INVALID_PTS; 232 mAcquiredBuffer = NULL; 233 mLastReference = NULL; 234 mForwardReference = NULL; 235 mOutputHead = NULL; 236 mOutputTail = NULL; 237 mDecodingFrame = false; 238 239 // flush vbp parser 240 if (mParserHandle && (mParserFlush(mParserHandle) != VBP_OK)) { 241 WTRACE("Failed to flush parser. Continue"); 242 } 243 244 // initialize surface buffer without resetting mapped/raw data 245 initSurfaceBuffer(false); 246 247 } 248 freeSurfaceBuffers(void)249 void VideoDecoderBase::freeSurfaceBuffers(void) { 250 if (mVAStarted == false) { 251 // nothing to free surface buffers at this stage 252 return; 253 } 254 255 pthread_mutex_lock(&mLock); 256 257 endDecodingFrame(true); 258 259 // if VA is already started, terminate VA as graphic buffers are reallocated by omxcodec 260 terminateVA(); 261 262 pthread_mutex_unlock(&mLock); 263 } 264 getFormatInfo(void)265 const VideoFormatInfo* VideoDecoderBase::getFormatInfo(void) { 266 if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) && mStoreMetaData) { 267 // Do nothing here, just to avoid thread 268 // contention in updateFormatInfo() 269 pthread_mutex_lock(&mFormatLock); 270 pthread_mutex_unlock(&mFormatLock); 271 } 272 273 return &mVideoFormatInfo; 274 } 275 getOutputQueueLength(void)276 int VideoDecoderBase::getOutputQueueLength(void) { 277 VideoSurfaceBuffer *p = mOutputHead; 278 279 int i = 0; 280 while (p) { 281 p = p->next; 282 i++; 283 } 284 285 return i; 286 } 287 getOutput(bool draining,VideoErrorBuffer * outErrBuf)288 const VideoRenderBuffer* VideoDecoderBase::getOutput(bool draining, VideoErrorBuffer *outErrBuf) { 289 if (mVAStarted == false) { 290 return NULL; 291 } 292 bool useGraphicBuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER; 293 294 if (draining) { 295 // complete decoding the last frame and ignore return 296 endDecodingFrame(false); 297 } 298 299 if (mOutputHead == NULL) { 300 return NULL; 301 } 302 303 // output by position (the first buffer) 304 VideoSurfaceBuffer *outputByPos = mOutputHead; 305 306 if (mLowDelay) { 307 mOutputHead = mOutputHead->next; 308 if (mOutputHead == NULL) { 309 mOutputTail = NULL; 310 } 311 vaSetTimestampForSurface(mVADisplay, outputByPos->renderBuffer.surface, outputByPos->renderBuffer.timeStamp); 312 if (useGraphicBuffer && !mUseGEN) { 313 vaSyncSurface(mVADisplay, outputByPos->renderBuffer.surface); 314 fillDecodingErrors(&(outputByPos->renderBuffer)); 315 } 316 if (draining && mOutputTail == NULL) { 317 outputByPos->renderBuffer.flag |= IS_EOS; 318 } 319 drainDecodingErrors(outErrBuf, &(outputByPos->renderBuffer)); 320 321 return &(outputByPos->renderBuffer); 322 } 323 324 VideoSurfaceBuffer *output = NULL; 325 if (mOutputMethod == OUTPUT_BY_POC) { 326 output = findOutputByPoc(draining); 327 } else if (mOutputMethod == OUTPUT_BY_PCT) { 328 output = findOutputByPct(draining); 329 } else { 330 ETRACE("Invalid output method."); 331 return NULL; 332 } 333 334 if (output == NULL) { 335 return NULL; 336 } 337 338 if (output != outputByPos) { 339 // remove this output from middle or end of the list 340 VideoSurfaceBuffer *p = outputByPos; 341 while (p->next != output) { 342 p = p->next; 343 } 344 p->next = output->next; 345 if (mOutputTail == output) { 346 mOutputTail = p; 347 } 348 } else { 349 // remove this output from head of the list 350 mOutputHead = mOutputHead->next; 351 if (mOutputHead == NULL) { 352 mOutputTail = NULL; 353 } 354 } 355 //VTRACE("Output POC %d for display (pts = %.2f)", output->pictureOrder, output->renderBuffer.timeStamp/1E6); 356 vaSetTimestampForSurface(mVADisplay, output->renderBuffer.surface, output->renderBuffer.timeStamp); 357 358 if (useGraphicBuffer && !mUseGEN) { 359 vaSyncSurface(mVADisplay, output->renderBuffer.surface); 360 fillDecodingErrors(&(output->renderBuffer)); 361 } 362 363 if (draining && mOutputTail == NULL) { 364 output->renderBuffer.flag |= IS_EOS; 365 } 366 367 drainDecodingErrors(outErrBuf, &(output->renderBuffer)); 368 369 return &(output->renderBuffer); 370 } 371 findOutputByPts()372 VideoSurfaceBuffer* VideoDecoderBase::findOutputByPts() { 373 // output by presentation time stamp - buffer with the smallest time stamp is output 374 VideoSurfaceBuffer *p = mOutputHead; 375 VideoSurfaceBuffer *outputByPts = NULL; 376 uint64_t pts = INVALID_PTS; 377 do { 378 if ((uint64_t)(p->renderBuffer.timeStamp) <= pts) { 379 // find buffer with the smallest PTS 380 pts = p->renderBuffer.timeStamp; 381 outputByPts = p; 382 } 383 p = p->next; 384 } while (p != NULL); 385 386 return outputByPts; 387 } 388 findOutputByPct(bool draining)389 VideoSurfaceBuffer* VideoDecoderBase::findOutputByPct(bool draining) { 390 // output by picture coding type (PCT) 391 // if there is more than one reference frame, the first reference frame is ouput, otherwise, 392 // output non-reference frame if there is any. 393 394 VideoSurfaceBuffer *p = mOutputHead; 395 VideoSurfaceBuffer *outputByPct = NULL; 396 int32_t reference = 0; 397 do { 398 if (p->referenceFrame) { 399 reference++; 400 if (reference > 1) { 401 // mOutputHead must be a reference frame 402 outputByPct = mOutputHead; 403 break; 404 } 405 } else { 406 // first non-reference frame 407 outputByPct = p; 408 break; 409 } 410 p = p->next; 411 } while (p != NULL); 412 413 if (outputByPct == NULL && draining) { 414 outputByPct = mOutputHead; 415 } 416 return outputByPct; 417 } 418 419 #if 0 420 VideoSurfaceBuffer* VideoDecoderBase::findOutputByPoc(bool draining) { 421 // output by picture order count (POC) 422 // Output criteria: 423 // if there is IDR frame (POC == 0), all the frames before IDR must be output; 424 // Otherwise, if draining flag is set or list is full, frame with the least POC is output; 425 // Otherwise, NOTHING is output 426 427 int32_t dpbFullness = 0; 428 for (int32_t i = 0; i < mNumSurfaces; i++) { 429 // count num of reference frames 430 if (mSurfaceBuffers[i].asReferernce) { 431 dpbFullness++; 432 } 433 } 434 435 if (mAcquiredBuffer && mAcquiredBuffer->asReferernce) { 436 // frame is being decoded and is not ready for output yet 437 dpbFullness--; 438 } 439 440 VideoSurfaceBuffer *p = mOutputHead; 441 while (p != NULL) { 442 // count dpbFullness with non-reference frame in the output queue 443 if (p->asReferernce == false) { 444 dpbFullness++; 445 } 446 p = p->next; 447 } 448 449 Retry: 450 p = mOutputHead; 451 VideoSurfaceBuffer *outputByPoc = NULL; 452 int32_t count = 0; 453 int32_t poc = MAXIMUM_POC; 454 455 do { 456 if (p->pictureOrder == 0) { 457 // output picture with the least POC before IDR 458 if (outputByPoc != NULL) { 459 mNextOutputPOC = outputByPoc->pictureOrder + 1; 460 return outputByPoc; 461 } else { 462 mNextOutputPOC = MINIMUM_POC; 463 } 464 } 465 466 // POC of the output candidate must not be less than mNextOutputPOC 467 if (p->pictureOrder < mNextOutputPOC) { 468 break; 469 } 470 471 if (p->pictureOrder < poc) { 472 // update the least POC. 473 poc = p->pictureOrder; 474 outputByPoc = p; 475 } 476 count++; 477 p = p->next; 478 } while (p != NULL && count < mOutputWindowSize); 479 480 if (draining == false && dpbFullness < mOutputWindowSize) { 481 // list is not full and we are not in draining state 482 // if DPB is already full, one frame must be output 483 return NULL; 484 } 485 486 if (outputByPoc == NULL) { 487 mNextOutputPOC = MINIMUM_POC; 488 goto Retry; 489 } 490 491 // for debugging purpose 492 if (outputByPoc->pictureOrder != 0 && outputByPoc->pictureOrder < mNextOutputPOC) { 493 ETRACE("Output POC is not incremental, expected %d, actual %d", mNextOutputPOC, outputByPoc->pictureOrder); 494 //gaps_in_frame_num_value_allowed_flag is not currently supported 495 } 496 497 mNextOutputPOC = outputByPoc->pictureOrder + 1; 498 499 return outputByPoc; 500 } 501 #else findOutputByPoc(bool draining)502 VideoSurfaceBuffer* VideoDecoderBase::findOutputByPoc(bool draining) { 503 VideoSurfaceBuffer *output = NULL; 504 VideoSurfaceBuffer *p = mOutputHead; 505 int32_t count = 0; 506 int32_t poc = MAXIMUM_POC; 507 VideoSurfaceBuffer *outputleastpoc = mOutputHead; 508 do { 509 count++; 510 if (p->pictureOrder == 0) { 511 // any picture before this POC (new IDR) must be output 512 if (output == NULL) { 513 mNextOutputPOC = MINIMUM_POC; 514 // looking for any POC with negative value 515 } else { 516 mNextOutputPOC = output->pictureOrder + 1; 517 break; 518 } 519 } 520 if (p->pictureOrder < poc && p->pictureOrder >= mNextOutputPOC) { 521 // this POC meets ouput criteria. 522 poc = p->pictureOrder; 523 output = p; 524 outputleastpoc = p; 525 } 526 if (poc == mNextOutputPOC || count == mOutputWindowSize) { 527 if (output != NULL) { 528 // this indicates two cases: 529 // 1) the next output POC is found. 530 // 2) output queue is full and there is at least one buffer meeting the output criteria. 531 mNextOutputPOC = output->pictureOrder + 1; 532 break; 533 } else { 534 // this indicates output queue is full and no buffer in the queue meets the output criteria 535 // restart processing as queue is FULL and output criteria is changed. (next output POC is 0) 536 mNextOutputPOC = MINIMUM_POC; 537 count = 0; 538 poc = MAXIMUM_POC; 539 p = mOutputHead; 540 continue; 541 } 542 } 543 if (p->next == NULL) { 544 output = NULL; 545 } 546 547 p = p->next; 548 } while (p != NULL); 549 550 if (draining == true && output == NULL) { 551 output = outputleastpoc; 552 } 553 554 return output; 555 } 556 #endif 557 checkBufferAvail(void)558 bool VideoDecoderBase::checkBufferAvail(void) { 559 if (!mInitialized) { 560 if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) == 0) { 561 return true; 562 } 563 for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) { 564 if (mSignalBufferPre[i] != NULL) { 565 return true; 566 } 567 } 568 return false; 569 } 570 // check whether there is buffer available for decoding 571 // TODO: check frame being referenced for frame skipping 572 VideoSurfaceBuffer *buffer = NULL; 573 for (int32_t i = 0; i < mNumSurfaces; i++) { 574 buffer = mSurfaceBuffers + i; 575 576 if (buffer->asReferernce == false && 577 buffer->renderBuffer.renderDone == true) { 578 querySurfaceRenderStatus(buffer); 579 if (buffer->renderBuffer.driverRenderDone == true) 580 return true; 581 } 582 } 583 return false; 584 } 585 acquireSurfaceBuffer(void)586 Decode_Status VideoDecoderBase::acquireSurfaceBuffer(void) { 587 if (mVAStarted == false) { 588 return DECODE_FAIL; 589 } 590 591 if (mAcquiredBuffer != NULL) { 592 ETRACE("mAcquiredBuffer is not NULL. Implementation bug."); 593 return DECODE_FAIL; 594 } 595 596 int nextAcquire = mSurfaceAcquirePos; 597 VideoSurfaceBuffer *acquiredBuffer = NULL; 598 bool acquired = false; 599 600 while (acquired == false) { 601 acquiredBuffer = mSurfaceBuffers + nextAcquire; 602 603 querySurfaceRenderStatus(acquiredBuffer); 604 605 if (acquiredBuffer->asReferernce == false && acquiredBuffer->renderBuffer.renderDone == true && acquiredBuffer->renderBuffer.driverRenderDone == true) { 606 // this is potential buffer for acquisition. Check if it is referenced by other surface for frame skipping 607 VideoSurfaceBuffer *temp; 608 acquired = true; 609 for (int i = 0; i < mNumSurfaces; i++) { 610 if (i == nextAcquire) { 611 continue; 612 } 613 temp = mSurfaceBuffers + i; 614 // use mSurfaces[nextAcquire] instead of acquiredBuffer->renderBuffer.surface as its the actual surface to use. 615 if (temp->renderBuffer.surface == mSurfaces[nextAcquire] && 616 temp->renderBuffer.renderDone == false) { 617 ITRACE("Surface is referenced by other surface buffer."); 618 acquired = false; 619 break; 620 } 621 } 622 } 623 if (acquired) { 624 break; 625 } 626 nextAcquire++; 627 if (nextAcquire == mNumSurfaces) { 628 nextAcquire = 0; 629 } 630 if (nextAcquire == mSurfaceAcquirePos) { 631 return DECODE_NO_SURFACE; 632 } 633 } 634 635 if (acquired == false) { 636 return DECODE_NO_SURFACE; 637 } 638 639 mAcquiredBuffer = acquiredBuffer; 640 mSurfaceAcquirePos = nextAcquire; 641 642 // set surface again as surface maybe reset by skipped frame. 643 // skipped frame is a "non-coded frame" and decoder needs to duplicate the previous reference frame as the output. 644 mAcquiredBuffer->renderBuffer.surface = mSurfaces[mSurfaceAcquirePos]; 645 if (mSurfaceUserPtr && mAcquiredBuffer->mappedData) { 646 mAcquiredBuffer->mappedData->data = mSurfaceUserPtr[mSurfaceAcquirePos]; 647 } 648 mAcquiredBuffer->renderBuffer.timeStamp = INVALID_PTS; 649 mAcquiredBuffer->renderBuffer.display = mVADisplay; 650 mAcquiredBuffer->renderBuffer.flag = 0; 651 mAcquiredBuffer->renderBuffer.renderDone = false; 652 mAcquiredBuffer->asReferernce = false; 653 mAcquiredBuffer->renderBuffer.errBuf.errorNumber = 0; 654 mAcquiredBuffer->renderBuffer.errBuf.timeStamp = INVALID_PTS; 655 656 return DECODE_SUCCESS; 657 } 658 outputSurfaceBuffer(void)659 Decode_Status VideoDecoderBase::outputSurfaceBuffer(void) { 660 Decode_Status status; 661 if (mAcquiredBuffer == NULL) { 662 ETRACE("mAcquiredBuffer is NULL. Implementation bug."); 663 return DECODE_FAIL; 664 } 665 666 if (mRawOutput) { 667 status = getRawDataFromSurface(); 668 CHECK_STATUS(); 669 } 670 671 // frame is successfly decoded to the current surface, it is ready for output 672 if (mShowFrame) { 673 mAcquiredBuffer->renderBuffer.renderDone = false; 674 } else { 675 mAcquiredBuffer->renderBuffer.renderDone = true; 676 } 677 678 // decoder must set "asReference and referenceFrame" flags properly 679 680 // update reference frames 681 if (mAcquiredBuffer->referenceFrame) { 682 if (mManageReference) { 683 // managing reference for MPEG4/H.263/WMV. 684 // AVC should manage reference frame in a different way 685 if (mForwardReference != NULL) { 686 // this foward reference is no longer needed 687 mForwardReference->asReferernce = false; 688 } 689 // Forware reference for either P or B frame prediction 690 mForwardReference = mLastReference; 691 mAcquiredBuffer->asReferernce = true; 692 } 693 694 // the last reference frame. 695 mLastReference = mAcquiredBuffer; 696 } 697 // add to the output list 698 if (mShowFrame) { 699 if (mOutputHead == NULL) { 700 mOutputHead = mAcquiredBuffer; 701 } else { 702 mOutputTail->next = mAcquiredBuffer; 703 } 704 mOutputTail = mAcquiredBuffer; 705 mOutputTail->next = NULL; 706 } 707 708 //VTRACE("Pushing POC %d to queue (pts = %.2f)", mAcquiredBuffer->pictureOrder, mAcquiredBuffer->renderBuffer.timeStamp/1E6); 709 710 mAcquiredBuffer = NULL; 711 mSurfaceAcquirePos = (mSurfaceAcquirePos + 1 ) % mNumSurfaces; 712 return DECODE_SUCCESS; 713 } 714 releaseSurfaceBuffer(void)715 Decode_Status VideoDecoderBase::releaseSurfaceBuffer(void) { 716 if (mAcquiredBuffer == NULL) { 717 // this is harmless error 718 return DECODE_SUCCESS; 719 } 720 721 // frame is not decoded to the acquired buffer, current surface is invalid, and can't be output. 722 mAcquiredBuffer->asReferernce = false; 723 mAcquiredBuffer->renderBuffer.renderDone = true; 724 mAcquiredBuffer = NULL; 725 return DECODE_SUCCESS; 726 } 727 flushSurfaceBuffers(void)728 void VideoDecoderBase::flushSurfaceBuffers(void) { 729 endDecodingFrame(true); 730 VideoSurfaceBuffer *p = NULL; 731 while (mOutputHead) { 732 mOutputHead->renderBuffer.renderDone = true; 733 p = mOutputHead; 734 mOutputHead = mOutputHead->next; 735 p->next = NULL; 736 } 737 mOutputHead = NULL; 738 mOutputTail = NULL; 739 } 740 endDecodingFrame(bool dropFrame)741 Decode_Status VideoDecoderBase::endDecodingFrame(bool dropFrame) { 742 Decode_Status status = DECODE_SUCCESS; 743 VAStatus vaStatus; 744 745 if (mDecodingFrame == false) { 746 if (mAcquiredBuffer != NULL) { 747 //ETRACE("mAcquiredBuffer is not NULL. Implementation bug."); 748 releaseSurfaceBuffer(); 749 status = DECODE_FAIL; 750 } 751 return status; 752 } 753 // return through exit label to reset mDecodingFrame 754 if (mAcquiredBuffer == NULL) { 755 ETRACE("mAcquiredBuffer is NULL. Implementation bug."); 756 status = DECODE_FAIL; 757 goto exit; 758 } 759 760 vaStatus = vaEndPicture(mVADisplay, mVAContext); 761 if (vaStatus != VA_STATUS_SUCCESS) { 762 releaseSurfaceBuffer(); 763 ETRACE("vaEndPicture failed. vaStatus = %d", vaStatus); 764 status = DECODE_DRIVER_FAIL; 765 goto exit; 766 } 767 768 if (dropFrame) { 769 // we are asked to drop this decoded picture 770 VTRACE("Frame dropped in endDecodingFrame"); 771 vaStatus = vaSyncSurface(mVADisplay, mAcquiredBuffer->renderBuffer.surface); 772 releaseSurfaceBuffer(); 773 goto exit; 774 } 775 status = outputSurfaceBuffer(); 776 // fall through 777 exit: 778 mDecodingFrame = false; 779 return status; 780 } 781 782 setupVA(uint32_t numSurface,VAProfile profile,uint32_t numExtraSurface)783 Decode_Status VideoDecoderBase::setupVA(uint32_t numSurface, VAProfile profile, uint32_t numExtraSurface) { 784 VAStatus vaStatus = VA_STATUS_SUCCESS; 785 Decode_Status status; 786 787 if (mVAStarted) { 788 return DECODE_SUCCESS; 789 } 790 791 mRotationDegrees = 0; 792 if (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER){ 793 #ifdef TARGET_HAS_ISV 794 if (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber - mConfigBuffer.vppBufferNum) 795 #else 796 if (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber) 797 #endif 798 return DECODE_FORMAT_CHANGE; 799 800 numSurface = mConfigBuffer.surfaceNumber; 801 // if format has been changed in USE_NATIVE_GRAPHIC_BUFFER mode, 802 // we can not setupVA here when the graphic buffer resolution is smaller than the resolution decoder really needs 803 if (mSizeChanged) { 804 if (mStoreMetaData || (!mStoreMetaData && (mVideoFormatInfo.surfaceWidth < mVideoFormatInfo.width || mVideoFormatInfo.surfaceHeight < mVideoFormatInfo.height))) { 805 mSizeChanged = false; 806 return DECODE_FORMAT_CHANGE; 807 } 808 } 809 } 810 811 // TODO: validate profile 812 if (numSurface == 0) { 813 return DECODE_FAIL; 814 } 815 816 if (mConfigBuffer.flag & HAS_MINIMUM_SURFACE_NUMBER) { 817 if (numSurface < mConfigBuffer.surfaceNumber) { 818 WTRACE("surface to allocated %d is less than minimum number required %d", 819 numSurface, mConfigBuffer.surfaceNumber); 820 numSurface = mConfigBuffer.surfaceNumber; 821 } 822 } 823 824 if (mVADisplay != NULL) { 825 ETRACE("VA is partially started."); 826 return DECODE_FAIL; 827 } 828 829 // Display is defined as "unsigned int" 830 #ifndef USE_HYBRID_DRIVER 831 mDisplay = new Display; 832 *mDisplay = ANDROID_DISPLAY_HANDLE; 833 #else 834 if (profile >= VAProfileH264Baseline && profile <= VAProfileVC1Advanced) { 835 ITRACE("Using GEN driver"); 836 mDisplay = "libva_driver_name=i965"; 837 mUseGEN = true; 838 } else { 839 ITRACE("Using PVR driver"); 840 mDisplay = "libva_driver_name=pvr"; 841 mUseGEN = false; 842 } 843 #endif 844 mVADisplay = vaGetDisplay(mDisplay); 845 if (mVADisplay == NULL) { 846 ETRACE("vaGetDisplay failed."); 847 return DECODE_DRIVER_FAIL; 848 } 849 850 int majorVersion, minorVersion; 851 vaStatus = vaInitialize(mVADisplay, &majorVersion, &minorVersion); 852 CHECK_VA_STATUS("vaInitialize"); 853 854 if ((int32_t)profile != VAProfileSoftwareDecoding) { 855 856 status = checkHardwareCapability(); 857 CHECK_STATUS("checkHardwareCapability"); 858 859 #if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING) 860 status = getCodecSpecificConfigs(profile, &mVAConfig); 861 CHECK_STATUS("getCodecSpecificAttributes"); 862 #else 863 VAConfigAttrib attrib; 864 //We are requesting RT attributes 865 attrib.type = VAConfigAttribRTFormat; 866 attrib.value = VA_RT_FORMAT_YUV420; 867 868 vaStatus = vaCreateConfig( 869 mVADisplay, 870 profile, 871 VAEntrypointVLD, 872 &attrib, 873 1, 874 &mVAConfig); 875 CHECK_VA_STATUS("vaCreateConfig"); 876 #endif 877 } 878 879 mNumSurfaces = numSurface; 880 mNumExtraSurfaces = numExtraSurface; 881 mSurfaces = new VASurfaceID [mNumSurfaces + mNumExtraSurfaces]; 882 mExtraSurfaces = mSurfaces + mNumSurfaces; 883 for (int i = 0; i < mNumSurfaces + mNumExtraSurfaces; ++i) { 884 mSurfaces[i] = VA_INVALID_SURFACE; 885 } 886 if (mSurfaces == NULL) { 887 return DECODE_MEMORY_FAIL; 888 } 889 890 setRenderRect(); 891 setColorSpaceInfo(mVideoFormatInfo.colorMatrix, mVideoFormatInfo.videoRange); 892 893 int32_t format = VA_RT_FORMAT_YUV420; 894 if (mConfigBuffer.flag & WANT_SURFACE_PROTECTION) { 895 #ifndef USE_AVC_SHORT_FORMAT 896 format |= VA_RT_FORMAT_PROTECTED; 897 WTRACE("Surface is protected."); 898 #endif 899 } 900 if (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) { 901 if (!mStoreMetaData) { 902 VASurfaceAttrib attribs[2]; 903 mVASurfaceAttrib = new VASurfaceAttribExternalBuffers; 904 if (mVASurfaceAttrib == NULL) { 905 return DECODE_MEMORY_FAIL; 906 } 907 908 mVASurfaceAttrib->buffers= (unsigned long *)malloc(sizeof(unsigned long)*mNumSurfaces); 909 if (mVASurfaceAttrib->buffers == NULL) { 910 return DECODE_MEMORY_FAIL; 911 } 912 mVASurfaceAttrib->num_buffers = mNumSurfaces; 913 mVASurfaceAttrib->pixel_format = VA_FOURCC_NV12; 914 mVASurfaceAttrib->width = mVideoFormatInfo.surfaceWidth; 915 mVASurfaceAttrib->height = mVideoFormatInfo.surfaceHeight; 916 mVASurfaceAttrib->data_size = mConfigBuffer.graphicBufferHStride * mConfigBuffer.graphicBufferVStride * 1.5; 917 mVASurfaceAttrib->num_planes = 2; 918 mVASurfaceAttrib->pitches[0] = mConfigBuffer.graphicBufferHStride; 919 mVASurfaceAttrib->pitches[1] = mConfigBuffer.graphicBufferHStride; 920 mVASurfaceAttrib->pitches[2] = 0; 921 mVASurfaceAttrib->pitches[3] = 0; 922 mVASurfaceAttrib->offsets[0] = 0; 923 mVASurfaceAttrib->offsets[1] = mConfigBuffer.graphicBufferHStride * mConfigBuffer.graphicBufferVStride; 924 mVASurfaceAttrib->offsets[2] = 0; 925 mVASurfaceAttrib->offsets[3] = 0; 926 mVASurfaceAttrib->private_data = (void *)mConfigBuffer.nativeWindow; 927 mVASurfaceAttrib->flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC; 928 if (mConfigBuffer.flag & USE_TILING_MEMORY) 929 mVASurfaceAttrib->flags |= VA_SURFACE_EXTBUF_DESC_ENABLE_TILING; 930 931 for (int i = 0; i < mNumSurfaces; i++) { 932 mVASurfaceAttrib->buffers[i] = (unsigned long)mConfigBuffer.graphicBufferHandler[i]; 933 } 934 935 attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType; 936 attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE; 937 attribs[0].value.type = VAGenericValueTypeInteger; 938 attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC; 939 940 attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor; 941 attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE; 942 attribs[1].value.type = VAGenericValueTypePointer; 943 attribs[1].value.value.p = (void *)mVASurfaceAttrib; 944 945 vaStatus = vaCreateSurfaces( 946 mVADisplay, 947 format, 948 mVideoFormatInfo.surfaceWidth, 949 mVideoFormatInfo.surfaceHeight, 950 mSurfaces, 951 mNumSurfaces, 952 attribs, 953 2); 954 } 955 } else { 956 vaStatus = vaCreateSurfaces( 957 mVADisplay, 958 format, 959 mVideoFormatInfo.width, 960 mVideoFormatInfo.height, 961 mSurfaces, 962 mNumSurfaces, 963 NULL, 964 0); 965 mVideoFormatInfo.surfaceWidth = mVideoFormatInfo.width; 966 mVideoFormatInfo.surfaceHeight = mVideoFormatInfo.height; 967 } 968 CHECK_VA_STATUS("vaCreateSurfaces"); 969 970 if (mNumExtraSurfaces != 0) { 971 vaStatus = vaCreateSurfaces( 972 mVADisplay, 973 format, 974 mVideoFormatInfo.surfaceWidth, 975 mVideoFormatInfo.surfaceHeight, 976 mExtraSurfaces, 977 mNumExtraSurfaces, 978 NULL, 979 0); 980 CHECK_VA_STATUS("vaCreateSurfaces"); 981 } 982 983 mVideoFormatInfo.surfaceNumber = mNumSurfaces; 984 mVideoFormatInfo.ctxSurfaces = mSurfaces; 985 986 if ((int32_t)profile != VAProfileSoftwareDecoding) { 987 if (mStoreMetaData) { 988 if (mUseGEN) { 989 vaStatus = vaCreateContext( 990 mVADisplay, 991 mVAConfig, 992 mVideoFormatInfo.surfaceWidth, 993 mVideoFormatInfo.surfaceHeight, 994 0, 995 NULL, 996 0, 997 &mVAContext); 998 } else { 999 vaStatus = vaCreateContext( 1000 mVADisplay, 1001 mVAConfig, 1002 mVideoFormatInfo.surfaceWidth, 1003 mVideoFormatInfo.surfaceHeight, 1004 0, 1005 NULL, 1006 mNumSurfaces + mNumExtraSurfaces, 1007 &mVAContext); 1008 } 1009 } else { 1010 vaStatus = vaCreateContext( 1011 mVADisplay, 1012 mVAConfig, 1013 mVideoFormatInfo.surfaceWidth, 1014 mVideoFormatInfo.surfaceHeight, 1015 0, 1016 mSurfaces, 1017 mNumSurfaces + mNumExtraSurfaces, 1018 &mVAContext); 1019 } 1020 CHECK_VA_STATUS("vaCreateContext"); 1021 } 1022 1023 mSurfaceBuffers = new VideoSurfaceBuffer [mNumSurfaces]; 1024 if (mSurfaceBuffers == NULL) { 1025 return DECODE_MEMORY_FAIL; 1026 } 1027 initSurfaceBuffer(true); 1028 1029 if ((int32_t)profile == VAProfileSoftwareDecoding) { 1030 // derive user pointer from surface for direct access 1031 status = mapSurface(); 1032 CHECK_STATUS("mapSurface") 1033 } 1034 1035 setRotationDegrees(mConfigBuffer.rotationDegrees); 1036 1037 mVAStarted = true; 1038 1039 pthread_mutex_lock(&mLock); 1040 if (mStoreMetaData) { 1041 for (uint32_t i = 0; i < mMetaDataBuffersNum; i++) { 1042 status = createSurfaceFromHandle(i); 1043 CHECK_STATUS("createSurfaceFromHandle"); 1044 mSurfaceBuffers[i].renderBuffer.graphicBufferIndex = i; 1045 } 1046 } 1047 pthread_mutex_unlock(&mLock); 1048 1049 return DECODE_SUCCESS; 1050 } 1051 terminateVA(void)1052 Decode_Status VideoDecoderBase::terminateVA(void) { 1053 mSignalBufferSize = 0; 1054 for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) { 1055 mSignalBufferPre[i] = NULL; 1056 } 1057 1058 if (mVAStarted == false) { 1059 // VA hasn't been started yet 1060 return DECODE_SUCCESS; 1061 } 1062 1063 if (mSurfaceBuffers) { 1064 for (int32_t i = 0; i < mNumSurfaces; i++) { 1065 if (mSurfaceBuffers[i].renderBuffer.rawData) { 1066 if (mSurfaceBuffers[i].renderBuffer.rawData->data) { 1067 delete [] mSurfaceBuffers[i].renderBuffer.rawData->data; 1068 } 1069 delete mSurfaceBuffers[i].renderBuffer.rawData; 1070 } 1071 if (mSurfaceBuffers[i].mappedData) { 1072 // don't delete data pointer as it is mapped from surface 1073 delete mSurfaceBuffers[i].mappedData; 1074 } 1075 } 1076 delete [] mSurfaceBuffers; 1077 mSurfaceBuffers = NULL; 1078 } 1079 1080 if (mVASurfaceAttrib) { 1081 if (mVASurfaceAttrib->buffers) free(mVASurfaceAttrib->buffers); 1082 delete mVASurfaceAttrib; 1083 mVASurfaceAttrib = NULL; 1084 } 1085 1086 1087 if (mSurfaceUserPtr) { 1088 delete [] mSurfaceUserPtr; 1089 mSurfaceUserPtr = NULL; 1090 } 1091 1092 if (mSurfaces) { 1093 vaDestroySurfaces(mVADisplay, mSurfaces, mStoreMetaData ? mMetaDataBuffersNum : (mNumSurfaces + mNumExtraSurfaces)); 1094 delete [] mSurfaces; 1095 mSurfaces = NULL; 1096 } 1097 1098 if (mVAContext != VA_INVALID_ID) { 1099 vaDestroyContext(mVADisplay, mVAContext); 1100 mVAContext = VA_INVALID_ID; 1101 } 1102 1103 if (mVAConfig != VA_INVALID_ID) { 1104 vaDestroyConfig(mVADisplay, mVAConfig); 1105 mVAConfig = VA_INVALID_ID; 1106 } 1107 1108 if (mVADisplay) { 1109 vaTerminate(mVADisplay); 1110 mVADisplay = NULL; 1111 } 1112 1113 if (mDisplay) { 1114 #ifndef USE_HYBRID_DRIVER 1115 delete mDisplay; 1116 #endif 1117 mDisplay = NULL; 1118 } 1119 1120 mVAStarted = false; 1121 mInitialized = false; 1122 mErrReportEnabled = false; 1123 if (mStoreMetaData) { 1124 mMetaDataBuffersNum = 0; 1125 mSurfaceAcquirePos = 0; 1126 } 1127 return DECODE_SUCCESS; 1128 } 1129 parseBuffer(uint8_t * buffer,int32_t size,bool config,void ** vbpData)1130 Decode_Status VideoDecoderBase::parseBuffer(uint8_t *buffer, int32_t size, bool config, void** vbpData) { 1131 // DON'T check if mVAStarted == true 1132 if (mParserHandle == NULL) { 1133 return DECODE_NO_PARSER; 1134 } 1135 1136 uint32_t vbpStatus; 1137 if (buffer == NULL || size <= 0) { 1138 return DECODE_INVALID_DATA; 1139 } 1140 1141 uint8_t configFlag = config ? 1 : 0; 1142 vbpStatus = mParserParse(mParserHandle, buffer, size, configFlag); 1143 CHECK_VBP_STATUS("vbp_parse"); 1144 1145 vbpStatus = mParserQuery(mParserHandle, vbpData); 1146 CHECK_VBP_STATUS("vbp_query"); 1147 1148 return DECODE_SUCCESS; 1149 } 1150 mapSurface(void)1151 Decode_Status VideoDecoderBase::mapSurface(void) { 1152 VAStatus vaStatus = VA_STATUS_SUCCESS; 1153 VAImage image; 1154 uint8_t *userPtr; 1155 mSurfaceUserPtr = new uint8_t* [mNumSurfaces]; 1156 if (mSurfaceUserPtr == NULL) { 1157 return DECODE_MEMORY_FAIL; 1158 } 1159 1160 for (int32_t i = 0; i< mNumSurfaces; i++) { 1161 vaStatus = vaDeriveImage(mVADisplay, mSurfaces[i], &image); 1162 CHECK_VA_STATUS("vaDeriveImage"); 1163 vaStatus = vaMapBuffer(mVADisplay, image.buf, (void**)&userPtr); 1164 CHECK_VA_STATUS("vaMapBuffer"); 1165 mSurfaceUserPtr[i] = userPtr; 1166 mSurfaceBuffers[i].mappedData = new VideoFrameRawData; 1167 if (mSurfaceBuffers[i].mappedData == NULL) { 1168 return DECODE_MEMORY_FAIL; 1169 } 1170 mSurfaceBuffers[i].mappedData->own = false; // derived from surface so can't be released 1171 mSurfaceBuffers[i].mappedData->data = NULL; // specified during acquireSurfaceBuffer 1172 mSurfaceBuffers[i].mappedData->fourcc = image.format.fourcc; 1173 mSurfaceBuffers[i].mappedData->width = mVideoFormatInfo.width; 1174 mSurfaceBuffers[i].mappedData->height = mVideoFormatInfo.height; 1175 mSurfaceBuffers[i].mappedData->size = image.data_size; 1176 for (int pi = 0; pi < 3; pi++) { 1177 mSurfaceBuffers[i].mappedData->pitch[pi] = image.pitches[pi]; 1178 mSurfaceBuffers[i].mappedData->offset[pi] = image.offsets[pi]; 1179 } 1180 // debug information 1181 if (image.pitches[0] != image.pitches[1] || 1182 image.width != mVideoFormatInfo.width || 1183 image.height != mVideoFormatInfo.height || 1184 image.offsets[0] != 0) { 1185 WTRACE("Unexpected VAImage format, w = %d, h = %d, offset = %d", image.width, image.height, image.offsets[0]); 1186 } 1187 // TODO: do we need to unmap buffer? 1188 //vaStatus = vaUnmapBuffer(mVADisplay, image.buf); 1189 //CHECK_VA_STATUS("vaMapBuffer"); 1190 vaStatus = vaDestroyImage(mVADisplay,image.image_id); 1191 CHECK_VA_STATUS("vaDestroyImage"); 1192 1193 } 1194 return DECODE_SUCCESS; 1195 } 1196 getRawDataFromSurface(VideoRenderBuffer * renderBuffer,uint8_t * pRawData,uint32_t * pSize,bool internal)1197 Decode_Status VideoDecoderBase::getRawDataFromSurface(VideoRenderBuffer *renderBuffer, uint8_t *pRawData, uint32_t *pSize, bool internal) { 1198 if (internal) { 1199 if (mAcquiredBuffer == NULL) { 1200 return DECODE_FAIL; 1201 } 1202 renderBuffer = &(mAcquiredBuffer->renderBuffer); 1203 } 1204 1205 VAStatus vaStatus; 1206 VAImage vaImage; 1207 vaStatus = vaSyncSurface(renderBuffer->display, renderBuffer->surface); 1208 CHECK_VA_STATUS("vaSyncSurface"); 1209 1210 vaStatus = vaDeriveImage(renderBuffer->display, renderBuffer->surface, &vaImage); 1211 CHECK_VA_STATUS("vaDeriveImage"); 1212 1213 void *pBuf = NULL; 1214 vaStatus = vaMapBuffer(renderBuffer->display, vaImage.buf, &pBuf); 1215 CHECK_VA_STATUS("vaMapBuffer"); 1216 1217 1218 // size in NV12 format 1219 uint32_t cropWidth = mVideoFormatInfo.width - (mVideoFormatInfo.cropLeft + mVideoFormatInfo.cropRight); 1220 uint32_t cropHeight = mVideoFormatInfo.height - (mVideoFormatInfo.cropBottom + mVideoFormatInfo.cropTop); 1221 if (strcasecmp(mVideoFormatInfo.mimeType,"video/avc") == 0 || 1222 strcasecmp(mVideoFormatInfo.mimeType,"video/avc-secure") == 0 || 1223 strcasecmp(mVideoFormatInfo.mimeType,"video/h264") == 0) { 1224 cropHeight = mVideoFormatInfo.height; 1225 cropWidth = mVideoFormatInfo.width; 1226 } 1227 int32_t size = cropWidth * cropHeight * 3 / 2; 1228 1229 if (internal) { 1230 VideoFrameRawData *rawData = NULL; 1231 if (renderBuffer->rawData == NULL) { 1232 rawData = new VideoFrameRawData; 1233 if (rawData == NULL) { 1234 return DECODE_MEMORY_FAIL; 1235 } 1236 memset(rawData, 0, sizeof(VideoFrameRawData)); 1237 renderBuffer->rawData = rawData; 1238 } else { 1239 rawData = renderBuffer->rawData; 1240 } 1241 1242 if (rawData->data != NULL && rawData->size != size) { 1243 delete [] rawData->data; 1244 rawData->data = NULL; 1245 rawData->size = 0; 1246 } 1247 if (rawData->data == NULL) { 1248 rawData->data = new uint8_t [size]; 1249 if (rawData->data == NULL) { 1250 return DECODE_MEMORY_FAIL; 1251 } 1252 } 1253 1254 rawData->own = true; // allocated by this library 1255 rawData->width = cropWidth; 1256 rawData->height = cropHeight; 1257 rawData->pitch[0] = cropWidth; 1258 rawData->pitch[1] = cropWidth; 1259 rawData->pitch[2] = 0; // interleaved U/V, two planes 1260 rawData->offset[0] = 0; 1261 rawData->offset[1] = cropWidth * cropHeight; 1262 rawData->offset[2] = cropWidth * cropHeight * 3 / 2; 1263 rawData->size = size; 1264 rawData->fourcc = 'NV12'; 1265 1266 pRawData = rawData->data; 1267 } else { 1268 *pSize = size; 1269 } 1270 1271 if (size == (int32_t)vaImage.data_size) { 1272 #ifdef __SSE4_1__ 1273 stream_memcpy(pRawData, pBuf, size); 1274 #else 1275 memcpy(pRawData, pBuf, size); 1276 #endif 1277 } else { 1278 // copy Y data 1279 uint8_t *src = (uint8_t*)pBuf; 1280 uint8_t *dst = pRawData; 1281 uint32_t row = 0; 1282 for (row = 0; row < cropHeight; row++) { 1283 #ifdef __SSE4_1__ 1284 stream_memcpy(dst, src, cropWidth); 1285 #else 1286 memcpy(dst, src, cropWidth); 1287 #endif 1288 dst += cropWidth; 1289 src += vaImage.pitches[0]; 1290 } 1291 // copy interleaved V and U data 1292 src = (uint8_t*)pBuf + vaImage.offsets[1]; 1293 for (row = 0; row < cropHeight / 2; row++) { 1294 #ifdef __SSE4_1__ 1295 stream_memcpy(dst, src, cropWidth); 1296 #else 1297 memcpy(dst, src, cropWidth); 1298 #endif 1299 dst += cropWidth; 1300 src += vaImage.pitches[1]; 1301 } 1302 } 1303 1304 vaStatus = vaUnmapBuffer(renderBuffer->display, vaImage.buf); 1305 CHECK_VA_STATUS("vaUnmapBuffer"); 1306 1307 vaStatus = vaDestroyImage(renderBuffer->display, vaImage.image_id); 1308 CHECK_VA_STATUS("vaDestroyImage"); 1309 1310 return DECODE_SUCCESS; 1311 } 1312 createSurfaceFromHandle(int index)1313 Decode_Status VideoDecoderBase::createSurfaceFromHandle(int index) { 1314 VAStatus vaStatus = VA_STATUS_SUCCESS; 1315 Decode_Status status; 1316 1317 int32_t format = VA_RT_FORMAT_YUV420; 1318 if (mConfigBuffer.flag & WANT_SURFACE_PROTECTION) { 1319 #ifndef USE_AVC_SHORT_FORMAT 1320 format |= VA_RT_FORMAT_PROTECTED; 1321 WTRACE("Surface is protected."); 1322 #endif 1323 } 1324 VASurfaceAttrib attribs[2]; 1325 VASurfaceAttribExternalBuffers surfExtBuf; 1326 surfExtBuf.num_buffers = 1; 1327 surfExtBuf.pixel_format = VA_FOURCC_NV12; 1328 surfExtBuf.width = mVideoFormatInfo.surfaceWidth; 1329 surfExtBuf.height = mVideoFormatInfo.surfaceHeight; 1330 surfExtBuf.data_size = mConfigBuffer.graphicBufferHStride * mConfigBuffer.graphicBufferVStride * 1.5; 1331 surfExtBuf.num_planes = 2; 1332 surfExtBuf.pitches[0] = mConfigBuffer.graphicBufferHStride; 1333 surfExtBuf.pitches[1] = mConfigBuffer.graphicBufferHStride; 1334 surfExtBuf.pitches[2] = 0; 1335 surfExtBuf.pitches[3] = 0; 1336 surfExtBuf.offsets[0] = 0; 1337 surfExtBuf.offsets[1] = mConfigBuffer.graphicBufferHStride * mConfigBuffer.graphicBufferVStride; 1338 surfExtBuf.offsets[2] = 0; 1339 surfExtBuf.offsets[3] = 0; 1340 surfExtBuf.private_data = (void *)mConfigBuffer.nativeWindow; 1341 surfExtBuf.flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC; 1342 if (mConfigBuffer.flag & USE_TILING_MEMORY) { 1343 surfExtBuf.flags |= VA_SURFACE_EXTBUF_DESC_ENABLE_TILING; 1344 } 1345 1346 surfExtBuf.buffers = (long unsigned int*)&(mConfigBuffer.graphicBufferHandler[index]); 1347 1348 attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType; 1349 attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE; 1350 attribs[0].value.type = VAGenericValueTypeInteger; 1351 attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC; 1352 1353 attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor; 1354 attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE; 1355 attribs[1].value.type = VAGenericValueTypePointer; 1356 attribs[1].value.value.p = (void *)&surfExtBuf; 1357 1358 vaStatus = vaCreateSurfaces( 1359 mVADisplay, 1360 format, 1361 mVideoFormatInfo.surfaceWidth, 1362 mVideoFormatInfo.surfaceHeight, 1363 &(mSurfaces[index]), 1364 1, 1365 attribs, 1366 2); 1367 CHECK_VA_STATUS("vaCreateSurfaces"); 1368 1369 return DECODE_SUCCESS; 1370 } 1371 initSurfaceBuffer(bool reset)1372 void VideoDecoderBase::initSurfaceBuffer(bool reset) { 1373 bool useGraphicBuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER; 1374 if (useGraphicBuffer && reset) { 1375 pthread_mutex_lock(&mLock); 1376 } 1377 for (int32_t i = 0; i < mNumSurfaces; i++) { 1378 mSurfaceBuffers[i].renderBuffer.display = mVADisplay; 1379 mSurfaceBuffers[i].renderBuffer.surface = VA_INVALID_SURFACE; // set in acquireSurfaceBuffer 1380 mSurfaceBuffers[i].renderBuffer.flag = 0; 1381 mSurfaceBuffers[i].renderBuffer.scanFormat = VA_FRAME_PICTURE; 1382 mSurfaceBuffers[i].renderBuffer.timeStamp = 0; 1383 mSurfaceBuffers[i].referenceFrame = false; 1384 mSurfaceBuffers[i].asReferernce= false; 1385 mSurfaceBuffers[i].pictureOrder = 0; 1386 mSurfaceBuffers[i].next = NULL; 1387 if (reset == true) { 1388 mSurfaceBuffers[i].renderBuffer.rawData = NULL; 1389 mSurfaceBuffers[i].mappedData = NULL; 1390 } 1391 if (useGraphicBuffer) { 1392 if (reset) { 1393 mSurfaceBuffers[i].renderBuffer.graphicBufferHandle = mConfigBuffer.graphicBufferHandler[i]; 1394 mSurfaceBuffers[i].renderBuffer.renderDone = false; //default false 1395 for (uint32_t j = 0; j < mSignalBufferSize; j++) { 1396 if(mSignalBufferPre[j] != NULL && mSignalBufferPre[j] == mSurfaceBuffers[i].renderBuffer.graphicBufferHandle) { 1397 mSurfaceBuffers[i].renderBuffer.renderDone = true; 1398 VTRACE("initSurfaceBuffer set renderDone = true index = %d", i); 1399 mSignalBufferPre[j] = NULL; 1400 break; 1401 } 1402 } 1403 } else { 1404 mSurfaceBuffers[i].renderBuffer.renderDone = false; 1405 } 1406 } else { 1407 mSurfaceBuffers[i].renderBuffer.graphicBufferHandle = NULL; 1408 mSurfaceBuffers[i].renderBuffer.renderDone = true; 1409 } 1410 mSurfaceBuffers[i].renderBuffer.graphicBufferIndex = i; 1411 } 1412 1413 if (useGraphicBuffer && reset) { 1414 mInitialized = true; 1415 mSignalBufferSize = 0; 1416 pthread_mutex_unlock(&mLock); 1417 } 1418 } 1419 signalRenderDone(void * graphichandler,bool isNew)1420 Decode_Status VideoDecoderBase::signalRenderDone(void * graphichandler, bool isNew) { 1421 Decode_Status status; 1422 if (graphichandler == NULL) { 1423 return DECODE_SUCCESS; 1424 } 1425 pthread_mutex_lock(&mLock); 1426 bool graphicBufferMode = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER; 1427 if (mStoreMetaData) { 1428 if (!graphicBufferMode) { 1429 pthread_mutex_unlock(&mLock); 1430 return DECODE_SUCCESS; 1431 } 1432 1433 if ((mMetaDataBuffersNum < mConfigBuffer.surfaceNumber) && isNew) { 1434 mConfigBuffer.graphicBufferHandler[mMetaDataBuffersNum] = graphichandler; 1435 if (mInitialized) { 1436 mSurfaceBuffers[mMetaDataBuffersNum].renderBuffer.graphicBufferHandle = graphichandler; 1437 mSurfaceBuffers[mMetaDataBuffersNum].renderBuffer.graphicBufferIndex = mMetaDataBuffersNum; 1438 } 1439 } 1440 } 1441 int i = 0; 1442 if (!mInitialized) { 1443 if (mSignalBufferSize >= MAX_GRAPHIC_BUFFER_NUM) { 1444 pthread_mutex_unlock(&mLock); 1445 return DECODE_INVALID_DATA; 1446 } 1447 mSignalBufferPre[mSignalBufferSize++] = graphichandler; 1448 VTRACE("SignalRenderDoneFlag mInitialized = false graphichandler = %p, mSignalBufferSize = %d", graphichandler, mSignalBufferSize); 1449 } else { 1450 if (!graphicBufferMode) { 1451 pthread_mutex_unlock(&mLock); 1452 return DECODE_SUCCESS; 1453 } 1454 if (mStoreMetaData) { 1455 if ((mMetaDataBuffersNum < mConfigBuffer.surfaceNumber) && isNew) { 1456 if (mVAStarted) { 1457 status = createSurfaceFromHandle(mMetaDataBuffersNum); 1458 CHECK_STATUS("createSurfaceFromHandle") 1459 } 1460 } 1461 } 1462 for (i = 0; i < mNumSurfaces; i++) { 1463 if (mSurfaceBuffers[i].renderBuffer.graphicBufferHandle == graphichandler) { 1464 mSurfaceBuffers[i].renderBuffer.renderDone = true; 1465 VTRACE("SignalRenderDoneFlag mInitialized = true index = %d", i); 1466 break; 1467 } 1468 } 1469 } 1470 1471 if (mStoreMetaData) { 1472 if ((mMetaDataBuffersNum < mConfigBuffer.surfaceNumber) && isNew) { 1473 mMetaDataBuffersNum++; 1474 } 1475 } 1476 1477 pthread_mutex_unlock(&mLock); 1478 1479 return DECODE_SUCCESS; 1480 1481 } 1482 querySurfaceRenderStatus(VideoSurfaceBuffer * surface)1483 void VideoDecoderBase::querySurfaceRenderStatus(VideoSurfaceBuffer* surface) { 1484 VASurfaceStatus surfStat = VASurfaceReady; 1485 VAStatus vaStat = VA_STATUS_SUCCESS; 1486 1487 if (!surface) { 1488 LOGW("SurfaceBuffer not ready yet"); 1489 return; 1490 } 1491 surface->renderBuffer.driverRenderDone = true; 1492 1493 #ifndef USE_GEN_HW 1494 if (surface->renderBuffer.surface != VA_INVALID_SURFACE && 1495 (mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER)) { 1496 1497 vaStat = vaQuerySurfaceStatus(mVADisplay, surface->renderBuffer.surface, &surfStat); 1498 1499 if ((vaStat == VA_STATUS_SUCCESS) && (surfStat != VASurfaceReady)) 1500 surface->renderBuffer.driverRenderDone = false; 1501 1502 } 1503 #endif 1504 1505 } 1506 1507 // This function should be called before start() to load different type of parsers 1508 #if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING) setParserType(_vbp_parser_type type)1509 Decode_Status VideoDecoderBase::setParserType(_vbp_parser_type type) { 1510 if ((int32_t)type != VBP_INVALID) { 1511 ITRACE("Parser Type = %d", (int32_t)type); 1512 mParserType = type; 1513 return DECODE_SUCCESS; 1514 } else { 1515 ETRACE("Invalid parser type = %d", (int32_t)type); 1516 return DECODE_NO_PARSER; 1517 } 1518 } 1519 updateBuffer(uint8_t * buffer,int32_t size,void ** vbpData)1520 Decode_Status VideoDecoderBase::updateBuffer(uint8_t *buffer, int32_t size, void** vbpData) { 1521 if (mParserHandle == NULL) { 1522 return DECODE_NO_PARSER; 1523 } 1524 1525 uint32_t vbpStatus; 1526 if (buffer == NULL || size <= 0) { 1527 return DECODE_INVALID_DATA; 1528 } 1529 1530 vbpStatus = mParserUpdate(mParserHandle, buffer, size, vbpData); 1531 CHECK_VBP_STATUS("vbp_update"); 1532 1533 return DECODE_SUCCESS; 1534 } 1535 queryBuffer(void ** vbpData)1536 Decode_Status VideoDecoderBase::queryBuffer(void** vbpData) { 1537 if (mParserHandle == NULL) { 1538 return DECODE_NO_PARSER; 1539 } 1540 1541 uint32_t vbpStatus; 1542 vbpStatus = mParserQuery(mParserHandle, vbpData); 1543 CHECK_VBP_STATUS("vbp_query"); 1544 1545 return DECODE_SUCCESS; 1546 } 1547 getCodecSpecificConfigs(VAProfile profile,VAConfigID * config)1548 Decode_Status VideoDecoderBase::getCodecSpecificConfigs(VAProfile profile, VAConfigID *config) { 1549 VAStatus vaStatus; 1550 VAConfigAttrib attrib; 1551 attrib.type = VAConfigAttribRTFormat; 1552 attrib.value = VA_RT_FORMAT_YUV420; 1553 1554 if (config == NULL) { 1555 ETRACE("Invalid parameter!"); 1556 return DECODE_FAIL; 1557 } 1558 1559 vaStatus = vaCreateConfig( 1560 mVADisplay, 1561 profile, 1562 VAEntrypointVLD, 1563 &attrib, 1564 1, 1565 config); 1566 1567 CHECK_VA_STATUS("vaCreateConfig"); 1568 1569 return DECODE_SUCCESS; 1570 } 1571 #endif checkHardwareCapability()1572 Decode_Status VideoDecoderBase::checkHardwareCapability() { 1573 return DECODE_SUCCESS; 1574 } 1575 drainDecodingErrors(VideoErrorBuffer * outErrBuf,VideoRenderBuffer * currentSurface)1576 void VideoDecoderBase::drainDecodingErrors(VideoErrorBuffer *outErrBuf, VideoRenderBuffer *currentSurface) { 1577 if (mErrReportEnabled && outErrBuf && currentSurface) { 1578 memcpy(outErrBuf, &(currentSurface->errBuf), sizeof(VideoErrorBuffer)); 1579 1580 currentSurface->errBuf.errorNumber = 0; 1581 currentSurface->errBuf.timeStamp = INVALID_PTS; 1582 } 1583 if (outErrBuf) 1584 VTRACE("%s: error number is %d", __FUNCTION__, outErrBuf->errorNumber); 1585 } 1586 fillDecodingErrors(VideoRenderBuffer * currentSurface)1587 void VideoDecoderBase::fillDecodingErrors(VideoRenderBuffer *currentSurface) { 1588 VAStatus ret; 1589 1590 if (mErrReportEnabled) { 1591 currentSurface->errBuf.timeStamp = currentSurface->timeStamp; 1592 // TODO: is 10 a suitable number? 1593 VASurfaceDecodeMBErrors *err_drv_output = NULL; 1594 ret = vaQuerySurfaceError(mVADisplay, currentSurface->surface, VA_STATUS_ERROR_DECODING_ERROR, (void **)&err_drv_output); 1595 if (ret || !err_drv_output) { 1596 WTRACE("vaQuerySurfaceError failed."); 1597 return; 1598 } 1599 1600 int offset = 0x1 & currentSurface->errBuf.errorNumber;// offset is either 0 or 1 1601 for (int i = 0; i < MAX_ERR_NUM - offset; i++) { 1602 if (err_drv_output[i].status != -1) { 1603 currentSurface->errBuf.errorNumber++; 1604 currentSurface->errBuf.errorArray[i + offset].type = DecodeMBError; 1605 currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.start_mb = err_drv_output[i].start_mb; 1606 currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.end_mb = err_drv_output[i].end_mb; 1607 currentSurface->errBuf.errorArray[i + offset].num_mbs = err_drv_output[i].end_mb - err_drv_output[i].start_mb + 1; 1608 ITRACE("Error Index[%d]: type = %d, start_mb = %d, end_mb = %d", 1609 currentSurface->errBuf.errorNumber - 1, 1610 currentSurface->errBuf.errorArray[i + offset].type, 1611 currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.start_mb, 1612 currentSurface->errBuf.errorArray[i + offset].error_data.mb_pos.end_mb); 1613 } else break; 1614 } 1615 ITRACE("%s: error number of current surface is %d, timestamp @%llu", 1616 __FUNCTION__, currentSurface->errBuf.errorNumber, currentSurface->timeStamp); 1617 } 1618 } 1619 setRotationDegrees(int32_t rotationDegrees)1620 void VideoDecoderBase::setRotationDegrees(int32_t rotationDegrees) { 1621 if (mRotationDegrees == rotationDegrees) { 1622 return; 1623 } 1624 1625 ITRACE("set new rotation degree: %d", rotationDegrees); 1626 VADisplayAttribute rotate; 1627 rotate.type = VADisplayAttribRotation; 1628 rotate.value = VA_ROTATION_NONE; 1629 if (rotationDegrees == 0) 1630 rotate.value = VA_ROTATION_NONE; 1631 else if (rotationDegrees == 90) 1632 rotate.value = VA_ROTATION_90; 1633 else if (rotationDegrees == 180) 1634 rotate.value = VA_ROTATION_180; 1635 else if (rotationDegrees == 270) 1636 rotate.value = VA_ROTATION_270; 1637 1638 VAStatus ret = vaSetDisplayAttributes(mVADisplay, &rotate, 1); 1639 if (ret) { 1640 ETRACE("Failed to set rotation degree."); 1641 } 1642 mRotationDegrees = rotationDegrees; 1643 } 1644 setRenderRect()1645 void VideoDecoderBase::setRenderRect() { 1646 1647 if (!mVADisplay) 1648 return; 1649 1650 VAStatus ret; 1651 VARectangle rect; 1652 rect.x = mVideoFormatInfo.cropLeft; 1653 rect.y = mVideoFormatInfo.cropTop; 1654 rect.width = mVideoFormatInfo.width - (mVideoFormatInfo.cropLeft + mVideoFormatInfo.cropRight); 1655 rect.height = mVideoFormatInfo.height - (mVideoFormatInfo.cropBottom + mVideoFormatInfo.cropTop); 1656 if (strcasecmp(mVideoFormatInfo.mimeType,"video/avc") == 0 || 1657 strcasecmp(mVideoFormatInfo.mimeType,"video/avc-secure") == 0 || 1658 strcasecmp(mVideoFormatInfo.mimeType,"video/h264") == 0) { 1659 rect.height = mVideoFormatInfo.height; 1660 rect.width = mVideoFormatInfo.width; 1661 } 1662 1663 VADisplayAttribute render_rect; 1664 render_rect.type = VADisplayAttribRenderRect; 1665 render_rect.attrib_ptr = ▭ 1666 1667 ret = vaSetDisplayAttributes(mVADisplay, &render_rect, 1); 1668 if (ret) { 1669 ETRACE("Failed to set rotation degree."); 1670 } 1671 } 1672 setColorSpaceInfo(int32_t colorMatrix,int32_t videoRange)1673 void VideoDecoderBase::setColorSpaceInfo(int32_t colorMatrix, int32_t videoRange) { 1674 ITRACE("set colorMatrix: 0x%x ", colorMatrix); 1675 VADisplayAttribute cm; 1676 cm.type = VADisplayAttribCSCMatrix; 1677 if (colorMatrix == VA_SRC_BT601) { 1678 cm.attrib_ptr = &s601; 1679 } else if (colorMatrix == VA_SRC_BT709) { 1680 cm.attrib_ptr = &s709; 1681 } else { 1682 // if we can't get the color matrix or it's not BT601 or BT709 1683 // we decide the color matrix according to clip resolution 1684 if (mVideoFormatInfo.width < 1280 && mVideoFormatInfo.height < 720) 1685 cm.attrib_ptr = &s601; 1686 else 1687 cm.attrib_ptr = &s709; 1688 } 1689 1690 VAStatus ret = vaSetDisplayAttributes(mVADisplay, &cm, 1); 1691 1692 if (ret) { 1693 ETRACE("Failed to set colorMatrix."); 1694 } 1695 1696 // 1: full range, 0: reduced range 1697 ITRACE("set videoRange: %d ", videoRange); 1698 VADisplayAttribute vr; 1699 vr.type = VADisplayAttribColorRange; 1700 vr.value = (videoRange == 1) ? VA_SOURCE_RANGE_FULL : VA_SOURCE_RANGE_REDUCED; 1701 1702 ret = vaSetDisplayAttributes(mVADisplay, &vr, 1); 1703 1704 if (ret) { 1705 ETRACE("Failed to set videoRange."); 1706 } 1707 } 1708