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