1 /* 2 * Copyright (C) 2011 The Android Open Source Project 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 ************************************************************************* 18 * @file VideoEditorVideoDecoder.cpp 19 * @brief StageFright shell video decoder 20 ************************************************************************* 21 */ 22 #define LOG_NDEBUG 1 23 #define LOG_TAG "VIDEOEDITOR_VIDEODECODER" 24 /******************* 25 * HEADERS * 26 *******************/ 27 28 #include "VideoEditorVideoDecoder_internal.h" 29 #include "VideoEditorUtils.h" 30 #include "M4VD_Tools.h" 31 32 #include <media/stagefright/MetaData.h> 33 #include <media/stagefright/MediaDefs.h> 34 #include <media/stagefright/MediaDebug.h> 35 /******************** 36 * DEFINITIONS * 37 ********************/ 38 #define MAX_DEC_BUFFERS 10 39 40 /******************** 41 * SOURCE CLASS * 42 ********************/ 43 using namespace android; 44 static M4OSA_ERR copyBufferToQueue( 45 VideoEditorVideoDecoder_Context* pDecShellContext, 46 MediaBuffer* pDecodedBuffer); 47 48 class VideoEditorVideoDecoderSource : public MediaSource { 49 public: 50 51 VideoEditorVideoDecoderSource( 52 const sp<MetaData> &format, 53 VIDEOEDITOR_CodecType codecType, 54 void *decoderShellContext); 55 56 virtual status_t start(MetaData *params = NULL); 57 virtual status_t stop(); 58 virtual sp<MetaData> getFormat(); 59 virtual status_t read( 60 MediaBuffer **buffer, const ReadOptions *options = NULL); 61 62 protected : 63 virtual ~VideoEditorVideoDecoderSource(); 64 65 private: 66 sp<MetaData> mFormat; 67 MediaBuffer* mBuffer; 68 MediaBufferGroup* mGroup; 69 Mutex mLock; 70 VideoEditorVideoDecoder_Context* mpDecShellContext; 71 int32_t mMaxAUSize; 72 bool mStarted; 73 VIDEOEDITOR_CodecType mCodecType; 74 75 // Don't call me 76 VideoEditorVideoDecoderSource(const VideoEditorVideoDecoderSource &); 77 VideoEditorVideoDecoderSource &operator=( 78 const VideoEditorVideoDecoderSource &); 79 }; 80 81 VideoEditorVideoDecoderSource::VideoEditorVideoDecoderSource( 82 const sp<MetaData> &format, VIDEOEDITOR_CodecType codecType, 83 void *decoderShellContext) : 84 mFormat(format), 85 mBuffer(NULL), 86 mGroup(NULL), 87 mStarted(false), 88 mCodecType(codecType) { 89 mpDecShellContext = (VideoEditorVideoDecoder_Context*) decoderShellContext; 90 } 91 92 VideoEditorVideoDecoderSource::~VideoEditorVideoDecoderSource() { 93 if (mStarted == true) { 94 stop(); 95 } 96 } 97 98 status_t VideoEditorVideoDecoderSource::start( 99 MetaData *params) { 100 101 if (!mStarted) { 102 if (mFormat->findInt32(kKeyMaxInputSize, &mMaxAUSize) == false) { 103 LOGE("Could not find kKeyMaxInputSize"); 104 return ERROR_MALFORMED; 105 } 106 107 mGroup = new MediaBufferGroup; 108 if (mGroup == NULL) { 109 LOGE("FATAL: memory limitation ! "); 110 return NO_MEMORY; 111 } 112 113 mGroup->add_buffer(new MediaBuffer(mMaxAUSize)); 114 115 mStarted = true; 116 } 117 return OK; 118 } 119 120 status_t VideoEditorVideoDecoderSource::stop() { 121 if (mStarted) { 122 if (mBuffer != NULL) { 123 124 // FIXME: 125 // Why do we need to check on the ref count? 126 int ref_count = mBuffer->refcount(); 127 LOGV("MediaBuffer refcount is %d",ref_count); 128 for (int i = 0; i < ref_count; ++i) { 129 mBuffer->release(); 130 } 131 132 mBuffer = NULL; 133 } 134 delete mGroup; 135 mGroup = NULL; 136 mStarted = false; 137 } 138 return OK; 139 } 140 141 sp<MetaData> VideoEditorVideoDecoderSource::getFormat() { 142 Mutex::Autolock autolock(mLock); 143 144 return mFormat; 145 } 146 147 status_t VideoEditorVideoDecoderSource::read(MediaBuffer** buffer_out, 148 const ReadOptions *options) { 149 150 Mutex::Autolock autolock(mLock); 151 if (options != NULL) { 152 int64_t time_us; 153 MediaSource::ReadOptions::SeekMode mode; 154 options->getSeekTo(&time_us, &mode); 155 if (mode != MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC) { 156 LOGE("Unexpected read options"); 157 return BAD_VALUE; 158 } 159 160 M4OSA_ERR err; 161 M4OSA_Int32 rapTime = time_us / 1000; 162 163 /*--- Retrieve the previous RAP time ---*/ 164 err = mpDecShellContext->m_pReaderGlobal->m_pFctGetPrevRapTime( 165 mpDecShellContext->m_pReader->m_readerContext, 166 (M4_StreamHandler*)mpDecShellContext->m_pVideoStreamhandler, 167 &rapTime); 168 169 if (err == M4WAR_READER_INFORMATION_NOT_PRESENT) { 170 /* No RAP table, jump backward and predecode */ 171 rapTime -= 40000; 172 if(rapTime < 0) rapTime = 0; 173 } else if (err != OK) { 174 LOGE("get rap time error = 0x%x\n", (uint32_t)err); 175 return UNKNOWN_ERROR; 176 } 177 178 err = mpDecShellContext->m_pReaderGlobal->m_pFctJump( 179 mpDecShellContext->m_pReader->m_readerContext, 180 (M4_StreamHandler*)mpDecShellContext->m_pVideoStreamhandler, 181 &rapTime); 182 183 if (err != OK) { 184 LOGE("jump err = 0x%x\n", (uint32_t)err); 185 return BAD_VALUE; 186 } 187 } 188 189 *buffer_out = NULL; 190 191 M4OSA_ERR lerr = mGroup->acquire_buffer(&mBuffer); 192 if (lerr != OK) { 193 return lerr; 194 } 195 mBuffer->meta_data()->clear(); // clear all the meta data 196 197 if (mStarted) { 198 //getNext AU from reader. 199 M4_AccessUnit* pAccessUnit = mpDecShellContext->m_pNextAccessUnitToDecode; 200 lerr = mpDecShellContext->m_pReader->m_pFctGetNextAu( 201 mpDecShellContext->m_pReader->m_readerContext, 202 (M4_StreamHandler*)mpDecShellContext->m_pVideoStreamhandler, 203 pAccessUnit); 204 if (lerr == M4WAR_NO_DATA_YET || lerr == M4WAR_NO_MORE_AU) { 205 *buffer_out = NULL; 206 return ERROR_END_OF_STREAM; 207 } 208 209 //copy the reader AU buffer to mBuffer 210 M4OSA_UInt32 lSize = (pAccessUnit->m_size > (M4OSA_UInt32)mMaxAUSize)\ 211 ? (M4OSA_UInt32)mMaxAUSize : pAccessUnit->m_size; 212 memcpy((void *)mBuffer->data(),(void *)pAccessUnit->m_dataAddress, 213 lSize); 214 215 mBuffer->set_range(0, lSize); 216 int64_t frameTimeUs = (int64_t) (pAccessUnit->m_CTS * 1000); 217 mBuffer->meta_data()->setInt64(kKeyTime, frameTimeUs); 218 219 // Replace the AU start code for H264 220 if (VIDEOEDITOR_kH264VideoDec == mCodecType) { 221 uint8_t *data =(uint8_t *)mBuffer->data() + mBuffer->range_offset(); 222 data[0]=0; 223 data[1]=0; 224 data[2]=0; 225 data[3]=1; 226 } 227 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 228 (pAccessUnit->m_attribute == 0x04)? 1 : 0); 229 *buffer_out = mBuffer; 230 } 231 return OK; 232 } 233 234 static M4OSA_UInt32 VideoEditorVideoDecoder_GetBitsFromMemory( 235 VIDEOEDITOR_VIDEO_Bitstream_ctxt* parsingCtxt, M4OSA_UInt32 nb_bits) { 236 return (M4VD_Tools_GetBitsFromMemory((M4VS_Bitstream_ctxt*) parsingCtxt, 237 nb_bits)); 238 } 239 240 M4OSA_ERR VideoEditorVideoDecoder_internalParseVideoDSI(M4OSA_UInt8* pVol, 241 M4OSA_Int32 aVolSize, M4DECODER_MPEG4_DecoderConfigInfo* pDci, 242 M4DECODER_VideoSize* pVideoSize) { 243 244 VIDEOEDITOR_VIDEO_Bitstream_ctxt parsingCtxt; 245 M4OSA_UInt32 code, j; 246 M4OSA_MemAddr8 start; 247 M4OSA_UInt8 i; 248 M4OSA_UInt32 time_incr_length; 249 M4OSA_UInt8 vol_verid=0, b_hierarchy_type; 250 251 /* Parsing variables */ 252 M4OSA_UInt8 video_object_layer_shape = 0; 253 M4OSA_UInt8 sprite_enable = 0; 254 M4OSA_UInt8 reduced_resolution_vop_enable = 0; 255 M4OSA_UInt8 scalability = 0; 256 M4OSA_UInt8 enhancement_type = 0; 257 M4OSA_UInt8 complexity_estimation_disable = 0; 258 M4OSA_UInt8 interlaced = 0; 259 M4OSA_UInt8 sprite_warping_points = 0; 260 M4OSA_UInt8 sprite_brightness_change = 0; 261 M4OSA_UInt8 quant_precision = 0; 262 263 /* Fill the structure with default parameters */ 264 pVideoSize->m_uiWidth = 0; 265 pVideoSize->m_uiHeight = 0; 266 267 pDci->uiTimeScale = 0; 268 pDci->uiProfile = 0; 269 pDci->uiUseOfResynchMarker = 0; 270 pDci->bDataPartition = M4OSA_FALSE; 271 pDci->bUseOfRVLC = M4OSA_FALSE; 272 273 /* Reset the bitstream context */ 274 parsingCtxt.stream_byte = 0; 275 parsingCtxt.stream_index = 8; 276 parsingCtxt.in = (M4OSA_MemAddr8) pVol; 277 278 start = (M4OSA_MemAddr8) pVol; 279 280 /* Start parsing */ 281 while (parsingCtxt.in - start < aVolSize) { 282 code = VideoEditorVideoDecoder_GetBitsFromMemory(&parsingCtxt, 8); 283 if (code == 0) { 284 code = VideoEditorVideoDecoder_GetBitsFromMemory(&parsingCtxt, 8); 285 if (code == 0) { 286 code = VideoEditorVideoDecoder_GetBitsFromMemory(&parsingCtxt,8); 287 if (code == 1) { 288 /* start code found */ 289 code = VideoEditorVideoDecoder_GetBitsFromMemory( 290 &parsingCtxt, 8); 291 292 /* ----- 0x20..0x2F : video_object_layer_start_code ----- */ 293 294 if ((code > 0x1F) && (code < 0x30)) { 295 code = VideoEditorVideoDecoder_GetBitsFromMemory( 296 &parsingCtxt, 1); 297 code = VideoEditorVideoDecoder_GetBitsFromMemory( 298 &parsingCtxt, 8); 299 code = VideoEditorVideoDecoder_GetBitsFromMemory( 300 &parsingCtxt, 1); 301 if (code == 1) { 302 code = VideoEditorVideoDecoder_GetBitsFromMemory( 303 &parsingCtxt, 4); 304 vol_verid = (M4OSA_UInt8)code; 305 code = VideoEditorVideoDecoder_GetBitsFromMemory( 306 &parsingCtxt, 3); 307 } 308 code = VideoEditorVideoDecoder_GetBitsFromMemory( 309 &parsingCtxt, 4); 310 if (code == 15) { 311 code = VideoEditorVideoDecoder_GetBitsFromMemory( 312 &parsingCtxt, 16); 313 } 314 code = VideoEditorVideoDecoder_GetBitsFromMemory( 315 &parsingCtxt, 1); 316 if (code == 1) { 317 code = VideoEditorVideoDecoder_GetBitsFromMemory( 318 &parsingCtxt, 3); 319 code = VideoEditorVideoDecoder_GetBitsFromMemory( 320 &parsingCtxt, 1); 321 if (code == 1) { 322 code = VideoEditorVideoDecoder_GetBitsFromMemory( 323 &parsingCtxt, 32); 324 code = VideoEditorVideoDecoder_GetBitsFromMemory( 325 &parsingCtxt, 31); 326 code = VideoEditorVideoDecoder_GetBitsFromMemory( 327 &parsingCtxt, 16); 328 } 329 } 330 code = VideoEditorVideoDecoder_GetBitsFromMemory( 331 &parsingCtxt, 2); 332 /* Need to save it for vop parsing */ 333 video_object_layer_shape = (M4OSA_UInt8)code; 334 335 if (code != 0) { 336 return 0; /* only rectangular case supported */ 337 } 338 339 code = VideoEditorVideoDecoder_GetBitsFromMemory( 340 &parsingCtxt, 1); 341 code = VideoEditorVideoDecoder_GetBitsFromMemory( 342 &parsingCtxt, 16); 343 pDci->uiTimeScale = code; 344 345 /* Computes time increment length */ 346 j = code - 1; 347 for (i = 0; (i < 32) && (j != 0); j >>=1) { 348 i++; 349 } 350 time_incr_length = (i == 0) ? 1 : i; 351 352 code = VideoEditorVideoDecoder_GetBitsFromMemory( 353 &parsingCtxt, 1); 354 code = VideoEditorVideoDecoder_GetBitsFromMemory( 355 &parsingCtxt, 1); 356 if (code == 1) { 357 code = VideoEditorVideoDecoder_GetBitsFromMemory( 358 &parsingCtxt, time_incr_length); 359 } 360 361 if(video_object_layer_shape != 1) { /* 1 = Binary */ 362 if(video_object_layer_shape == 0) { 363 code = VideoEditorVideoDecoder_GetBitsFromMemory( 364 &parsingCtxt, 1);/* Marker bit */ 365 code = VideoEditorVideoDecoder_GetBitsFromMemory( 366 &parsingCtxt, 13);/* Width */ 367 pVideoSize->m_uiWidth = code; 368 code = VideoEditorVideoDecoder_GetBitsFromMemory( 369 &parsingCtxt, 1);/* Marker bit */ 370 code = VideoEditorVideoDecoder_GetBitsFromMemory( 371 &parsingCtxt, 13);/* Height */ 372 pVideoSize->m_uiHeight = code; 373 code = VideoEditorVideoDecoder_GetBitsFromMemory( 374 &parsingCtxt, 1);/* Marker bit */ 375 } 376 } 377 378 code = VideoEditorVideoDecoder_GetBitsFromMemory( 379 &parsingCtxt, 1);/* interlaced */ 380 interlaced = (M4OSA_UInt8)code; 381 code = VideoEditorVideoDecoder_GetBitsFromMemory( 382 &parsingCtxt, 1);/* OBMC disable */ 383 384 if(vol_verid == 1) { 385 code = VideoEditorVideoDecoder_GetBitsFromMemory( 386 &parsingCtxt, 1);/* sprite enable */ 387 sprite_enable = (M4OSA_UInt8)code; 388 } else { 389 code = VideoEditorVideoDecoder_GetBitsFromMemory( 390 &parsingCtxt, 2);/* sprite enable */ 391 sprite_enable = (M4OSA_UInt8)code; 392 } 393 if ((sprite_enable == 1) || (sprite_enable == 2)) { 394 if (sprite_enable != 2) { 395 396 code = VideoEditorVideoDecoder_GetBitsFromMemory( 397 &parsingCtxt, 13);/* sprite width */ 398 code = VideoEditorVideoDecoder_GetBitsFromMemory( 399 &parsingCtxt, 1);/* Marker bit */ 400 code = VideoEditorVideoDecoder_GetBitsFromMemory( 401 &parsingCtxt, 13);/* sprite height */ 402 code = VideoEditorVideoDecoder_GetBitsFromMemory( 403 &parsingCtxt, 1);/* Marker bit */ 404 code = VideoEditorVideoDecoder_GetBitsFromMemory( 405 &parsingCtxt, 13);/* sprite l coordinate */ 406 code = VideoEditorVideoDecoder_GetBitsFromMemory( 407 &parsingCtxt, 1);/* Marker bit */ 408 code = VideoEditorVideoDecoder_GetBitsFromMemory( 409 &parsingCtxt, 13);/* sprite top coordinate */ 410 code = VideoEditorVideoDecoder_GetBitsFromMemory( 411 &parsingCtxt, 1);/* Marker bit */ 412 } 413 414 code = VideoEditorVideoDecoder_GetBitsFromMemory( 415 &parsingCtxt, 6);/* sprite warping points */ 416 sprite_warping_points = (M4OSA_UInt8)code; 417 code = VideoEditorVideoDecoder_GetBitsFromMemory( 418 &parsingCtxt, 2);/* sprite warping accuracy */ 419 code = VideoEditorVideoDecoder_GetBitsFromMemory( 420 &parsingCtxt, 1);/* sprite brightness change */ 421 sprite_brightness_change = (M4OSA_UInt8)code; 422 if (sprite_enable != 2) { 423 code = VideoEditorVideoDecoder_GetBitsFromMemory( 424 &parsingCtxt, 1); 425 } 426 } 427 if ((vol_verid != 1) && (video_object_layer_shape != 0)){ 428 code = VideoEditorVideoDecoder_GetBitsFromMemory( 429 &parsingCtxt, 1);/* sadct disable */ 430 } 431 432 code = VideoEditorVideoDecoder_GetBitsFromMemory( 433 &parsingCtxt, 1); /* not 8 bits */ 434 if (code) { 435 code = VideoEditorVideoDecoder_GetBitsFromMemory( 436 &parsingCtxt, 4);/* quant precision */ 437 quant_precision = (M4OSA_UInt8)code; 438 code = VideoEditorVideoDecoder_GetBitsFromMemory( 439 &parsingCtxt, 4);/* bits per pixel */ 440 } 441 442 /* greyscale not supported */ 443 if(video_object_layer_shape == 3) { 444 code = VideoEditorVideoDecoder_GetBitsFromMemory( 445 &parsingCtxt, 3); 446 } 447 448 code = VideoEditorVideoDecoder_GetBitsFromMemory( 449 &parsingCtxt, 1);/* quant type */ 450 if (code) { 451 code = VideoEditorVideoDecoder_GetBitsFromMemory( 452 &parsingCtxt, 1);/* load intra quant mat */ 453 if (code) { 454 code = VideoEditorVideoDecoder_GetBitsFromMemory( 455 &parsingCtxt, 8);/* */ 456 i = 1; 457 while (i < 64) { 458 code = 459 VideoEditorVideoDecoder_GetBitsFromMemory( 460 &parsingCtxt, 8); 461 if (code == 0) { 462 break; 463 } 464 i++; 465 } 466 } 467 468 code = VideoEditorVideoDecoder_GetBitsFromMemory( 469 &parsingCtxt, 1);/* load non intra quant mat */ 470 if (code) { 471 code = VideoEditorVideoDecoder_GetBitsFromMemory( 472 &parsingCtxt, 8);/* */ 473 i = 1; 474 while (i < 64) { 475 code = 476 VideoEditorVideoDecoder_GetBitsFromMemory( 477 &parsingCtxt, 8); 478 if (code == 0) { 479 break; 480 } 481 i++; 482 } 483 } 484 } 485 486 if (vol_verid != 1) { 487 code = VideoEditorVideoDecoder_GetBitsFromMemory( 488 &parsingCtxt, 1);/* quarter sample */ 489 } 490 491 code = VideoEditorVideoDecoder_GetBitsFromMemory( 492 &parsingCtxt, 1);/* complexity estimation disable */ 493 complexity_estimation_disable = (M4OSA_UInt8)code; 494 if (!code) { 495 //return M4ERR_NOT_IMPLEMENTED; 496 } 497 498 code = VideoEditorVideoDecoder_GetBitsFromMemory( 499 &parsingCtxt, 1);/* resync marker disable */ 500 pDci->uiUseOfResynchMarker = (code) ? 0 : 1; 501 502 code = VideoEditorVideoDecoder_GetBitsFromMemory( 503 &parsingCtxt, 1);/* data partitionned */ 504 pDci->bDataPartition = (code) ? M4OSA_TRUE : M4OSA_FALSE; 505 if (code) { 506 code = VideoEditorVideoDecoder_GetBitsFromMemory( 507 &parsingCtxt, 1);/* reversible VLC */ 508 pDci->bUseOfRVLC = (code) ? M4OSA_TRUE : M4OSA_FALSE; 509 } 510 511 if (vol_verid != 1) { 512 code = VideoEditorVideoDecoder_GetBitsFromMemory( 513 &parsingCtxt, 1);/* newpred */ 514 if (code) { 515 //return M4ERR_PARAMETER; 516 } 517 518 code = VideoEditorVideoDecoder_GetBitsFromMemory( 519 &parsingCtxt, 1); 520 reduced_resolution_vop_enable = (M4OSA_UInt8)code; 521 } 522 523 code = VideoEditorVideoDecoder_GetBitsFromMemory( 524 &parsingCtxt, 1);/* scalability */ 525 scalability = (M4OSA_UInt8)code; 526 if (code) { 527 code = VideoEditorVideoDecoder_GetBitsFromMemory( 528 &parsingCtxt, 1);/* hierarchy type */ 529 b_hierarchy_type = (M4OSA_UInt8)code; 530 code = VideoEditorVideoDecoder_GetBitsFromMemory( 531 &parsingCtxt, 4);/* ref layer id */ 532 code = VideoEditorVideoDecoder_GetBitsFromMemory( 533 &parsingCtxt, 1);/* ref sampling direct */ 534 code = VideoEditorVideoDecoder_GetBitsFromMemory( 535 &parsingCtxt, 5);/* hor sampling factor N */ 536 code = VideoEditorVideoDecoder_GetBitsFromMemory( 537 &parsingCtxt, 5);/* hor sampling factor M */ 538 code = VideoEditorVideoDecoder_GetBitsFromMemory( 539 &parsingCtxt, 5);/* vert sampling factor N */ 540 code = VideoEditorVideoDecoder_GetBitsFromMemory( 541 &parsingCtxt, 5);/* vert sampling factor M */ 542 code = VideoEditorVideoDecoder_GetBitsFromMemory( 543 &parsingCtxt, 1);/* enhancement type */ 544 enhancement_type = (M4OSA_UInt8)code; 545 if ((!b_hierarchy_type) && 546 (video_object_layer_shape == 1)) { 547 code = VideoEditorVideoDecoder_GetBitsFromMemory( 548 &parsingCtxt, 1);/* use ref shape */ 549 code = VideoEditorVideoDecoder_GetBitsFromMemory( 550 &parsingCtxt, 1);/* use ref texture */ 551 code = VideoEditorVideoDecoder_GetBitsFromMemory( 552 &parsingCtxt, 5); 553 code = VideoEditorVideoDecoder_GetBitsFromMemory( 554 &parsingCtxt, 5); 555 code = VideoEditorVideoDecoder_GetBitsFromMemory( 556 &parsingCtxt, 5); 557 code = VideoEditorVideoDecoder_GetBitsFromMemory( 558 &parsingCtxt, 5); 559 } 560 } 561 break; 562 } 563 564 /* ----- 0xB0 : visual_object_sequence_start_code ----- */ 565 566 else if(code == 0xB0) { 567 code = VideoEditorVideoDecoder_GetBitsFromMemory( 568 &parsingCtxt, 8);/* profile_and_level_indication */ 569 pDci->uiProfile = (M4OSA_UInt8)code; 570 } 571 572 /* ----- 0xB5 : visual_object_start_code ----- */ 573 574 else if(code == 0xB5) { 575 code = VideoEditorVideoDecoder_GetBitsFromMemory( 576 &parsingCtxt, 1);/* is object layer identifier */ 577 if (code == 1) { 578 code = VideoEditorVideoDecoder_GetBitsFromMemory( 579 &parsingCtxt, 4); /* visual object verid */ 580 vol_verid = (M4OSA_UInt8)code; 581 code = VideoEditorVideoDecoder_GetBitsFromMemory( 582 &parsingCtxt, 3); 583 } else { 584 code = VideoEditorVideoDecoder_GetBitsFromMemory( 585 &parsingCtxt, 7); /* Realign on byte */ 586 vol_verid = 1; 587 } 588 } 589 590 /* ----- end ----- */ 591 } else { 592 if ((code >> 2) == 0x20) { 593 /* H263 ...-> wrong*/ 594 break; 595 } 596 } 597 } 598 } 599 } 600 return M4NO_ERROR; 601 } 602 603 M4VIFI_UInt8 M4VIFI_SemiplanarYVU420toYUV420(void *user_data, 604 M4VIFI_UInt8 *inyuv, M4VIFI_ImagePlane *PlaneOut ) { 605 M4VIFI_UInt8 return_code = M4VIFI_OK; 606 M4VIFI_UInt8 *outyuv = 607 ((M4VIFI_UInt8*)&(PlaneOut[0].pac_data[PlaneOut[0].u_topleft])); 608 int32_t width = PlaneOut[0].u_width; 609 int32_t height = PlaneOut[0].u_height; 610 611 int32_t outYsize = width * height; 612 uint32_t *outy = (uint32_t *) outyuv; 613 uint16_t *outcb = 614 (uint16_t *) &(PlaneOut[1].pac_data[PlaneOut[1].u_topleft]); 615 uint16_t *outcr = 616 (uint16_t *) &(PlaneOut[2].pac_data[PlaneOut[2].u_topleft]); 617 618 /* Y copying */ 619 memcpy((void *)outy, (void *)inyuv, outYsize); 620 621 /* U & V copying */ 622 uint32_t *inyuv_4 = (uint32_t *) (inyuv + outYsize); 623 for (int32_t i = height >> 1; i > 0; --i) { 624 for (int32_t j = width >> 2; j > 0; --j) { 625 uint32_t temp = *inyuv_4++; 626 uint32_t tempU = temp & 0xFF; 627 tempU = tempU | ((temp >> 8) & 0xFF00); 628 629 uint32_t tempV = (temp >> 8) & 0xFF; 630 tempV = tempV | ((temp >> 16) & 0xFF00); 631 632 // Flip U and V 633 *outcb++ = tempV; 634 *outcr++ = tempU; 635 } 636 } 637 return return_code; 638 } 639 void logSupportDecodersAndCapabilities(M4DECODER_VideoDecoders* decoders) { 640 VideoDecoder *pDecoder; 641 VideoComponentCapabilities *pOmxComponents = NULL; 642 VideoProfileLevel *pProfileLevel = NULL; 643 pDecoder = decoders->decoder; 644 for (size_t i = 0; i< decoders->decoderNumber; i++) { 645 LOGV("Supported Codec[%d] :%d", i, pDecoder->codec); 646 pOmxComponents = pDecoder->component; 647 for(size_t j = 0; j < pDecoder->componentNumber; j++) { 648 pProfileLevel = pOmxComponents->profileLevel; 649 LOGV("-->component %d", j); 650 for(size_t k = 0; k < pOmxComponents->profileNumber; k++) { 651 LOGV("-->profile:%ld maxLevel:%ld", pProfileLevel->mProfile, 652 pProfileLevel->mLevel); 653 pProfileLevel++; 654 } 655 pOmxComponents++; 656 } 657 pDecoder++; 658 } 659 } 660 661 M4OSA_ERR queryVideoDecoderCapabilities 662 (M4DECODER_VideoDecoders** decoders) { 663 M4OSA_ERR err = M4NO_ERROR; 664 const char *kMimeTypes[] = { 665 MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4, 666 MEDIA_MIMETYPE_VIDEO_H263 667 }; 668 669 int32_t supportFormats = sizeof(kMimeTypes) / sizeof(kMimeTypes[0]); 670 M4DECODER_VideoDecoders *pDecoders; 671 VideoDecoder *pDecoder; 672 VideoComponentCapabilities *pOmxComponents = NULL; 673 VideoProfileLevel *pProfileLevel = NULL; 674 OMXClient client; 675 status_t status = OK; 676 SAFE_MALLOC(pDecoders, M4DECODER_VideoDecoders, 1, "VideoDecoders"); 677 SAFE_MALLOC(pDecoder, VideoDecoder, supportFormats, 678 "VideoDecoder"); 679 pDecoders->decoder = pDecoder; 680 681 pDecoders->decoderNumber= supportFormats; 682 status = client.connect(); 683 CHECK(status == OK); 684 for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]); 685 ++k) { 686 Vector<CodecCapabilities> results; 687 CHECK_EQ(QueryCodecs(client.interface(), kMimeTypes[k], 688 true, // queryDecoders 689 &results), (status_t)OK); 690 691 if (results.size()) { 692 SAFE_MALLOC(pOmxComponents, VideoComponentCapabilities, 693 results.size(), "VideoComponentCapabilities"); 694 LOGV("K=%d",k); 695 pDecoder->component = pOmxComponents; 696 pDecoder->componentNumber = results.size(); 697 } 698 699 for (size_t i = 0; i < results.size(); ++i) { 700 LOGV(" decoder '%s' supports ", 701 results[i].mComponentName.string()); 702 703 if (results[i].mProfileLevels.size() == 0) { 704 LOGV("NOTHING.\n"); 705 continue; 706 } 707 708 #if 0 709 // FIXME: 710 // We should ignore the software codecs and make IsSoftwareCodec() 711 // part of pubic API from OMXCodec.cpp 712 if (IsSoftwareCodec(results[i].mComponentName.string())) { 713 LOGV("Ignore software codec %s", results[i].mComponentName.string()); 714 continue; 715 } 716 #endif 717 718 // Count the supported profiles 719 int32_t profileNumber = 0; 720 int32_t profile = -1; 721 for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) { 722 const CodecProfileLevel &profileLevel = 723 results[i].mProfileLevels[j]; 724 // FIXME: assume that the profiles are ordered 725 if (profileLevel.mProfile != profile) { 726 profile = profileLevel.mProfile; 727 profileNumber++; 728 } 729 } 730 SAFE_MALLOC(pProfileLevel, VideoProfileLevel, 731 profileNumber, "VideoProfileLevel"); 732 pOmxComponents->profileLevel = pProfileLevel; 733 pOmxComponents->profileNumber = profileNumber; 734 735 // Get the max Level for each profile. 736 int32_t maxLevel = -1; 737 profile = -1; 738 profileNumber = 0; 739 for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) { 740 const CodecProfileLevel &profileLevel = 741 results[i].mProfileLevels[j]; 742 if (profile == -1 && maxLevel == -1) { 743 profile = profileLevel.mProfile; 744 maxLevel = profileLevel.mLevel; 745 pProfileLevel->mProfile = profile; 746 pProfileLevel->mLevel = maxLevel; 747 LOGV("%d profile: %ld, max level: %ld", 748 __LINE__, pProfileLevel->mProfile, pProfileLevel->mLevel); 749 } 750 if (profileLevel.mProfile != profile) { 751 profile = profileLevel.mProfile; 752 maxLevel = profileLevel.mLevel; 753 profileNumber++; 754 pProfileLevel++; 755 pProfileLevel->mProfile = profile; 756 pProfileLevel->mLevel = maxLevel; 757 LOGV("%d profile: %ld, max level: %ld", 758 __LINE__, pProfileLevel->mProfile, pProfileLevel->mLevel); 759 } else if (profileLevel.mLevel > maxLevel) { 760 maxLevel = profileLevel.mLevel; 761 pProfileLevel->mLevel = maxLevel; 762 LOGV("%d profile: %ld, max level: %ld", 763 __LINE__, pProfileLevel->mProfile, pProfileLevel->mLevel); 764 } 765 766 } 767 pOmxComponents++; 768 } 769 if (!strcmp(MEDIA_MIMETYPE_VIDEO_AVC, kMimeTypes[k])) 770 pDecoder->codec = M4DA_StreamTypeVideoMpeg4Avc; 771 if (!strcmp(MEDIA_MIMETYPE_VIDEO_MPEG4, kMimeTypes[k])) 772 pDecoder->codec = M4DA_StreamTypeVideoMpeg4; 773 if (!strcmp(MEDIA_MIMETYPE_VIDEO_H263, kMimeTypes[k])) 774 pDecoder->codec = M4DA_StreamTypeVideoH263; 775 776 pDecoder++; 777 } 778 779 logSupportDecodersAndCapabilities(pDecoders); 780 *decoders = pDecoders; 781 cleanUp: 782 return err; 783 } 784 /******************** 785 * ENGINE INTERFACE * 786 ********************/ 787 M4OSA_ERR VideoEditorVideoDecoder_configureFromMetadata(M4OSA_Context pContext, 788 MetaData* meta) { 789 M4OSA_ERR err = M4NO_ERROR; 790 VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL; 791 bool success = OK; 792 int32_t width = 0; 793 int32_t height = 0; 794 int32_t frameSize = 0; 795 int32_t vWidth, vHeight; 796 int32_t cropLeft, cropTop, cropRight, cropBottom; 797 798 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 799 VIDEOEDITOR_CHECK(M4OSA_NULL != meta, M4ERR_PARAMETER); 800 801 LOGV("VideoEditorVideoDecoder_configureFromMetadata begin"); 802 803 pDecShellContext = (VideoEditorVideoDecoder_Context*)pContext; 804 805 success = meta->findInt32(kKeyWidth, &vWidth); 806 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 807 success = meta->findInt32(kKeyHeight, &vHeight); 808 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 809 810 LOGV("vWidth = %d, vHeight = %d", vWidth, vHeight); 811 812 pDecShellContext->mGivenWidth = vWidth; 813 pDecShellContext->mGivenHeight = vHeight; 814 815 if (!meta->findRect( 816 kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) { 817 818 cropLeft = cropTop = 0; 819 cropRight = vWidth - 1; 820 cropBottom = vHeight - 1; 821 822 LOGV("got dimensions only %d x %d", width, height); 823 } else { 824 LOGV("got crop rect %d, %d, %d, %d", 825 cropLeft, cropTop, cropRight, cropBottom); 826 } 827 828 pDecShellContext->mCropRect.left = cropLeft; 829 pDecShellContext->mCropRect.right = cropRight; 830 pDecShellContext->mCropRect.top = cropTop; 831 pDecShellContext->mCropRect.bottom = cropBottom; 832 833 width = cropRight - cropLeft + 1; 834 height = cropBottom - cropTop + 1; 835 836 LOGV("VideoDecoder_configureFromMetadata : W=%d H=%d", width, height); 837 VIDEOEDITOR_CHECK((0 != width) && (0 != height), M4ERR_PARAMETER); 838 839 if( (M4OSA_NULL != pDecShellContext->m_pDecBufferPool) && 840 (pDecShellContext->m_pVideoStreamhandler->m_videoWidth == \ 841 (uint32_t)width) && 842 (pDecShellContext->m_pVideoStreamhandler->m_videoHeight == \ 843 (uint32_t)height) ) { 844 // No need to reconfigure 845 goto cleanUp; 846 } 847 LOGV("VideoDecoder_configureFromMetadata reset: W=%d H=%d", width, height); 848 // Update the stream handler parameters 849 pDecShellContext->m_pVideoStreamhandler->m_videoWidth = width; 850 pDecShellContext->m_pVideoStreamhandler->m_videoHeight = height; 851 frameSize = (width * height * 3) / 2; 852 853 // Configure the buffer pool 854 if( M4OSA_NULL != pDecShellContext->m_pDecBufferPool ) { 855 LOGV("VideoDecoder_configureFromMetadata : reset the buffer pool"); 856 VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool); 857 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 858 } 859 err = VIDEOEDITOR_BUFFER_allocatePool(&pDecShellContext->m_pDecBufferPool, 860 MAX_DEC_BUFFERS, (M4OSA_Char*)"VIDEOEDITOR_DecodedBufferPool"); 861 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 862 err = VIDEOEDITOR_BUFFER_initPoolBuffers(pDecShellContext->m_pDecBufferPool, 863 frameSize + pDecShellContext->mGivenWidth * 2); 864 865 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 866 867 cleanUp: 868 if( M4NO_ERROR == err ) { 869 LOGV("VideoEditorVideoDecoder_configureFromMetadata no error"); 870 } else { 871 if( M4OSA_NULL != pDecShellContext->m_pDecBufferPool ) { 872 VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool); 873 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 874 } 875 LOGV("VideoEditorVideoDecoder_configureFromMetadata ERROR 0x%X", err); 876 } 877 LOGV("VideoEditorVideoDecoder_configureFromMetadata end"); 878 return err; 879 } 880 881 M4OSA_ERR VideoEditorVideoDecoder_destroy(M4OSA_Context pContext) { 882 M4OSA_ERR err = M4NO_ERROR; 883 VideoEditorVideoDecoder_Context* pDecShellContext = 884 (VideoEditorVideoDecoder_Context*)pContext; 885 886 // Input parameters check 887 LOGV("VideoEditorVideoDecoder_destroy begin"); 888 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 889 890 // Release the color converter 891 delete pDecShellContext->mI420ColorConverter; 892 893 // Destroy the graph 894 if( pDecShellContext->mVideoDecoder != NULL ) { 895 LOGV("### VideoEditorVideoDecoder_destroy : releasing decoder"); 896 pDecShellContext->mVideoDecoder->stop(); 897 pDecShellContext->mVideoDecoder.clear(); 898 } 899 pDecShellContext->mClient.disconnect(); 900 pDecShellContext->mReaderSource.clear(); 901 902 // Release memory 903 if( pDecShellContext->m_pDecBufferPool != M4OSA_NULL ) { 904 VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool); 905 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 906 } 907 SAFE_FREE(pDecShellContext); 908 pContext = NULL; 909 910 cleanUp: 911 if( M4NO_ERROR == err ) { 912 LOGV("VideoEditorVideoDecoder_destroy no error"); 913 } else { 914 LOGV("VideoEditorVideoDecoder_destroy ERROR 0x%X", err); 915 } 916 LOGV("VideoEditorVideoDecoder_destroy end"); 917 return err; 918 } 919 920 M4OSA_ERR VideoEditorVideoDecoder_create(M4OSA_Context *pContext, 921 M4_StreamHandler *pStreamHandler, 922 M4READER_GlobalInterface *pReaderGlobalInterface, 923 M4READER_DataInterface *pReaderDataInterface, 924 M4_AccessUnit *pAccessUnit, M4OSA_Void *pUserData) { 925 M4OSA_ERR err = M4NO_ERROR; 926 VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL; 927 status_t status = OK; 928 bool success = TRUE; 929 int32_t colorFormat = 0; 930 M4OSA_UInt32 size = 0; 931 sp<MetaData> decoderMetadata = NULL; 932 int decoderOutput = OMX_COLOR_FormatYUV420Planar; 933 934 LOGV("VideoEditorVideoDecoder_create begin"); 935 // Input parameters check 936 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 937 VIDEOEDITOR_CHECK(M4OSA_NULL != pStreamHandler, M4ERR_PARAMETER); 938 VIDEOEDITOR_CHECK(M4OSA_NULL != pReaderDataInterface, M4ERR_PARAMETER); 939 940 // Context allocation & initialization 941 SAFE_MALLOC(pDecShellContext, VideoEditorVideoDecoder_Context, 1, 942 "VideoEditorVideoDecoder"); 943 pDecShellContext->m_pVideoStreamhandler = 944 (M4_VideoStreamHandler*)pStreamHandler; 945 pDecShellContext->m_pNextAccessUnitToDecode = pAccessUnit; 946 pDecShellContext->m_pReaderGlobal = pReaderGlobalInterface; 947 pDecShellContext->m_pReader = pReaderDataInterface; 948 pDecShellContext->m_lastDecodedCTS = -1; 949 pDecShellContext->m_lastRenderCts = -1; 950 switch( pStreamHandler->m_streamType ) { 951 case M4DA_StreamTypeVideoH263: 952 pDecShellContext->mDecoderType = VIDEOEDITOR_kH263VideoDec; 953 break; 954 case M4DA_StreamTypeVideoMpeg4: 955 pDecShellContext->mDecoderType = VIDEOEDITOR_kMpeg4VideoDec; 956 // Parse the VOL header 957 err = VideoEditorVideoDecoder_internalParseVideoDSI( 958 (M4OSA_UInt8*)pDecShellContext->m_pVideoStreamhandler->\ 959 m_basicProperties.m_pDecoderSpecificInfo, 960 pDecShellContext->m_pVideoStreamhandler->\ 961 m_basicProperties.m_decoderSpecificInfoSize, 962 &pDecShellContext->m_Dci, &pDecShellContext->m_VideoSize); 963 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 964 break; 965 case M4DA_StreamTypeVideoMpeg4Avc: 966 pDecShellContext->mDecoderType = VIDEOEDITOR_kH264VideoDec; 967 break; 968 default: 969 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 970 M4ERR_PARAMETER); 971 break; 972 } 973 974 pDecShellContext->mNbInputFrames = 0; 975 pDecShellContext->mFirstInputCts = -1.0; 976 pDecShellContext->mLastInputCts = -1.0; 977 pDecShellContext->mNbRenderedFrames = 0; 978 pDecShellContext->mFirstRenderedCts = -1.0; 979 pDecShellContext->mLastRenderedCts = -1.0; 980 pDecShellContext->mNbOutputFrames = 0; 981 pDecShellContext->mFirstOutputCts = -1; 982 pDecShellContext->mLastOutputCts = -1; 983 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 984 985 /** 986 * StageFright graph building 987 */ 988 decoderMetadata = new MetaData; 989 switch( pDecShellContext->mDecoderType ) { 990 case VIDEOEDITOR_kH263VideoDec: 991 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 992 break; 993 case VIDEOEDITOR_kMpeg4VideoDec: 994 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 995 decoderMetadata->setData(kKeyESDS, kTypeESDS, 996 pStreamHandler->m_pESDSInfo, 997 pStreamHandler->m_ESDSInfoSize); 998 break; 999 case VIDEOEDITOR_kH264VideoDec: 1000 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 1001 decoderMetadata->setData(kKeyAVCC, kTypeAVCC, 1002 pStreamHandler->m_pH264DecoderSpecificInfo, 1003 pStreamHandler->m_H264decoderSpecificInfoSize); 1004 break; 1005 default: 1006 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 1007 M4ERR_PARAMETER); 1008 break; 1009 } 1010 1011 decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize); 1012 decoderMetadata->setInt32(kKeyWidth, 1013 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 1014 decoderMetadata->setInt32(kKeyHeight, 1015 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1016 1017 // Create the decoder source 1018 pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource( 1019 decoderMetadata, pDecShellContext->mDecoderType, 1020 (void *)pDecShellContext); 1021 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(), 1022 M4ERR_SF_DECODER_RSRC_FAIL); 1023 1024 // Connect to the OMX client 1025 status = pDecShellContext->mClient.connect(); 1026 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 1027 1028 // Create the decoder 1029 pDecShellContext->mVideoDecoder = OMXCodec::Create( 1030 pDecShellContext->mClient.interface(), 1031 decoderMetadata, false, pDecShellContext->mReaderSource); 1032 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(), 1033 M4ERR_SF_DECODER_RSRC_FAIL); 1034 1035 1036 // Get the output color format 1037 success = pDecShellContext->mVideoDecoder->getFormat()->findInt32( 1038 kKeyColorFormat, &colorFormat); 1039 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 1040 pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; 1041 1042 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth, 1043 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 1044 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight, 1045 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1046 1047 // Get the color converter 1048 pDecShellContext->mI420ColorConverter = new I420ColorConverter; 1049 if (pDecShellContext->mI420ColorConverter->isLoaded()) { 1050 decoderOutput = pDecShellContext->mI420ColorConverter->getDecoderOutputFormat(); 1051 } 1052 1053 if (decoderOutput == OMX_COLOR_FormatYUV420Planar) { 1054 delete pDecShellContext->mI420ColorConverter; 1055 pDecShellContext->mI420ColorConverter = NULL; 1056 } 1057 1058 LOGI("decoder output format = 0x%X\n", decoderOutput); 1059 1060 // Configure the buffer pool from the metadata 1061 err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext, 1062 pDecShellContext->mVideoDecoder->getFormat().get()); 1063 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 1064 1065 // Start the graph 1066 status = pDecShellContext->mVideoDecoder->start(); 1067 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 1068 1069 *pContext = (M4OSA_Context)pDecShellContext; 1070 1071 cleanUp: 1072 if( M4NO_ERROR == err ) { 1073 LOGV("VideoEditorVideoDecoder_create no error"); 1074 } else { 1075 VideoEditorVideoDecoder_destroy(pDecShellContext); 1076 *pContext = M4OSA_NULL; 1077 LOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err); 1078 } 1079 LOGV("VideoEditorVideoDecoder_create : DONE"); 1080 return err; 1081 } 1082 1083 M4OSA_ERR VideoEditorVideoSoftwareDecoder_create(M4OSA_Context *pContext, 1084 M4_StreamHandler *pStreamHandler, 1085 M4READER_GlobalInterface *pReaderGlobalInterface, 1086 M4READER_DataInterface *pReaderDataInterface, 1087 M4_AccessUnit *pAccessUnit, M4OSA_Void *pUserData) { 1088 M4OSA_ERR err = M4NO_ERROR; 1089 VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL; 1090 status_t status = OK; 1091 bool success = TRUE; 1092 int32_t colorFormat = 0; 1093 M4OSA_UInt32 size = 0; 1094 sp<MetaData> decoderMetadata = NULL; 1095 1096 LOGV("VideoEditorVideoDecoder_create begin"); 1097 // Input parameters check 1098 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 1099 VIDEOEDITOR_CHECK(M4OSA_NULL != pStreamHandler, M4ERR_PARAMETER); 1100 VIDEOEDITOR_CHECK(M4OSA_NULL != pReaderDataInterface, M4ERR_PARAMETER); 1101 1102 // Context allocation & initialization 1103 SAFE_MALLOC(pDecShellContext, VideoEditorVideoDecoder_Context, 1, 1104 "VideoEditorVideoDecoder"); 1105 pDecShellContext->m_pVideoStreamhandler = 1106 (M4_VideoStreamHandler*)pStreamHandler; 1107 pDecShellContext->m_pNextAccessUnitToDecode = pAccessUnit; 1108 pDecShellContext->m_pReaderGlobal = pReaderGlobalInterface; 1109 pDecShellContext->m_pReader = pReaderDataInterface; 1110 pDecShellContext->m_lastDecodedCTS = -1; 1111 pDecShellContext->m_lastRenderCts = -1; 1112 switch( pStreamHandler->m_streamType ) { 1113 case M4DA_StreamTypeVideoH263: 1114 pDecShellContext->mDecoderType = VIDEOEDITOR_kH263VideoDec; 1115 break; 1116 case M4DA_StreamTypeVideoMpeg4: 1117 pDecShellContext->mDecoderType = VIDEOEDITOR_kMpeg4VideoDec; 1118 // Parse the VOL header 1119 err = VideoEditorVideoDecoder_internalParseVideoDSI( 1120 (M4OSA_UInt8*)pDecShellContext->m_pVideoStreamhandler->\ 1121 m_basicProperties.m_pDecoderSpecificInfo, 1122 pDecShellContext->m_pVideoStreamhandler->\ 1123 m_basicProperties.m_decoderSpecificInfoSize, 1124 &pDecShellContext->m_Dci, &pDecShellContext->m_VideoSize); 1125 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 1126 break; 1127 case M4DA_StreamTypeVideoMpeg4Avc: 1128 pDecShellContext->mDecoderType = VIDEOEDITOR_kH264VideoDec; 1129 break; 1130 default: 1131 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 1132 M4ERR_PARAMETER); 1133 break; 1134 } 1135 1136 pDecShellContext->mNbInputFrames = 0; 1137 pDecShellContext->mFirstInputCts = -1.0; 1138 pDecShellContext->mLastInputCts = -1.0; 1139 pDecShellContext->mNbRenderedFrames = 0; 1140 pDecShellContext->mFirstRenderedCts = -1.0; 1141 pDecShellContext->mLastRenderedCts = -1.0; 1142 pDecShellContext->mNbOutputFrames = 0; 1143 pDecShellContext->mFirstOutputCts = -1; 1144 pDecShellContext->mLastOutputCts = -1; 1145 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 1146 1147 /** 1148 * StageFright graph building 1149 */ 1150 decoderMetadata = new MetaData; 1151 switch( pDecShellContext->mDecoderType ) { 1152 case VIDEOEDITOR_kH263VideoDec: 1153 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 1154 break; 1155 case VIDEOEDITOR_kMpeg4VideoDec: 1156 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 1157 decoderMetadata->setData(kKeyESDS, kTypeESDS, 1158 pStreamHandler->m_pESDSInfo, 1159 pStreamHandler->m_ESDSInfoSize); 1160 break; 1161 case VIDEOEDITOR_kH264VideoDec: 1162 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 1163 decoderMetadata->setData(kKeyAVCC, kTypeAVCC, 1164 pStreamHandler->m_pH264DecoderSpecificInfo, 1165 pStreamHandler->m_H264decoderSpecificInfoSize); 1166 break; 1167 default: 1168 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 1169 M4ERR_PARAMETER); 1170 break; 1171 } 1172 1173 decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize); 1174 decoderMetadata->setInt32(kKeyWidth, 1175 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 1176 decoderMetadata->setInt32(kKeyHeight, 1177 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1178 1179 // Create the decoder source 1180 pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource( 1181 decoderMetadata, pDecShellContext->mDecoderType, 1182 (void *)pDecShellContext); 1183 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(), 1184 M4ERR_SF_DECODER_RSRC_FAIL); 1185 1186 // Connect to the OMX client 1187 status = pDecShellContext->mClient.connect(); 1188 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 1189 1190 LOGI("Using software codecs only"); 1191 // Create the decoder 1192 pDecShellContext->mVideoDecoder = OMXCodec::Create( 1193 pDecShellContext->mClient.interface(), 1194 decoderMetadata, false, pDecShellContext->mReaderSource,NULL,OMXCodec::kSoftwareCodecsOnly); 1195 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(), 1196 M4ERR_SF_DECODER_RSRC_FAIL); 1197 1198 // Get the output color format 1199 success = pDecShellContext->mVideoDecoder->getFormat()->findInt32( 1200 kKeyColorFormat, &colorFormat); 1201 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 1202 pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; 1203 1204 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth, 1205 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 1206 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight, 1207 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1208 1209 // Configure the buffer pool from the metadata 1210 err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext, 1211 pDecShellContext->mVideoDecoder->getFormat().get()); 1212 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 1213 1214 // Start the graph 1215 status = pDecShellContext->mVideoDecoder->start(); 1216 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 1217 1218 *pContext = (M4OSA_Context)pDecShellContext; 1219 1220 cleanUp: 1221 if( M4NO_ERROR == err ) { 1222 LOGV("VideoEditorVideoDecoder_create no error"); 1223 } else { 1224 VideoEditorVideoDecoder_destroy(pDecShellContext); 1225 *pContext = M4OSA_NULL; 1226 LOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err); 1227 } 1228 LOGV("VideoEditorVideoDecoder_create : DONE"); 1229 return err; 1230 } 1231 1232 1233 M4OSA_ERR VideoEditorVideoDecoder_getOption(M4OSA_Context context, 1234 M4OSA_OptionID optionId, M4OSA_DataOption pValue) { 1235 M4OSA_ERR lerr = M4NO_ERROR; 1236 VideoEditorVideoDecoder_Context* pDecShellContext = 1237 (VideoEditorVideoDecoder_Context*) context; 1238 M4_VersionInfo* pVersionInfo; 1239 M4DECODER_VideoSize* pVideoSize; 1240 M4OSA_UInt32* pNextFrameCts; 1241 M4OSA_UInt32 *plastDecodedFrameCts; 1242 M4DECODER_AVCProfileLevel* profile; 1243 M4DECODER_MPEG4_DecoderConfigInfo* pDecConfInfo; 1244 1245 LOGV("VideoEditorVideoDecoder_getOption begin"); 1246 1247 switch (optionId) { 1248 case M4DECODER_kOptionID_AVCLastDecodedFrameCTS: 1249 plastDecodedFrameCts = (M4OSA_UInt32 *) pValue; 1250 *plastDecodedFrameCts = pDecShellContext->m_lastDecodedCTS; 1251 break; 1252 1253 case M4DECODER_kOptionID_Version: 1254 pVersionInfo = (M4_VersionInfo*)pValue; 1255 1256 pVersionInfo->m_major = VIDEOEDITOR_VIDEC_SHELL_VER_MAJOR; 1257 pVersionInfo->m_minor= VIDEOEDITOR_VIDEC_SHELL_VER_MINOR; 1258 pVersionInfo->m_revision = VIDEOEDITOR_VIDEC_SHELL_VER_REVISION; 1259 pVersionInfo->m_structSize=sizeof(M4_VersionInfo); 1260 break; 1261 1262 case M4DECODER_kOptionID_VideoSize: 1263 /** Only VPS uses this Option ID. */ 1264 pVideoSize = (M4DECODER_VideoSize*)pValue; 1265 pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyWidth, 1266 (int32_t*)(&pVideoSize->m_uiWidth)); 1267 pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyHeight, 1268 (int32_t*)(&pVideoSize->m_uiHeight)); 1269 LOGV("VideoEditorVideoDecoder_getOption : W=%d H=%d", 1270 pVideoSize->m_uiWidth, pVideoSize->m_uiHeight); 1271 break; 1272 1273 case M4DECODER_kOptionID_NextRenderedFrameCTS: 1274 /** How to get this information. SF decoder does not provide this. * 1275 ** Let us provide last decoded frame CTS as of now. * 1276 ** Only VPS uses this Option ID. */ 1277 pNextFrameCts = (M4OSA_UInt32 *)pValue; 1278 *pNextFrameCts = pDecShellContext->m_lastDecodedCTS; 1279 break; 1280 case M4DECODER_MPEG4_kOptionID_DecoderConfigInfo: 1281 if(pDecShellContext->mDecoderType == VIDEOEDITOR_kMpeg4VideoDec) { 1282 (*(M4DECODER_MPEG4_DecoderConfigInfo*)pValue) = 1283 pDecShellContext->m_Dci; 1284 } 1285 break; 1286 default: 1287 lerr = M4ERR_BAD_OPTION_ID; 1288 break; 1289 1290 } 1291 1292 LOGV("VideoEditorVideoDecoder_getOption: end with err = 0x%x", lerr); 1293 return lerr; 1294 } 1295 1296 M4OSA_ERR VideoEditorVideoDecoder_setOption(M4OSA_Context context, 1297 M4OSA_OptionID optionId, M4OSA_DataOption pValue) { 1298 M4OSA_ERR lerr = M4NO_ERROR; 1299 VideoEditorVideoDecoder_Context *pDecShellContext = 1300 (VideoEditorVideoDecoder_Context*) context; 1301 1302 LOGV("VideoEditorVideoDecoder_setOption begin"); 1303 1304 switch (optionId) { 1305 case M4DECODER_kOptionID_OutputFilter: { 1306 M4DECODER_OutputFilter* pOutputFilter = 1307 (M4DECODER_OutputFilter*) pValue; 1308 pDecShellContext->m_pFilter = 1309 (M4VIFI_PlanConverterFunctionType*)pOutputFilter->\ 1310 m_pFilterFunction; 1311 pDecShellContext->m_pFilterUserData = 1312 pOutputFilter->m_pFilterUserData; 1313 } 1314 break; 1315 case M4DECODER_kOptionID_DeblockingFilter: 1316 break; 1317 default: 1318 lerr = M4ERR_BAD_CONTEXT; 1319 break; 1320 } 1321 1322 LOGV("VideoEditorVideoDecoder_setOption: end with err = 0x%x", lerr); 1323 return lerr; 1324 } 1325 1326 M4OSA_ERR VideoEditorVideoDecoder_decode(M4OSA_Context context, 1327 M4_MediaTime* pTime, M4OSA_Bool bJump, M4OSA_UInt32 tolerance) { 1328 M4OSA_ERR lerr = M4NO_ERROR; 1329 VideoEditorVideoDecoder_Context* pDecShellContext = 1330 (VideoEditorVideoDecoder_Context*) context; 1331 int64_t lFrameTime; 1332 MediaBuffer* pDecoderBuffer = NULL; 1333 MediaBuffer* pNextBuffer = NULL; 1334 status_t errStatus; 1335 bool needSeek = bJump; 1336 1337 LOGV("VideoEditorVideoDecoder_decode begin"); 1338 1339 if( M4OSA_TRUE == pDecShellContext->mReachedEOS ) { 1340 // Do not call read(), it could lead to a freeze 1341 LOGV("VideoEditorVideoDecoder_decode : EOS already reached"); 1342 lerr = M4WAR_NO_MORE_AU; 1343 goto VIDEOEDITOR_VideoDecode_cleanUP; 1344 } 1345 if(pDecShellContext->m_lastDecodedCTS >= *pTime) { 1346 LOGV("VideoDecoder_decode: Already decoded up to this time CTS = %lf.", 1347 pDecShellContext->m_lastDecodedCTS); 1348 goto VIDEOEDITOR_VideoDecode_cleanUP; 1349 } 1350 if(M4OSA_TRUE == bJump) { 1351 LOGV("VideoEditorVideoDecoder_decode: Jump called"); 1352 pDecShellContext->m_lastDecodedCTS = -1; 1353 pDecShellContext->m_lastRenderCts = -1; 1354 } 1355 1356 pDecShellContext->mNbInputFrames++; 1357 if (0 > pDecShellContext->mFirstInputCts){ 1358 pDecShellContext->mFirstInputCts = *pTime; 1359 } 1360 pDecShellContext->mLastInputCts = *pTime; 1361 1362 while (pDecoderBuffer == NULL || pDecShellContext->m_lastDecodedCTS + tolerance < *pTime) { 1363 LOGV("VideoEditorVideoDecoder_decode, frameCTS = %lf, DecodeUpTo = %lf", 1364 pDecShellContext->m_lastDecodedCTS, *pTime); 1365 1366 // Read the buffer from the stagefright decoder 1367 if (needSeek) { 1368 MediaSource::ReadOptions options; 1369 int64_t time_us = *pTime * 1000; 1370 options.setSeekTo(time_us, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); 1371 errStatus = pDecShellContext->mVideoDecoder->read(&pNextBuffer, &options); 1372 needSeek = false; 1373 } else { 1374 errStatus = pDecShellContext->mVideoDecoder->read(&pNextBuffer); 1375 } 1376 1377 // Handle EOS and format change 1378 if (errStatus == ERROR_END_OF_STREAM) { 1379 LOGV("End of stream reached, returning M4WAR_NO_MORE_AU "); 1380 pDecShellContext->mReachedEOS = M4OSA_TRUE; 1381 lerr = M4WAR_NO_MORE_AU; 1382 // If we decoded a buffer before EOS, we still need to put it 1383 // into the queue. 1384 if (pDecoderBuffer && bJump) { 1385 copyBufferToQueue(pDecShellContext, pDecoderBuffer); 1386 } 1387 goto VIDEOEDITOR_VideoDecode_cleanUP; 1388 } else if (INFO_FORMAT_CHANGED == errStatus) { 1389 LOGV("VideoDecoder_decode : source returns INFO_FORMAT_CHANGED"); 1390 lerr = VideoEditorVideoDecoder_configureFromMetadata( 1391 pDecShellContext, 1392 pDecShellContext->mVideoDecoder->getFormat().get()); 1393 if( M4NO_ERROR != lerr ) { 1394 LOGV("!!! VideoEditorVideoDecoder_decode ERROR : " 1395 "VideoDecoder_configureFromMetadata returns 0x%X", lerr); 1396 break; 1397 } 1398 continue; 1399 } 1400 1401 // The OMXCodec client should expect to receive 0-length buffers 1402 // and drop the 0-length buffers. 1403 if (pNextBuffer->range_length() == 0) { 1404 pNextBuffer->release(); 1405 continue; 1406 } 1407 1408 // Now we have a good next buffer, release the previous one. 1409 if (pDecoderBuffer != NULL) { 1410 pDecoderBuffer->release(); 1411 pDecoderBuffer = NULL; 1412 } 1413 pDecoderBuffer = pNextBuffer; 1414 1415 // Record the timestamp of last decoded buffer 1416 pDecoderBuffer->meta_data()->findInt64(kKeyTime, &lFrameTime); 1417 pDecShellContext->m_lastDecodedCTS = (M4_MediaTime)(lFrameTime/1000); 1418 LOGV("VideoEditorVideoDecoder_decode,decoded frametime = %lf,size = %d", 1419 (M4_MediaTime)lFrameTime, pDecoderBuffer->size() ); 1420 1421 // If bJump is false, we need to save every decoded buffer 1422 if (!bJump) { 1423 lerr = copyBufferToQueue(pDecShellContext, pDecoderBuffer); 1424 if (lerr != M4NO_ERROR) { 1425 goto VIDEOEDITOR_VideoDecode_cleanUP; 1426 } 1427 } 1428 } 1429 1430 // If bJump is true, we only need to copy the last buffer 1431 if (bJump) { 1432 lerr = copyBufferToQueue(pDecShellContext, pDecoderBuffer); 1433 if (lerr != M4NO_ERROR) { 1434 goto VIDEOEDITOR_VideoDecode_cleanUP; 1435 } 1436 } 1437 1438 pDecShellContext->mNbOutputFrames++; 1439 if ( 0 > pDecShellContext->mFirstOutputCts ) { 1440 pDecShellContext->mFirstOutputCts = *pTime; 1441 } 1442 pDecShellContext->mLastOutputCts = *pTime; 1443 1444 VIDEOEDITOR_VideoDecode_cleanUP: 1445 *pTime = pDecShellContext->m_lastDecodedCTS; 1446 if (pDecoderBuffer != NULL) { 1447 pDecoderBuffer->release(); 1448 pDecoderBuffer = NULL; 1449 } 1450 1451 LOGV("VideoEditorVideoDecoder_decode: end with 0x%x", lerr); 1452 return lerr; 1453 } 1454 1455 static M4OSA_ERR copyBufferToQueue( 1456 VideoEditorVideoDecoder_Context* pDecShellContext, 1457 MediaBuffer* pDecoderBuffer) { 1458 1459 M4OSA_ERR lerr = M4NO_ERROR; 1460 VIDEOEDITOR_BUFFER_Buffer* tmpDecBuffer; 1461 1462 // Get a buffer from the queue 1463 lerr = VIDEOEDITOR_BUFFER_getBuffer(pDecShellContext->m_pDecBufferPool, 1464 VIDEOEDITOR_BUFFER_kEmpty, &tmpDecBuffer); 1465 if (lerr == (M4OSA_UInt32)M4ERR_NO_BUFFER_AVAILABLE) { 1466 lerr = VIDEOEDITOR_BUFFER_getOldestBuffer( 1467 pDecShellContext->m_pDecBufferPool, 1468 VIDEOEDITOR_BUFFER_kFilled, &tmpDecBuffer); 1469 tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kEmpty; 1470 lerr = M4NO_ERROR; 1471 } 1472 1473 if (lerr != M4NO_ERROR) return lerr; 1474 1475 // Color convert or copy from the given MediaBuffer to our buffer 1476 if (pDecShellContext->mI420ColorConverter) { 1477 if (pDecShellContext->mI420ColorConverter->convertDecoderOutputToI420( 1478 (uint8_t *)pDecoderBuffer->data(),// ?? + pDecoderBuffer->range_offset(), // decoderBits 1479 pDecShellContext->mGivenWidth, // decoderWidth 1480 pDecShellContext->mGivenHeight, // decoderHeight 1481 pDecShellContext->mCropRect, // decoderRect 1482 tmpDecBuffer->pData /* dstBits */) < 0) { 1483 LOGE("convertDecoderOutputToI420 failed"); 1484 lerr = M4ERR_NOT_IMPLEMENTED; 1485 } 1486 } else if (pDecShellContext->decOuputColorFormat == OMX_COLOR_FormatYUV420Planar) { 1487 int32_t width = pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1488 int32_t height = pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1489 int32_t yPlaneSize = width * height; 1490 int32_t uvPlaneSize = width * height / 4; 1491 int32_t offsetSrc = 0; 1492 1493 if (( width == pDecShellContext->mGivenWidth ) && 1494 ( height == pDecShellContext->mGivenHeight )) 1495 { 1496 M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset(); 1497 1498 memcpy((void *)tmpDecBuffer->pData, (void *)pTmpBuff, yPlaneSize); 1499 1500 offsetSrc += pDecShellContext->mGivenWidth * pDecShellContext->mGivenHeight; 1501 memcpy((void *)((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize), 1502 (void *)(pTmpBuff + offsetSrc), uvPlaneSize); 1503 1504 offsetSrc += (pDecShellContext->mGivenWidth >> 1) * (pDecShellContext->mGivenHeight >> 1); 1505 memcpy((void *)((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize + uvPlaneSize), 1506 (void *)(pTmpBuff + offsetSrc), uvPlaneSize); 1507 } 1508 else 1509 { 1510 M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset(); 1511 M4OSA_MemAddr8 pTmpBuffDst = (M4OSA_MemAddr8)tmpDecBuffer->pData; 1512 int32_t index; 1513 1514 for ( index = 0; index < height; index++) 1515 { 1516 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width); 1517 pTmpBuffDst += width; 1518 pTmpBuff += pDecShellContext->mGivenWidth; 1519 } 1520 1521 pTmpBuff += (pDecShellContext->mGivenWidth * ( pDecShellContext->mGivenHeight - height)); 1522 for ( index = 0; index < height >> 1; index++) 1523 { 1524 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width >> 1); 1525 pTmpBuffDst += width >> 1; 1526 pTmpBuff += pDecShellContext->mGivenWidth >> 1; 1527 } 1528 1529 pTmpBuff += ((pDecShellContext->mGivenWidth * (pDecShellContext->mGivenHeight - height)) / 4); 1530 for ( index = 0; index < height >> 1; index++) 1531 { 1532 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width >> 1); 1533 pTmpBuffDst += width >> 1; 1534 pTmpBuff += pDecShellContext->mGivenWidth >> 1; 1535 } 1536 } 1537 } else { 1538 LOGE("VideoDecoder_decode: unexpected color format 0x%X", 1539 pDecShellContext->decOuputColorFormat); 1540 lerr = M4ERR_PARAMETER; 1541 } 1542 1543 tmpDecBuffer->buffCTS = pDecShellContext->m_lastDecodedCTS; 1544 tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kFilled; 1545 tmpDecBuffer->size = pDecoderBuffer->size(); 1546 1547 return lerr; 1548 } 1549 1550 M4OSA_ERR VideoEditorVideoDecoder_render(M4OSA_Context context, 1551 M4_MediaTime* pTime, M4VIFI_ImagePlane* pOutputPlane, 1552 M4OSA_Bool bForceRender) { 1553 M4OSA_ERR err = M4NO_ERROR; 1554 VideoEditorVideoDecoder_Context* pDecShellContext = 1555 (VideoEditorVideoDecoder_Context*) context; 1556 M4OSA_UInt32 lindex, i; 1557 M4OSA_UInt8* p_buf_src, *p_buf_dest; 1558 M4VIFI_ImagePlane tmpPlaneIn, tmpPlaneOut; 1559 VIDEOEDITOR_BUFFER_Buffer* pTmpVIDEOEDITORBuffer, *pRenderVIDEOEDITORBuffer 1560 = M4OSA_NULL; 1561 M4_MediaTime candidateTimeStamp = -1; 1562 M4OSA_Bool bFound = M4OSA_FALSE; 1563 1564 LOGV("VideoEditorVideoDecoder_render begin"); 1565 // Input parameters check 1566 VIDEOEDITOR_CHECK(M4OSA_NULL != context, M4ERR_PARAMETER); 1567 VIDEOEDITOR_CHECK(M4OSA_NULL != pTime, M4ERR_PARAMETER); 1568 VIDEOEDITOR_CHECK(M4OSA_NULL != pOutputPlane, M4ERR_PARAMETER); 1569 1570 // The output buffer is already allocated, just copy the data 1571 if ( (*pTime <= pDecShellContext->m_lastRenderCts) && 1572 (M4OSA_FALSE == bForceRender) ) { 1573 LOGV("VIDEOEDITOR_VIDEO_render Frame in the past"); 1574 err = M4WAR_VIDEORENDERER_NO_NEW_FRAME; 1575 goto cleanUp; 1576 } 1577 LOGV("VideoDecoder_render: lastRendered time = %lf,requested render time = " 1578 "%lf", pDecShellContext->m_lastRenderCts, *pTime); 1579 1580 /** 1581 * Find the buffer appropriate for rendering. */ 1582 for (i=0; i < pDecShellContext->m_pDecBufferPool->NB; i++) { 1583 pTmpVIDEOEDITORBuffer = &pDecShellContext->m_pDecBufferPool\ 1584 ->pNXPBuffer[i]; 1585 if (pTmpVIDEOEDITORBuffer->state == VIDEOEDITOR_BUFFER_kFilled) { 1586 /** Free all those buffers older than last rendered frame. */ 1587 if (pTmpVIDEOEDITORBuffer->buffCTS < pDecShellContext->\ 1588 m_lastRenderCts) { 1589 pTmpVIDEOEDITORBuffer->state = VIDEOEDITOR_BUFFER_kEmpty; 1590 } 1591 1592 /** Get the buffer with appropriate timestamp */ 1593 if ( (pTmpVIDEOEDITORBuffer->buffCTS >= pDecShellContext->\ 1594 m_lastRenderCts) && 1595 (pTmpVIDEOEDITORBuffer->buffCTS <= *pTime) && 1596 (pTmpVIDEOEDITORBuffer->buffCTS > candidateTimeStamp)) { 1597 bFound = M4OSA_TRUE; 1598 pRenderVIDEOEDITORBuffer = pTmpVIDEOEDITORBuffer; 1599 candidateTimeStamp = pTmpVIDEOEDITORBuffer->buffCTS; 1600 LOGV("VideoDecoder_render: found a buffer with timestamp = %lf", 1601 candidateTimeStamp); 1602 } 1603 } 1604 } 1605 if (M4OSA_FALSE == bFound) { 1606 err = M4WAR_VIDEORENDERER_NO_NEW_FRAME; 1607 goto cleanUp; 1608 } 1609 1610 LOGV("VideoEditorVideoDecoder_render 3 ouput %d %d %d %d", 1611 pOutputPlane[0].u_width, pOutputPlane[0].u_height, 1612 pOutputPlane[0].u_topleft, pOutputPlane[0].u_stride); 1613 1614 pDecShellContext->m_lastRenderCts = candidateTimeStamp; 1615 1616 if( M4OSA_NULL != pDecShellContext->m_pFilter ) { 1617 // Filtering was requested 1618 M4VIFI_ImagePlane tmpPlane[3]; 1619 // Prepare the output image for conversion 1620 tmpPlane[0].u_width = 1621 pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1622 tmpPlane[0].u_height = 1623 pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1624 tmpPlane[0].u_topleft = 0; 1625 tmpPlane[0].u_stride = tmpPlane[0].u_width; 1626 tmpPlane[0].pac_data = (M4VIFI_UInt8*)pRenderVIDEOEDITORBuffer->pData; 1627 tmpPlane[1].u_width = tmpPlane[0].u_width/2; 1628 tmpPlane[1].u_height = tmpPlane[0].u_height/2; 1629 tmpPlane[1].u_topleft = 0; 1630 tmpPlane[1].u_stride = tmpPlane[0].u_stride/2; 1631 tmpPlane[1].pac_data = tmpPlane[0].pac_data + 1632 (tmpPlane[0].u_stride * tmpPlane[0].u_height); 1633 tmpPlane[2].u_width = tmpPlane[1].u_width; 1634 tmpPlane[2].u_height = tmpPlane[1].u_height; 1635 tmpPlane[2].u_topleft = 0; 1636 tmpPlane[2].u_stride = tmpPlane[1].u_stride; 1637 tmpPlane[2].pac_data = tmpPlane[1].pac_data + 1638 (tmpPlane[1].u_stride * tmpPlane[1].u_height); 1639 1640 LOGV("VideoEditorVideoDecoder_render w = %d H = %d", 1641 tmpPlane[0].u_width,tmpPlane[0].u_height); 1642 pDecShellContext->m_pFilter(M4OSA_NULL, &tmpPlane[0], pOutputPlane); 1643 } else { 1644 // Just copy the YUV420P buffer 1645 M4OSA_MemAddr8 tempBuffPtr = 1646 (M4OSA_MemAddr8)pRenderVIDEOEDITORBuffer->pData; 1647 M4OSA_UInt32 tempWidth = 1648 pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1649 M4OSA_UInt32 tempHeight = 1650 pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1651 1652 memcpy((void *) pOutputPlane[0].pac_data, (void *)tempBuffPtr, 1653 tempWidth * tempHeight); 1654 tempBuffPtr += (tempWidth * tempHeight); 1655 memcpy((void *) pOutputPlane[1].pac_data, (void *)tempBuffPtr, 1656 (tempWidth/2) * (tempHeight/2)); 1657 tempBuffPtr += ((tempWidth/2) * (tempHeight/2)); 1658 memcpy((void *) pOutputPlane[2].pac_data, (void *)tempBuffPtr, 1659 (tempWidth/2) * (tempHeight/2)); 1660 } 1661 1662 pDecShellContext->mNbRenderedFrames++; 1663 if ( 0 > pDecShellContext->mFirstRenderedCts ) { 1664 pDecShellContext->mFirstRenderedCts = *pTime; 1665 } 1666 pDecShellContext->mLastRenderedCts = *pTime; 1667 1668 cleanUp: 1669 if( M4NO_ERROR == err ) { 1670 *pTime = pDecShellContext->m_lastRenderCts; 1671 LOGV("VideoEditorVideoDecoder_render no error"); 1672 } else { 1673 LOGV("VideoEditorVideoDecoder_render ERROR 0x%X", err); 1674 } 1675 LOGV("VideoEditorVideoDecoder_render end"); 1676 return err; 1677 } 1678 1679 M4OSA_ERR VideoEditorVideoDecoder_getInterface(M4DECODER_VideoType decoderType, 1680 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1681 M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL; 1682 1683 pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc( 1684 sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL, 1685 (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" ); 1686 if (M4OSA_NULL == pDecoderInterface) { 1687 return M4ERR_ALLOC; 1688 } 1689 1690 *pDecoderType = decoderType; 1691 1692 pDecoderInterface->m_pFctCreate = VideoEditorVideoDecoder_create; 1693 pDecoderInterface->m_pFctDestroy = VideoEditorVideoDecoder_destroy; 1694 pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption; 1695 pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption; 1696 pDecoderInterface->m_pFctDecode = VideoEditorVideoDecoder_decode; 1697 pDecoderInterface->m_pFctRender = VideoEditorVideoDecoder_render; 1698 1699 *pDecInterface = (M4OSA_Context)pDecoderInterface; 1700 return M4NO_ERROR; 1701 } 1702 1703 M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_VideoType decoderType, 1704 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1705 M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL; 1706 1707 pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc( 1708 sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL, 1709 (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" ); 1710 if (M4OSA_NULL == pDecoderInterface) { 1711 return M4ERR_ALLOC; 1712 } 1713 1714 *pDecoderType = decoderType; 1715 1716 pDecoderInterface->m_pFctCreate = VideoEditorVideoSoftwareDecoder_create; 1717 pDecoderInterface->m_pFctDestroy = VideoEditorVideoDecoder_destroy; 1718 pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption; 1719 pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption; 1720 pDecoderInterface->m_pFctDecode = VideoEditorVideoDecoder_decode; 1721 pDecoderInterface->m_pFctRender = VideoEditorVideoDecoder_render; 1722 1723 *pDecInterface = (M4OSA_Context)pDecoderInterface; 1724 return M4NO_ERROR; 1725 } 1726 extern "C" { 1727 1728 M4OSA_ERR VideoEditorVideoDecoder_getInterface_MPEG4( 1729 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1730 return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeMPEG4, 1731 pDecoderType, pDecInterface); 1732 } 1733 1734 M4OSA_ERR VideoEditorVideoDecoder_getInterface_H264( 1735 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1736 return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeAVC, 1737 pDecoderType, pDecInterface); 1738 1739 } 1740 1741 M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface_MPEG4( 1742 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1743 return VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_kVideoTypeMPEG4, 1744 pDecoderType, pDecInterface); 1745 } 1746 1747 M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface_H264( 1748 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1749 return VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_kVideoTypeAVC, 1750 pDecoderType, pDecInterface); 1751 1752 } 1753 1754 M4OSA_ERR VideoEditorVideoDecoder_getVideoDecodersAndCapabilities( 1755 M4DECODER_VideoDecoders** decoders) { 1756 return queryVideoDecoderCapabilities(decoders); 1757 } 1758 1759 } // extern "C" 1760