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 "VideoDecoderWMV.h" 18 #include "VideoDecoderTrace.h" 19 #include <string.h> 20 21 VideoDecoderWMV::VideoDecoderWMV(const char *mimeType) 22 : VideoDecoderBase(mimeType, VBP_VC1), 23 mBufferIDs(NULL), 24 mNumBufferIDs(0), 25 mConfigDataParsed(false), 26 mRangeMapped(false), 27 mDeblockedCurrPicIndex(0), 28 mDeblockedLastPicIndex(1), 29 mDeblockedForwardPicIndex(2) { 30 } 31 32 33 VideoDecoderWMV::~VideoDecoderWMV() { 34 stop(); 35 } 36 37 Decode_Status VideoDecoderWMV::start(VideoConfigBuffer *buffer) { 38 Decode_Status status; 39 40 status = VideoDecoderBase::start(buffer); 41 CHECK_STATUS("VideoDecoderBase::start"); 42 43 if (buffer->data == NULL || buffer->size == 0) { 44 WTRACE("No config data to start VA."); 45 return DECODE_SUCCESS; 46 } 47 48 vbp_data_vc1 *data = NULL; 49 status = parseBuffer(buffer->data, buffer->size, &data); 50 CHECK_STATUS("parseBuffer"); 51 52 status = startVA(data); 53 return status; 54 } 55 56 void VideoDecoderWMV::stop(void) { 57 if (mBufferIDs) { 58 delete [] mBufferIDs; 59 mBufferIDs = NULL; 60 } 61 mNumBufferIDs = 0; 62 mConfigDataParsed = false; 63 mRangeMapped = false; 64 65 mDeblockedCurrPicIndex = 0; 66 mDeblockedLastPicIndex = 1; 67 mDeblockedForwardPicIndex = 2; 68 69 VideoDecoderBase::stop(); 70 } 71 72 void VideoDecoderWMV::flush(void) { 73 VideoDecoderBase::flush(); 74 75 mRangeMapped = false; 76 mDeblockedCurrPicIndex = 0; 77 mDeblockedLastPicIndex = 1; 78 mDeblockedForwardPicIndex = 2; 79 } 80 81 Decode_Status VideoDecoderWMV::decode(VideoDecodeBuffer *buffer) { 82 Decode_Status status; 83 vbp_data_vc1 *data = NULL; 84 bool useGraphicbuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER; 85 if (buffer == NULL) { 86 return DECODE_INVALID_DATA; 87 } 88 89 status = parseBuffer(buffer->data, buffer->size, &data); 90 CHECK_STATUS("parseBuffer"); 91 92 if (!mVAStarted) { 93 status = startVA(data); 94 CHECK_STATUS("startVA"); 95 } 96 97 if (mSizeChanged && !useGraphicbuffer) { 98 mSizeChanged = false; 99 return DECODE_FORMAT_CHANGE; 100 } 101 102 if ((mVideoFormatInfo.width != data->se_data->CODED_WIDTH || 103 mVideoFormatInfo.height != data->se_data->CODED_HEIGHT) && 104 data->se_data->CODED_WIDTH && 105 data->se_data->CODED_HEIGHT) { 106 ITRACE("video size is changed from %dx%d to %dx%d", mVideoFormatInfo.width, mVideoFormatInfo.height, 107 data->se_data->CODED_WIDTH, data->se_data->CODED_HEIGHT); 108 if (useGraphicbuffer && mStoreMetaData) { 109 pthread_mutex_lock(&mFormatLock); 110 } 111 mVideoFormatInfo.width = data->se_data->CODED_WIDTH; 112 mVideoFormatInfo.height = data->se_data->CODED_HEIGHT; 113 bool needFlush = false; 114 if (useGraphicbuffer) { 115 if (mStoreMetaData) { 116 needFlush = true; 117 118 mVideoFormatInfo.valid = false; 119 pthread_mutex_unlock(&mFormatLock); 120 } else { 121 needFlush = (mVideoFormatInfo.width > mVideoFormatInfo.surfaceWidth) 122 || (mVideoFormatInfo.height > mVideoFormatInfo.surfaceHeight); 123 } 124 } 125 126 setRenderRect(); 127 128 if (needFlush) { 129 if (mStoreMetaData) { 130 status = endDecodingFrame(false); 131 CHECK_STATUS("endDecodingFrame"); 132 } else { 133 flushSurfaceBuffers(); 134 } 135 mSizeChanged = false; 136 return DECODE_FORMAT_CHANGE; 137 } else { 138 mSizeChanged = true; 139 } 140 } else { 141 if (useGraphicbuffer && mStoreMetaData) { 142 mVideoFormatInfo.valid = true; 143 } 144 } 145 146 status = decodeFrame(buffer, data); 147 CHECK_STATUS("decodeFrame"); 148 return status; 149 } 150 151 Decode_Status VideoDecoderWMV::decodeFrame(VideoDecodeBuffer* buffer, vbp_data_vc1 *data) { 152 Decode_Status status; 153 mCurrentPTS = buffer->timeStamp; 154 if (0 == data->num_pictures || NULL == data->pic_data) { 155 WTRACE("Number of pictures is 0, buffer contains configuration data only?"); 156 return DECODE_SUCCESS; 157 } 158 159 if (data->pic_data[0].picture_is_skipped == VC1_PTYPE_SKIPPED) { 160 161 // Do nothing for skip frame as the last frame will be rendered agian by natively 162 // No needs to handle reference frame neither 163 return DECODE_SUCCESS; 164 #if 0 165 //use the last P or I frame surface for skipped frame and treat it as P frame 166 if (mLastReference == NULL) { 167 // TODO: handle this case 168 WTRACE("The last reference is unavailable to construct skipped frame."); 169 return DECODE_SUCCESS; 170 } 171 172 status = acquireSurfaceBuffer(); 173 CHECK_STATUS("acquireSurfaceBuffer"); 174 mAcquiredBuffer->renderBuffer.timeStamp = mCurrentPTS; 175 mAcquiredBuffer->renderBuffer.flag = 0; 176 mAcquiredBuffer->renderBuffer.scanFormat = mLastReference->renderBuffer.scanFormat; 177 mAcquiredBuffer->renderBuffer.surface = mLastReference->renderBuffer.surface; 178 // No need to update mappedData for HW decoding 179 //mAcquiredBuffer->mappedData.data = mLastReference->mappedData.data; 180 mAcquiredBuffer->referenceFrame = true; 181 // let outputSurfaceBuffer handle "asReference" for VC1 182 status = outputSurfaceBuffer(); 183 return status; 184 #endif 185 } 186 187 status = acquireSurfaceBuffer(); 188 CHECK_STATUS("acquireSurfaceBuffer"); 189 190 mAcquiredBuffer->renderBuffer.timeStamp = buffer->timeStamp; 191 if (buffer->flag & HAS_DISCONTINUITY) { 192 mAcquiredBuffer->renderBuffer.flag |= HAS_DISCONTINUITY; 193 } 194 if (buffer->flag & WANT_DECODE_ONLY) { 195 mAcquiredBuffer->renderBuffer.flag |= WANT_DECODE_ONLY; 196 } 197 if (mSizeChanged) { 198 mSizeChanged = false; 199 mAcquiredBuffer->renderBuffer.flag |= IS_RESOLUTION_CHANGE; 200 } 201 202 if (data->num_pictures > 1) { 203 if (data->pic_data[0].pic_parms->picture_fields.bits.is_first_field) { 204 mAcquiredBuffer->renderBuffer.scanFormat = VA_TOP_FIELD; 205 } else { 206 mAcquiredBuffer->renderBuffer.scanFormat = VA_BOTTOM_FIELD; 207 } 208 } else { 209 mAcquiredBuffer->renderBuffer.scanFormat = VA_FRAME_PICTURE; 210 } 211 212 mRangeMapped = (data->se_data->RANGE_MAPY_FLAG || data->se_data->RANGE_MAPUV_FLAG || data->se_data->RANGERED); 213 214 int frameType = data->pic_data[0].pic_parms->picture_fields.bits.picture_type; 215 mAcquiredBuffer->referenceFrame = (frameType == VC1_PTYPE_I || frameType == VC1_PTYPE_P); 216 217 // TODO: handle multiple frames parsed from a sample buffer 218 int numPictures = (data->num_pictures > 1) ? 2 : 1; 219 220 for (int index = 0; index < numPictures; index++) { 221 status = decodePicture(data, index); 222 if (status != DECODE_SUCCESS) { 223 endDecodingFrame(true); 224 return status; 225 } 226 } 227 228 if (mRangeMapped) { 229 updateDeblockedPicIndexes(frameType); 230 } 231 232 // let outputSurfaceBuffer handle "asReference" for VC1 233 status = outputSurfaceBuffer(); 234 return status; 235 } 236 237 238 Decode_Status VideoDecoderWMV::decodePicture(vbp_data_vc1 *data, int32_t picIndex) { 239 VAStatus vaStatus = VA_STATUS_SUCCESS; 240 Decode_Status status; 241 int32_t bufferIDCount = 0; 242 vbp_picture_data_vc1 *picData = &(data->pic_data[picIndex]); 243 VAPictureParameterBufferVC1 *picParams = picData->pic_parms; 244 245 if (picParams == NULL) { 246 return DECODE_PARSER_FAIL; 247 } 248 249 status = allocateVABufferIDs(picData->num_slices * 2 + 2); 250 CHECK_STATUS("allocateVABufferIDs"); 251 252 status = setReference(picParams, picIndex, mAcquiredBuffer->renderBuffer.surface); 253 CHECK_STATUS("setReference"); 254 255 if (mRangeMapped) { 256 // keep the destination surface for the picture after decoding and in-loop filtering 257 picParams->inloop_decoded_picture = mExtraSurfaces[mDeblockedCurrPicIndex]; 258 } else { 259 picParams->inloop_decoded_picture = VA_INVALID_SURFACE; 260 } 261 262 vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface); 263 CHECK_VA_STATUS("vaBeginPicture"); 264 // setting mDecodingFrame to true so vaEndPicture will be invoked to end the picture decoding. 265 mDecodingFrame = true; 266 267 vaStatus = vaCreateBuffer( 268 mVADisplay, 269 mVAContext, 270 VAPictureParameterBufferType, 271 sizeof(VAPictureParameterBufferVC1), 272 1, 273 picParams, 274 &mBufferIDs[bufferIDCount]); 275 CHECK_VA_STATUS("vaCreatePictureParameterBuffer"); 276 bufferIDCount++; 277 278 if (picParams->bitplane_present.value) { 279 vaStatus = vaCreateBuffer( 280 mVADisplay, 281 mVAContext, 282 VABitPlaneBufferType, 283 picData->size_bitplanes, 284 1, 285 picData->packed_bitplanes, 286 &mBufferIDs[bufferIDCount]); 287 CHECK_VA_STATUS("vaCreateBitPlaneBuffer"); 288 bufferIDCount++; 289 } 290 291 for (uint32_t i = 0; i < picData->num_slices; i++) { 292 vaStatus = vaCreateBuffer( 293 mVADisplay, 294 mVAContext, 295 VASliceParameterBufferType, 296 sizeof(VASliceParameterBufferVC1), 297 1, 298 &(picData->slc_data[i].slc_parms), 299 &mBufferIDs[bufferIDCount]); 300 CHECK_VA_STATUS("vaCreateSliceParameterBuffer"); 301 bufferIDCount++; 302 303 vaStatus = vaCreateBuffer( 304 mVADisplay, 305 mVAContext, 306 VASliceDataBufferType, 307 //size 308 picData->slc_data[i].slice_size, 309 //num_elements 310 1, 311 //slice data buffer pointer 312 //Note that this is the original data buffer ptr; 313 // offset to the actual slice data is provided in 314 // slice_data_offset in VASliceParameterBufferVC1 315 picData->slc_data[i].buffer_addr + picData->slc_data[i].slice_offset, 316 &mBufferIDs[bufferIDCount]); 317 CHECK_VA_STATUS("vaCreateSliceDataBuffer"); 318 bufferIDCount++; 319 } 320 321 vaStatus = vaRenderPicture( 322 mVADisplay, 323 mVAContext, 324 mBufferIDs, 325 bufferIDCount); 326 CHECK_VA_STATUS("vaRenderPicture"); 327 328 vaStatus = vaEndPicture(mVADisplay, mVAContext); 329 mDecodingFrame = false; 330 CHECK_VA_STATUS("vaRenderPicture"); 331 332 return DECODE_SUCCESS; 333 } 334 335 336 Decode_Status VideoDecoderWMV::setReference( 337 VAPictureParameterBufferVC1 *params, 338 int32_t picIndex, 339 VASurfaceID current) { 340 int frameType = params->picture_fields.bits.picture_type; 341 switch (frameType) { 342 case VC1_PTYPE_I: 343 params->forward_reference_picture = current; 344 params->backward_reference_picture = current; 345 break; 346 case VC1_PTYPE_P: 347 // check REFDIST in the picture parameter buffer 348 if (0 != params->reference_fields.bits.reference_distance_flag && 349 0 != params->reference_fields.bits.reference_distance) { 350 /* The previous decoded frame (distance is up to 16 but not 0) is used 351 for reference. Not supported here. 352 */ 353 return DECODE_NO_REFERENCE; 354 } 355 if (1 == picIndex) { 356 // handle interlace field coding case 357 if (1 == params->reference_fields.bits.num_reference_pictures || 358 1 == params->reference_fields.bits.reference_field_pic_indicator) { 359 /* 360 two reference fields or the second closest I/P field is used for 361 prediction. Set forward reference picture to INVALID so it will be 362 updated to a valid previous reconstructed reference frame later. 363 */ 364 params->forward_reference_picture = VA_INVALID_SURFACE; 365 } else { 366 /* the closest I/P is used for reference so it must be the 367 complementary field in the same surface. 368 */ 369 params->forward_reference_picture = current; 370 } 371 } 372 if (VA_INVALID_SURFACE == params->forward_reference_picture) { 373 if (mLastReference == NULL) { 374 return DECODE_NO_REFERENCE; 375 } 376 params->forward_reference_picture = mLastReference->renderBuffer.surface; 377 } 378 params->backward_reference_picture = VA_INVALID_SURFACE; 379 break; 380 case VC1_PTYPE_B: 381 if (mForwardReference == NULL || mLastReference == NULL) { 382 return DECODE_NO_REFERENCE; 383 } 384 params->forward_reference_picture = mForwardReference->renderBuffer.surface; 385 params->backward_reference_picture = mLastReference->renderBuffer.surface; 386 break; 387 case VC1_PTYPE_BI: 388 params->forward_reference_picture = VA_INVALID_SURFACE; 389 params->backward_reference_picture = VA_INVALID_SURFACE; 390 break; 391 case VC1_PTYPE_SKIPPED: 392 //Will never happen here 393 break; 394 default: 395 break; 396 } 397 return DECODE_SUCCESS; 398 } 399 400 void VideoDecoderWMV::updateDeblockedPicIndexes(int frameType) { 401 int32_t curPicIndex = mDeblockedCurrPicIndex; 402 403 /* Out Loop (range map) buffers */ 404 if (frameType != VC1_PTYPE_SKIPPED) { 405 if ((frameType == VC1_PTYPE_I) || (frameType == VC1_PTYPE_P)) { 406 mDeblockedCurrPicIndex = mDeblockedLastPicIndex; 407 mDeblockedLastPicIndex = curPicIndex; 408 } else { 409 mDeblockedCurrPicIndex = mDeblockedForwardPicIndex; 410 mDeblockedForwardPicIndex = curPicIndex; 411 } 412 } 413 } 414 415 Decode_Status VideoDecoderWMV::updateConfigData( 416 uint8_t *configData, 417 int32_t configDataLen, 418 uint8_t **newConfigData, 419 int32_t* newConfigDataLen) { 420 int32_t i = 0; 421 uint8_t *p = configData; 422 423 /* Check for start codes. If one exist, then this is VC-1 and not WMV. */ 424 while (i < configDataLen - 2) { 425 if ((p[i] == 0) && 426 (p[i + 1] == 0) && 427 (p[i + 2] == 1)) { 428 *newConfigData = NULL; 429 *newConfigDataLen = 0; 430 return DECODE_SUCCESS; 431 } 432 i++; 433 } 434 435 *newConfigDataLen = configDataLen + 9; 436 p = *newConfigData = new uint8_t [*newConfigDataLen]; 437 if (!p) { 438 return DECODE_MEMORY_FAIL; 439 } 440 441 /* If we get here we have 4+ bytes of codec data that must be formatted */ 442 /* to pass through as an RCV sequence header. */ 443 p[0] = 0; 444 p[1] = 0; 445 p[2] = 1; 446 p[3] = 0x0f; /* Start code. */ 447 p[4] = (mVideoFormatInfo.width >> 8) & 0x0ff; 448 p[5] = mVideoFormatInfo.width & 0x0ff; 449 p[6] = (mVideoFormatInfo.height >> 8) & 0x0ff; 450 p[7] = mVideoFormatInfo.height & 0x0ff; 451 452 memcpy(p + 8, configData, configDataLen); 453 *(p + configDataLen + 8) = 0x80; 454 455 return DECODE_SUCCESS; 456 } 457 458 Decode_Status VideoDecoderWMV::startVA(vbp_data_vc1 *data) { 459 updateFormatInfo(data); 460 461 VAProfile vaProfile; 462 switch (data->se_data->PROFILE) { 463 case 0: 464 vaProfile = VAProfileVC1Simple; 465 break; 466 case 1: 467 vaProfile = VAProfileVC1Main; 468 break; 469 default: 470 vaProfile = VAProfileVC1Advanced; 471 break; 472 } 473 474 return VideoDecoderBase::setupVA(VC1_SURFACE_NUMBER, vaProfile, VC1_EXTRA_SURFACE_NUMBER); 475 } 476 477 void VideoDecoderWMV::updateFormatInfo(vbp_data_vc1 *data) { 478 ITRACE("updateFormatInfo: current size: %d x %d, new size: %d x %d", 479 mVideoFormatInfo.width, mVideoFormatInfo.height, 480 data->se_data->CODED_WIDTH, data->se_data->CODED_HEIGHT); 481 482 mVideoFormatInfo.cropBottom = data->se_data->CODED_HEIGHT > mVideoFormatInfo.height ? 483 data->se_data->CODED_HEIGHT - mVideoFormatInfo.height : 0; 484 mVideoFormatInfo.cropRight = data->se_data->CODED_WIDTH > mVideoFormatInfo.width ? 485 data->se_data->CODED_WIDTH - mVideoFormatInfo.width : 0; 486 487 if ((mVideoFormatInfo.width != data->se_data->CODED_WIDTH || 488 mVideoFormatInfo.height != data->se_data->CODED_HEIGHT) && 489 data->se_data->CODED_WIDTH && 490 data->se_data->CODED_HEIGHT) { 491 // encoded image size 492 mVideoFormatInfo.width = data->se_data->CODED_WIDTH; 493 mVideoFormatInfo.height = data->se_data->CODED_HEIGHT; 494 mSizeChanged = true; 495 ITRACE("Video size is changed."); 496 } 497 498 // video_range has default value of 0. Y ranges from 16 to 235. 499 mVideoFormatInfo.videoRange = 0; 500 501 switch (data->se_data->MATRIX_COEF) { 502 case 1: 503 mVideoFormatInfo.colorMatrix = VA_SRC_BT709; 504 break; 505 // ITU-R BT.1700, ITU-R BT.601-5, and SMPTE 293M-1996. 506 case 6: 507 mVideoFormatInfo.colorMatrix = VA_SRC_BT601; 508 break; 509 default: 510 // unknown color matrix, set to 0 so color space flag will not be set. 511 mVideoFormatInfo.colorMatrix = 0; 512 break; 513 } 514 515 mVideoFormatInfo.aspectX = data->se_data->ASPECT_HORIZ_SIZE; 516 mVideoFormatInfo.aspectY = data->se_data->ASPECT_VERT_SIZE; 517 mVideoFormatInfo.bitrate = 0; //data->se_data->bitrate; 518 mVideoFormatInfo.valid = true; 519 520 setRenderRect(); 521 setColorSpaceInfo(mVideoFormatInfo.colorMatrix, mVideoFormatInfo.videoRange); 522 } 523 524 Decode_Status VideoDecoderWMV::allocateVABufferIDs(int32_t number) { 525 if (mNumBufferIDs > number) { 526 return DECODE_SUCCESS; 527 } 528 if (mBufferIDs) { 529 delete [] mBufferIDs; 530 } 531 mBufferIDs = NULL; 532 mNumBufferIDs = 0; 533 mBufferIDs = new VABufferID [number]; 534 if (mBufferIDs == NULL) { 535 return DECODE_MEMORY_FAIL; 536 } 537 mNumBufferIDs = number; 538 return DECODE_SUCCESS; 539 } 540 541 Decode_Status VideoDecoderWMV::parseBuffer(uint8_t *data, int32_t size, vbp_data_vc1 **vbpData) { 542 Decode_Status status; 543 544 if (data == NULL || size == 0) { 545 return DECODE_INVALID_DATA; 546 } 547 548 if (mConfigDataParsed) { 549 status = VideoDecoderBase::parseBuffer(data, size, false, (void**)vbpData); 550 CHECK_STATUS("VideoDecoderBase::parseBuffer"); 551 } else { 552 uint8_t *newData = NULL; 553 int32_t newSize = 0; 554 status = updateConfigData(data, size, &newData, &newSize); 555 CHECK_STATUS("updateConfigData"); 556 557 if (newSize) { 558 status = VideoDecoderBase::parseBuffer(newData, newSize, true, (void**)vbpData); 559 delete [] newData; 560 } else { 561 status = VideoDecoderBase::parseBuffer(data, size, true, (void**)vbpData); 562 } 563 CHECK_STATUS("VideoDecoderBase::parseBuffer"); 564 mConfigDataParsed = true; 565 } 566 return DECODE_SUCCESS; 567 } 568 569 570 Decode_Status VideoDecoderWMV::checkHardwareCapability() { 571 #ifndef USE_GEN_HW 572 VAStatus vaStatus; 573 VAConfigAttrib cfgAttribs[2]; 574 cfgAttribs[0].type = VAConfigAttribMaxPictureWidth; 575 cfgAttribs[1].type = VAConfigAttribMaxPictureHeight; 576 vaStatus = vaGetConfigAttributes(mVADisplay, VAProfileVC1Advanced, 577 VAEntrypointVLD, cfgAttribs, 2); 578 CHECK_VA_STATUS("vaGetConfigAttributes"); 579 if (cfgAttribs[0].value * cfgAttribs[1].value < (uint32_t)mVideoFormatInfo.width * (uint32_t)mVideoFormatInfo.height) { 580 ETRACE("hardware supports resolution %d * %d smaller than the clip resolution %d * %d", 581 cfgAttribs[0].value, cfgAttribs[1].value, mVideoFormatInfo.width, mVideoFormatInfo.height); 582 return DECODE_DRIVER_FAIL; 583 } 584 #endif 585 return DECODE_SUCCESS; 586 } 587 588 589