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