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/foundation/ADebug.h> 33 #include <media/stagefright/MetaData.h> 34 #include <media/stagefright/MediaDefs.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 ALOGE("Could not find kKeyMaxInputSize"); 104 return ERROR_MALFORMED; 105 } 106 107 mGroup = new MediaBufferGroup; 108 if (mGroup == NULL) { 109 ALOGE("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 ALOGV("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 ALOGE("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 ALOGE("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 ALOGE("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 ALOGV("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 ALOGV("-->component %d", j); 650 for(size_t k = 0; k < pOmxComponents->profileNumber; k++) { 651 ALOGV("-->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 ALOGV("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 ALOGV(" decoder '%s' supports ", 701 results[i].mComponentName.string()); 702 703 if (results[i].mProfileLevels.size() == 0) { 704 ALOGV("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 ALOGV("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 ALOGV("%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 ALOGV("%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 ALOGV("%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 ALOGV("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 ALOGV("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 ALOGV("got dimensions only %d x %d", width, height); 823 } else { 824 ALOGV("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 ALOGV("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 ALOGV("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 ALOGV("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 ALOGV("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 ALOGV("VideoEditorVideoDecoder_configureFromMetadata ERROR 0x%X", err); 876 } 877 ALOGV("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 ALOGV("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 ALOGV("### 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 ALOGV("VideoEditorVideoDecoder_destroy no error"); 913 } else { 914 ALOGV("VideoEditorVideoDecoder_destroy ERROR 0x%X", err); 915 } 916 ALOGV("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 ALOGV("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 // Calculate the interval between two video frames. 986 CHECK(pDecShellContext->m_pVideoStreamhandler->m_averageFrameRate > 0); 987 pDecShellContext->mFrameIntervalMs = 988 1000.0 / pDecShellContext->m_pVideoStreamhandler->m_averageFrameRate; 989 990 /** 991 * StageFright graph building 992 */ 993 decoderMetadata = new MetaData; 994 switch( pDecShellContext->mDecoderType ) { 995 case VIDEOEDITOR_kH263VideoDec: 996 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 997 break; 998 case VIDEOEDITOR_kMpeg4VideoDec: 999 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 1000 decoderMetadata->setData(kKeyESDS, kTypeESDS, 1001 pStreamHandler->m_pESDSInfo, 1002 pStreamHandler->m_ESDSInfoSize); 1003 break; 1004 case VIDEOEDITOR_kH264VideoDec: 1005 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 1006 decoderMetadata->setData(kKeyAVCC, kTypeAVCC, 1007 pStreamHandler->m_pH264DecoderSpecificInfo, 1008 pStreamHandler->m_H264decoderSpecificInfoSize); 1009 break; 1010 default: 1011 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 1012 M4ERR_PARAMETER); 1013 break; 1014 } 1015 1016 decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize); 1017 decoderMetadata->setInt32(kKeyWidth, 1018 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 1019 decoderMetadata->setInt32(kKeyHeight, 1020 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1021 1022 // Create the decoder source 1023 pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource( 1024 decoderMetadata, pDecShellContext->mDecoderType, 1025 (void *)pDecShellContext); 1026 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(), 1027 M4ERR_SF_DECODER_RSRC_FAIL); 1028 1029 // Connect to the OMX client 1030 status = pDecShellContext->mClient.connect(); 1031 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 1032 1033 // Create the decoder 1034 pDecShellContext->mVideoDecoder = OMXCodec::Create( 1035 pDecShellContext->mClient.interface(), 1036 decoderMetadata, false, pDecShellContext->mReaderSource); 1037 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(), 1038 M4ERR_SF_DECODER_RSRC_FAIL); 1039 1040 1041 // Get the output color format 1042 success = pDecShellContext->mVideoDecoder->getFormat()->findInt32( 1043 kKeyColorFormat, &colorFormat); 1044 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 1045 pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; 1046 1047 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth, 1048 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 1049 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight, 1050 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1051 1052 // Get the color converter 1053 pDecShellContext->mI420ColorConverter = new I420ColorConverter; 1054 if (pDecShellContext->mI420ColorConverter->isLoaded()) { 1055 decoderOutput = pDecShellContext->mI420ColorConverter->getDecoderOutputFormat(); 1056 } 1057 1058 if (decoderOutput == OMX_COLOR_FormatYUV420Planar) { 1059 delete pDecShellContext->mI420ColorConverter; 1060 pDecShellContext->mI420ColorConverter = NULL; 1061 } 1062 1063 ALOGI("decoder output format = 0x%X\n", decoderOutput); 1064 1065 // Configure the buffer pool from the metadata 1066 err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext, 1067 pDecShellContext->mVideoDecoder->getFormat().get()); 1068 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 1069 1070 // Start the graph 1071 status = pDecShellContext->mVideoDecoder->start(); 1072 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 1073 1074 *pContext = (M4OSA_Context)pDecShellContext; 1075 1076 cleanUp: 1077 if( M4NO_ERROR == err ) { 1078 ALOGV("VideoEditorVideoDecoder_create no error"); 1079 } else { 1080 VideoEditorVideoDecoder_destroy(pDecShellContext); 1081 *pContext = M4OSA_NULL; 1082 ALOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err); 1083 } 1084 ALOGV("VideoEditorVideoDecoder_create : DONE"); 1085 return err; 1086 } 1087 1088 M4OSA_ERR VideoEditorVideoSoftwareDecoder_create(M4OSA_Context *pContext, 1089 M4_StreamHandler *pStreamHandler, 1090 M4READER_GlobalInterface *pReaderGlobalInterface, 1091 M4READER_DataInterface *pReaderDataInterface, 1092 M4_AccessUnit *pAccessUnit, M4OSA_Void *pUserData) { 1093 M4OSA_ERR err = M4NO_ERROR; 1094 VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL; 1095 status_t status = OK; 1096 bool success = TRUE; 1097 int32_t colorFormat = 0; 1098 M4OSA_UInt32 size = 0; 1099 sp<MetaData> decoderMetadata = NULL; 1100 1101 ALOGV("VideoEditorVideoDecoder_create begin"); 1102 // Input parameters check 1103 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 1104 VIDEOEDITOR_CHECK(M4OSA_NULL != pStreamHandler, M4ERR_PARAMETER); 1105 VIDEOEDITOR_CHECK(M4OSA_NULL != pReaderDataInterface, M4ERR_PARAMETER); 1106 1107 // Context allocation & initialization 1108 SAFE_MALLOC(pDecShellContext, VideoEditorVideoDecoder_Context, 1, 1109 "VideoEditorVideoDecoder"); 1110 pDecShellContext->m_pVideoStreamhandler = 1111 (M4_VideoStreamHandler*)pStreamHandler; 1112 pDecShellContext->m_pNextAccessUnitToDecode = pAccessUnit; 1113 pDecShellContext->m_pReaderGlobal = pReaderGlobalInterface; 1114 pDecShellContext->m_pReader = pReaderDataInterface; 1115 pDecShellContext->m_lastDecodedCTS = -1; 1116 pDecShellContext->m_lastRenderCts = -1; 1117 switch( pStreamHandler->m_streamType ) { 1118 case M4DA_StreamTypeVideoH263: 1119 pDecShellContext->mDecoderType = VIDEOEDITOR_kH263VideoDec; 1120 break; 1121 case M4DA_StreamTypeVideoMpeg4: 1122 pDecShellContext->mDecoderType = VIDEOEDITOR_kMpeg4VideoDec; 1123 // Parse the VOL header 1124 err = VideoEditorVideoDecoder_internalParseVideoDSI( 1125 (M4OSA_UInt8*)pDecShellContext->m_pVideoStreamhandler->\ 1126 m_basicProperties.m_pDecoderSpecificInfo, 1127 pDecShellContext->m_pVideoStreamhandler->\ 1128 m_basicProperties.m_decoderSpecificInfoSize, 1129 &pDecShellContext->m_Dci, &pDecShellContext->m_VideoSize); 1130 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 1131 break; 1132 case M4DA_StreamTypeVideoMpeg4Avc: 1133 pDecShellContext->mDecoderType = VIDEOEDITOR_kH264VideoDec; 1134 break; 1135 default: 1136 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 1137 M4ERR_PARAMETER); 1138 break; 1139 } 1140 1141 pDecShellContext->mNbInputFrames = 0; 1142 pDecShellContext->mFirstInputCts = -1.0; 1143 pDecShellContext->mLastInputCts = -1.0; 1144 pDecShellContext->mNbRenderedFrames = 0; 1145 pDecShellContext->mFirstRenderedCts = -1.0; 1146 pDecShellContext->mLastRenderedCts = -1.0; 1147 pDecShellContext->mNbOutputFrames = 0; 1148 pDecShellContext->mFirstOutputCts = -1; 1149 pDecShellContext->mLastOutputCts = -1; 1150 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 1151 1152 // Calculate the interval between two video frames. 1153 if(pDecShellContext->m_pVideoStreamhandler->m_averageFrameRate > 0){ 1154 pDecShellContext->mFrameIntervalMs = 1155 1000.0 / pDecShellContext->m_pVideoStreamhandler->m_averageFrameRate; 1156 } 1157 1158 /** 1159 * StageFright graph building 1160 */ 1161 decoderMetadata = new MetaData; 1162 switch( pDecShellContext->mDecoderType ) { 1163 case VIDEOEDITOR_kH263VideoDec: 1164 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 1165 break; 1166 case VIDEOEDITOR_kMpeg4VideoDec: 1167 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 1168 decoderMetadata->setData(kKeyESDS, kTypeESDS, 1169 pStreamHandler->m_pESDSInfo, 1170 pStreamHandler->m_ESDSInfoSize); 1171 break; 1172 case VIDEOEDITOR_kH264VideoDec: 1173 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 1174 decoderMetadata->setData(kKeyAVCC, kTypeAVCC, 1175 pStreamHandler->m_pH264DecoderSpecificInfo, 1176 pStreamHandler->m_H264decoderSpecificInfoSize); 1177 break; 1178 default: 1179 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 1180 M4ERR_PARAMETER); 1181 break; 1182 } 1183 1184 decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize); 1185 decoderMetadata->setInt32(kKeyWidth, 1186 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 1187 decoderMetadata->setInt32(kKeyHeight, 1188 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1189 1190 // Create the decoder source 1191 pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource( 1192 decoderMetadata, pDecShellContext->mDecoderType, 1193 (void *)pDecShellContext); 1194 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(), 1195 M4ERR_SF_DECODER_RSRC_FAIL); 1196 1197 // Connect to the OMX client 1198 status = pDecShellContext->mClient.connect(); 1199 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 1200 1201 ALOGI("Using software codecs only"); 1202 // Create the decoder 1203 pDecShellContext->mVideoDecoder = OMXCodec::Create( 1204 pDecShellContext->mClient.interface(), 1205 decoderMetadata, false, pDecShellContext->mReaderSource,NULL,OMXCodec::kSoftwareCodecsOnly); 1206 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(), 1207 M4ERR_SF_DECODER_RSRC_FAIL); 1208 1209 // Get the output color format 1210 success = pDecShellContext->mVideoDecoder->getFormat()->findInt32( 1211 kKeyColorFormat, &colorFormat); 1212 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 1213 pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; 1214 1215 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth, 1216 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 1217 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight, 1218 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1219 1220 // Configure the buffer pool from the metadata 1221 err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext, 1222 pDecShellContext->mVideoDecoder->getFormat().get()); 1223 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 1224 1225 // Start the graph 1226 status = pDecShellContext->mVideoDecoder->start(); 1227 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 1228 1229 *pContext = (M4OSA_Context)pDecShellContext; 1230 1231 cleanUp: 1232 if( M4NO_ERROR == err ) { 1233 ALOGV("VideoEditorVideoDecoder_create no error"); 1234 } else { 1235 VideoEditorVideoDecoder_destroy(pDecShellContext); 1236 *pContext = M4OSA_NULL; 1237 ALOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err); 1238 } 1239 ALOGV("VideoEditorVideoDecoder_create : DONE"); 1240 return err; 1241 } 1242 1243 1244 M4OSA_ERR VideoEditorVideoDecoder_getOption(M4OSA_Context context, 1245 M4OSA_OptionID optionId, M4OSA_DataOption pValue) { 1246 M4OSA_ERR lerr = M4NO_ERROR; 1247 VideoEditorVideoDecoder_Context* pDecShellContext = 1248 (VideoEditorVideoDecoder_Context*) context; 1249 M4_VersionInfo* pVersionInfo; 1250 M4DECODER_VideoSize* pVideoSize; 1251 M4OSA_UInt32* pNextFrameCts; 1252 M4OSA_UInt32 *plastDecodedFrameCts; 1253 M4DECODER_AVCProfileLevel* profile; 1254 M4DECODER_MPEG4_DecoderConfigInfo* pDecConfInfo; 1255 1256 ALOGV("VideoEditorVideoDecoder_getOption begin"); 1257 1258 switch (optionId) { 1259 case M4DECODER_kOptionID_AVCLastDecodedFrameCTS: 1260 plastDecodedFrameCts = (M4OSA_UInt32 *) pValue; 1261 *plastDecodedFrameCts = pDecShellContext->m_lastDecodedCTS; 1262 break; 1263 1264 case M4DECODER_kOptionID_Version: 1265 pVersionInfo = (M4_VersionInfo*)pValue; 1266 1267 pVersionInfo->m_major = VIDEOEDITOR_VIDEC_SHELL_VER_MAJOR; 1268 pVersionInfo->m_minor= VIDEOEDITOR_VIDEC_SHELL_VER_MINOR; 1269 pVersionInfo->m_revision = VIDEOEDITOR_VIDEC_SHELL_VER_REVISION; 1270 pVersionInfo->m_structSize=sizeof(M4_VersionInfo); 1271 break; 1272 1273 case M4DECODER_kOptionID_VideoSize: 1274 /** Only VPS uses this Option ID. */ 1275 pVideoSize = (M4DECODER_VideoSize*)pValue; 1276 pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyWidth, 1277 (int32_t*)(&pVideoSize->m_uiWidth)); 1278 pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyHeight, 1279 (int32_t*)(&pVideoSize->m_uiHeight)); 1280 ALOGV("VideoEditorVideoDecoder_getOption : W=%d H=%d", 1281 pVideoSize->m_uiWidth, pVideoSize->m_uiHeight); 1282 break; 1283 1284 case M4DECODER_kOptionID_NextRenderedFrameCTS: 1285 /** How to get this information. SF decoder does not provide this. * 1286 ** Let us provide last decoded frame CTS as of now. * 1287 ** Only VPS uses this Option ID. */ 1288 pNextFrameCts = (M4OSA_UInt32 *)pValue; 1289 *pNextFrameCts = pDecShellContext->m_lastDecodedCTS; 1290 break; 1291 case M4DECODER_MPEG4_kOptionID_DecoderConfigInfo: 1292 if(pDecShellContext->mDecoderType == VIDEOEDITOR_kMpeg4VideoDec) { 1293 (*(M4DECODER_MPEG4_DecoderConfigInfo*)pValue) = 1294 pDecShellContext->m_Dci; 1295 } 1296 break; 1297 default: 1298 lerr = M4ERR_BAD_OPTION_ID; 1299 break; 1300 1301 } 1302 1303 ALOGV("VideoEditorVideoDecoder_getOption: end with err = 0x%x", lerr); 1304 return lerr; 1305 } 1306 1307 M4OSA_ERR VideoEditorVideoDecoder_setOption(M4OSA_Context context, 1308 M4OSA_OptionID optionId, M4OSA_DataOption pValue) { 1309 M4OSA_ERR lerr = M4NO_ERROR; 1310 VideoEditorVideoDecoder_Context *pDecShellContext = 1311 (VideoEditorVideoDecoder_Context*) context; 1312 1313 ALOGV("VideoEditorVideoDecoder_setOption begin"); 1314 1315 switch (optionId) { 1316 case M4DECODER_kOptionID_OutputFilter: { 1317 M4DECODER_OutputFilter* pOutputFilter = 1318 (M4DECODER_OutputFilter*) pValue; 1319 pDecShellContext->m_pFilter = 1320 (M4VIFI_PlanConverterFunctionType*)pOutputFilter->\ 1321 m_pFilterFunction; 1322 pDecShellContext->m_pFilterUserData = 1323 pOutputFilter->m_pFilterUserData; 1324 } 1325 break; 1326 case M4DECODER_kOptionID_DeblockingFilter: 1327 break; 1328 default: 1329 lerr = M4ERR_BAD_CONTEXT; 1330 break; 1331 } 1332 1333 ALOGV("VideoEditorVideoDecoder_setOption: end with err = 0x%x", lerr); 1334 return lerr; 1335 } 1336 1337 M4OSA_ERR VideoEditorVideoDecoder_decode(M4OSA_Context context, 1338 M4_MediaTime* pTime, M4OSA_Bool bJump, M4OSA_UInt32 tolerance) { 1339 M4OSA_ERR lerr = M4NO_ERROR; 1340 VideoEditorVideoDecoder_Context* pDecShellContext = 1341 (VideoEditorVideoDecoder_Context*) context; 1342 int64_t lFrameTime; 1343 MediaBuffer* pDecoderBuffer = NULL; 1344 MediaBuffer* pNextBuffer = NULL; 1345 status_t errStatus; 1346 bool needSeek = bJump; 1347 1348 ALOGV("VideoEditorVideoDecoder_decode begin"); 1349 1350 if( M4OSA_TRUE == pDecShellContext->mReachedEOS ) { 1351 // Do not call read(), it could lead to a freeze 1352 ALOGV("VideoEditorVideoDecoder_decode : EOS already reached"); 1353 lerr = M4WAR_NO_MORE_AU; 1354 goto VIDEOEDITOR_VideoDecode_cleanUP; 1355 } 1356 if(pDecShellContext->m_lastDecodedCTS >= *pTime) { 1357 ALOGV("VideoDecoder_decode: Already decoded up to this time CTS = %lf.", 1358 pDecShellContext->m_lastDecodedCTS); 1359 goto VIDEOEDITOR_VideoDecode_cleanUP; 1360 } 1361 if(M4OSA_TRUE == bJump) { 1362 ALOGV("VideoEditorVideoDecoder_decode: Jump called"); 1363 pDecShellContext->m_lastDecodedCTS = -1; 1364 pDecShellContext->m_lastRenderCts = -1; 1365 } 1366 1367 pDecShellContext->mNbInputFrames++; 1368 if (0 > pDecShellContext->mFirstInputCts){ 1369 pDecShellContext->mFirstInputCts = *pTime; 1370 } 1371 pDecShellContext->mLastInputCts = *pTime; 1372 1373 while (pDecoderBuffer == NULL || pDecShellContext->m_lastDecodedCTS + tolerance < *pTime) { 1374 ALOGV("VideoEditorVideoDecoder_decode, frameCTS = %lf, DecodeUpTo = %lf", 1375 pDecShellContext->m_lastDecodedCTS, *pTime); 1376 1377 // Read the buffer from the stagefright decoder 1378 if (needSeek) { 1379 MediaSource::ReadOptions options; 1380 int64_t time_us = *pTime * 1000; 1381 options.setSeekTo(time_us, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); 1382 errStatus = pDecShellContext->mVideoDecoder->read(&pNextBuffer, &options); 1383 needSeek = false; 1384 } else { 1385 errStatus = pDecShellContext->mVideoDecoder->read(&pNextBuffer); 1386 } 1387 1388 // Handle EOS and format change 1389 if (errStatus == ERROR_END_OF_STREAM) { 1390 ALOGV("End of stream reached, returning M4WAR_NO_MORE_AU "); 1391 pDecShellContext->mReachedEOS = M4OSA_TRUE; 1392 lerr = M4WAR_NO_MORE_AU; 1393 // If we decoded a buffer before EOS, we still need to put it 1394 // into the queue. 1395 if (pDecoderBuffer && bJump) { 1396 copyBufferToQueue(pDecShellContext, pDecoderBuffer); 1397 } 1398 goto VIDEOEDITOR_VideoDecode_cleanUP; 1399 } else if (INFO_FORMAT_CHANGED == errStatus) { 1400 ALOGV("VideoDecoder_decode : source returns INFO_FORMAT_CHANGED"); 1401 lerr = VideoEditorVideoDecoder_configureFromMetadata( 1402 pDecShellContext, 1403 pDecShellContext->mVideoDecoder->getFormat().get()); 1404 if( M4NO_ERROR != lerr ) { 1405 ALOGV("!!! VideoEditorVideoDecoder_decode ERROR : " 1406 "VideoDecoder_configureFromMetadata returns 0x%X", lerr); 1407 break; 1408 } 1409 continue; 1410 } else if (errStatus != OK) { 1411 ALOGE("VideoEditorVideoDecoder_decode ERROR:0x%x(%d)", 1412 errStatus,errStatus); 1413 lerr = errStatus; 1414 goto VIDEOEDITOR_VideoDecode_cleanUP; 1415 } 1416 1417 // The OMXCodec client should expect to receive 0-length buffers 1418 // and drop the 0-length buffers. 1419 if (pNextBuffer->range_length() == 0) { 1420 pNextBuffer->release(); 1421 continue; 1422 } 1423 1424 // Now we have a good next buffer, release the previous one. 1425 if (pDecoderBuffer != NULL) { 1426 pDecoderBuffer->release(); 1427 pDecoderBuffer = NULL; 1428 } 1429 pDecoderBuffer = pNextBuffer; 1430 1431 // Record the timestamp of last decoded buffer 1432 pDecoderBuffer->meta_data()->findInt64(kKeyTime, &lFrameTime); 1433 pDecShellContext->m_lastDecodedCTS = (M4_MediaTime)(lFrameTime/1000); 1434 ALOGV("VideoEditorVideoDecoder_decode,decoded frametime = %lf,size = %d", 1435 (M4_MediaTime)lFrameTime, pDecoderBuffer->size() ); 1436 1437 /* 1438 * We need to save a buffer if bJump == false to a queue. These 1439 * buffers have a timestamp >= the target time, *pTime (for instance, 1440 * the transition between two videos, or a trimming postion inside 1441 * one video), since they are part of the transition clip or the 1442 * trimmed video. 1443 * 1444 * If *pTime does not have the same value as any of the existing 1445 * video frames, we would like to get the buffer right before *pTime 1446 * and in the transcoding phrase, this video frame will be encoded 1447 * as a key frame and becomes the first video frame for the transition or the 1448 * trimmed video to be generated. This buffer must also be queued. 1449 * 1450 */ 1451 int64_t targetTimeMs = 1452 pDecShellContext->m_lastDecodedCTS + 1453 pDecShellContext->mFrameIntervalMs + 1454 tolerance; 1455 if (!bJump || targetTimeMs > *pTime) { 1456 lerr = copyBufferToQueue(pDecShellContext, pDecoderBuffer); 1457 if (lerr != M4NO_ERROR) { 1458 goto VIDEOEDITOR_VideoDecode_cleanUP; 1459 } 1460 } 1461 } 1462 1463 pDecShellContext->mNbOutputFrames++; 1464 if ( 0 > pDecShellContext->mFirstOutputCts ) { 1465 pDecShellContext->mFirstOutputCts = *pTime; 1466 } 1467 pDecShellContext->mLastOutputCts = *pTime; 1468 1469 VIDEOEDITOR_VideoDecode_cleanUP: 1470 *pTime = pDecShellContext->m_lastDecodedCTS; 1471 if (pDecoderBuffer != NULL) { 1472 pDecoderBuffer->release(); 1473 pDecoderBuffer = NULL; 1474 } 1475 1476 ALOGV("VideoEditorVideoDecoder_decode: end with 0x%x", lerr); 1477 return lerr; 1478 } 1479 1480 static M4OSA_ERR copyBufferToQueue( 1481 VideoEditorVideoDecoder_Context* pDecShellContext, 1482 MediaBuffer* pDecoderBuffer) { 1483 1484 M4OSA_ERR lerr = M4NO_ERROR; 1485 VIDEOEDITOR_BUFFER_Buffer* tmpDecBuffer; 1486 1487 // Get a buffer from the queue 1488 lerr = VIDEOEDITOR_BUFFER_getBuffer(pDecShellContext->m_pDecBufferPool, 1489 VIDEOEDITOR_BUFFER_kEmpty, &tmpDecBuffer); 1490 if (lerr == (M4OSA_UInt32)M4ERR_NO_BUFFER_AVAILABLE) { 1491 lerr = VIDEOEDITOR_BUFFER_getOldestBuffer( 1492 pDecShellContext->m_pDecBufferPool, 1493 VIDEOEDITOR_BUFFER_kFilled, &tmpDecBuffer); 1494 tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kEmpty; 1495 lerr = M4NO_ERROR; 1496 } 1497 1498 if (lerr != M4NO_ERROR) return lerr; 1499 1500 // Color convert or copy from the given MediaBuffer to our buffer 1501 if (pDecShellContext->mI420ColorConverter) { 1502 if (pDecShellContext->mI420ColorConverter->convertDecoderOutputToI420( 1503 (uint8_t *)pDecoderBuffer->data(),// ?? + pDecoderBuffer->range_offset(), // decoderBits 1504 pDecShellContext->mGivenWidth, // decoderWidth 1505 pDecShellContext->mGivenHeight, // decoderHeight 1506 pDecShellContext->mCropRect, // decoderRect 1507 tmpDecBuffer->pData /* dstBits */) < 0) { 1508 ALOGE("convertDecoderOutputToI420 failed"); 1509 lerr = M4ERR_NOT_IMPLEMENTED; 1510 } 1511 } else if (pDecShellContext->decOuputColorFormat == OMX_COLOR_FormatYUV420Planar) { 1512 int32_t width = pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1513 int32_t height = pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1514 int32_t yPlaneSize = width * height; 1515 int32_t uvPlaneSize = width * height / 4; 1516 int32_t offsetSrc = 0; 1517 1518 if (( width == pDecShellContext->mGivenWidth ) && 1519 ( height == pDecShellContext->mGivenHeight )) 1520 { 1521 M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset(); 1522 1523 memcpy((void *)tmpDecBuffer->pData, (void *)pTmpBuff, yPlaneSize); 1524 1525 offsetSrc += pDecShellContext->mGivenWidth * pDecShellContext->mGivenHeight; 1526 memcpy((void *)((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize), 1527 (void *)(pTmpBuff + offsetSrc), uvPlaneSize); 1528 1529 offsetSrc += (pDecShellContext->mGivenWidth >> 1) * (pDecShellContext->mGivenHeight >> 1); 1530 memcpy((void *)((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize + uvPlaneSize), 1531 (void *)(pTmpBuff + offsetSrc), uvPlaneSize); 1532 } 1533 else 1534 { 1535 M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset(); 1536 M4OSA_MemAddr8 pTmpBuffDst = (M4OSA_MemAddr8)tmpDecBuffer->pData; 1537 int32_t index; 1538 1539 for ( index = 0; index < height; index++) 1540 { 1541 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width); 1542 pTmpBuffDst += width; 1543 pTmpBuff += pDecShellContext->mGivenWidth; 1544 } 1545 1546 pTmpBuff += (pDecShellContext->mGivenWidth * ( pDecShellContext->mGivenHeight - height)); 1547 for ( index = 0; index < height >> 1; index++) 1548 { 1549 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width >> 1); 1550 pTmpBuffDst += width >> 1; 1551 pTmpBuff += pDecShellContext->mGivenWidth >> 1; 1552 } 1553 1554 pTmpBuff += ((pDecShellContext->mGivenWidth * (pDecShellContext->mGivenHeight - height)) / 4); 1555 for ( index = 0; index < height >> 1; index++) 1556 { 1557 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width >> 1); 1558 pTmpBuffDst += width >> 1; 1559 pTmpBuff += pDecShellContext->mGivenWidth >> 1; 1560 } 1561 } 1562 } else { 1563 ALOGE("VideoDecoder_decode: unexpected color format 0x%X", 1564 pDecShellContext->decOuputColorFormat); 1565 lerr = M4ERR_PARAMETER; 1566 } 1567 1568 tmpDecBuffer->buffCTS = pDecShellContext->m_lastDecodedCTS; 1569 tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kFilled; 1570 tmpDecBuffer->size = pDecoderBuffer->size(); 1571 1572 return lerr; 1573 } 1574 1575 M4OSA_ERR VideoEditorVideoDecoder_render(M4OSA_Context context, 1576 M4_MediaTime* pTime, M4VIFI_ImagePlane* pOutputPlane, 1577 M4OSA_Bool bForceRender) { 1578 M4OSA_ERR err = M4NO_ERROR; 1579 VideoEditorVideoDecoder_Context* pDecShellContext = 1580 (VideoEditorVideoDecoder_Context*) context; 1581 M4OSA_UInt32 lindex, i; 1582 M4OSA_UInt8* p_buf_src, *p_buf_dest; 1583 M4VIFI_ImagePlane tmpPlaneIn, tmpPlaneOut; 1584 VIDEOEDITOR_BUFFER_Buffer* pTmpVIDEOEDITORBuffer, *pRenderVIDEOEDITORBuffer 1585 = M4OSA_NULL; 1586 M4_MediaTime candidateTimeStamp = -1; 1587 M4OSA_Bool bFound = M4OSA_FALSE; 1588 1589 ALOGV("VideoEditorVideoDecoder_render begin"); 1590 // Input parameters check 1591 VIDEOEDITOR_CHECK(M4OSA_NULL != context, M4ERR_PARAMETER); 1592 VIDEOEDITOR_CHECK(M4OSA_NULL != pTime, M4ERR_PARAMETER); 1593 VIDEOEDITOR_CHECK(M4OSA_NULL != pOutputPlane, M4ERR_PARAMETER); 1594 1595 // The output buffer is already allocated, just copy the data 1596 if ( (*pTime <= pDecShellContext->m_lastRenderCts) && 1597 (M4OSA_FALSE == bForceRender) ) { 1598 ALOGV("VIDEOEDITOR_VIDEO_render Frame in the past"); 1599 err = M4WAR_VIDEORENDERER_NO_NEW_FRAME; 1600 goto cleanUp; 1601 } 1602 ALOGV("VideoDecoder_render: lastRendered time = %lf,requested render time = " 1603 "%lf", pDecShellContext->m_lastRenderCts, *pTime); 1604 1605 /** 1606 * Find the buffer appropriate for rendering. */ 1607 for (i=0; i < pDecShellContext->m_pDecBufferPool->NB; i++) { 1608 pTmpVIDEOEDITORBuffer = &pDecShellContext->m_pDecBufferPool\ 1609 ->pNXPBuffer[i]; 1610 if (pTmpVIDEOEDITORBuffer->state == VIDEOEDITOR_BUFFER_kFilled) { 1611 /** Free all those buffers older than last rendered frame. */ 1612 if (pTmpVIDEOEDITORBuffer->buffCTS < pDecShellContext->\ 1613 m_lastRenderCts) { 1614 pTmpVIDEOEDITORBuffer->state = VIDEOEDITOR_BUFFER_kEmpty; 1615 } 1616 1617 /** Get the buffer with appropriate timestamp */ 1618 if ( (pTmpVIDEOEDITORBuffer->buffCTS >= pDecShellContext->\ 1619 m_lastRenderCts) && 1620 (pTmpVIDEOEDITORBuffer->buffCTS <= *pTime) && 1621 (pTmpVIDEOEDITORBuffer->buffCTS > candidateTimeStamp)) { 1622 bFound = M4OSA_TRUE; 1623 pRenderVIDEOEDITORBuffer = pTmpVIDEOEDITORBuffer; 1624 candidateTimeStamp = pTmpVIDEOEDITORBuffer->buffCTS; 1625 ALOGV("VideoDecoder_render: found a buffer with timestamp = %lf", 1626 candidateTimeStamp); 1627 } 1628 } 1629 } 1630 if (M4OSA_FALSE == bFound) { 1631 err = M4WAR_VIDEORENDERER_NO_NEW_FRAME; 1632 goto cleanUp; 1633 } 1634 1635 ALOGV("VideoEditorVideoDecoder_render 3 ouput %d %d %d %d", 1636 pOutputPlane[0].u_width, pOutputPlane[0].u_height, 1637 pOutputPlane[0].u_topleft, pOutputPlane[0].u_stride); 1638 1639 pDecShellContext->m_lastRenderCts = candidateTimeStamp; 1640 1641 if( M4OSA_NULL != pDecShellContext->m_pFilter ) { 1642 // Filtering was requested 1643 M4VIFI_ImagePlane tmpPlane[3]; 1644 // Prepare the output image for conversion 1645 tmpPlane[0].u_width = 1646 pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1647 tmpPlane[0].u_height = 1648 pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1649 tmpPlane[0].u_topleft = 0; 1650 tmpPlane[0].u_stride = tmpPlane[0].u_width; 1651 tmpPlane[0].pac_data = (M4VIFI_UInt8*)pRenderVIDEOEDITORBuffer->pData; 1652 tmpPlane[1].u_width = tmpPlane[0].u_width/2; 1653 tmpPlane[1].u_height = tmpPlane[0].u_height/2; 1654 tmpPlane[1].u_topleft = 0; 1655 tmpPlane[1].u_stride = tmpPlane[0].u_stride/2; 1656 tmpPlane[1].pac_data = tmpPlane[0].pac_data + 1657 (tmpPlane[0].u_stride * tmpPlane[0].u_height); 1658 tmpPlane[2].u_width = tmpPlane[1].u_width; 1659 tmpPlane[2].u_height = tmpPlane[1].u_height; 1660 tmpPlane[2].u_topleft = 0; 1661 tmpPlane[2].u_stride = tmpPlane[1].u_stride; 1662 tmpPlane[2].pac_data = tmpPlane[1].pac_data + 1663 (tmpPlane[1].u_stride * tmpPlane[1].u_height); 1664 1665 ALOGV("VideoEditorVideoDecoder_render w = %d H = %d", 1666 tmpPlane[0].u_width,tmpPlane[0].u_height); 1667 pDecShellContext->m_pFilter(M4OSA_NULL, &tmpPlane[0], pOutputPlane); 1668 } else { 1669 // Just copy the YUV420P buffer 1670 M4OSA_MemAddr8 tempBuffPtr = 1671 (M4OSA_MemAddr8)pRenderVIDEOEDITORBuffer->pData; 1672 M4OSA_UInt32 tempWidth = 1673 pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1674 M4OSA_UInt32 tempHeight = 1675 pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1676 1677 memcpy((void *) pOutputPlane[0].pac_data, (void *)tempBuffPtr, 1678 tempWidth * tempHeight); 1679 tempBuffPtr += (tempWidth * tempHeight); 1680 memcpy((void *) pOutputPlane[1].pac_data, (void *)tempBuffPtr, 1681 (tempWidth/2) * (tempHeight/2)); 1682 tempBuffPtr += ((tempWidth/2) * (tempHeight/2)); 1683 memcpy((void *) pOutputPlane[2].pac_data, (void *)tempBuffPtr, 1684 (tempWidth/2) * (tempHeight/2)); 1685 } 1686 1687 pDecShellContext->mNbRenderedFrames++; 1688 if ( 0 > pDecShellContext->mFirstRenderedCts ) { 1689 pDecShellContext->mFirstRenderedCts = *pTime; 1690 } 1691 pDecShellContext->mLastRenderedCts = *pTime; 1692 1693 cleanUp: 1694 if( M4NO_ERROR == err ) { 1695 *pTime = pDecShellContext->m_lastRenderCts; 1696 ALOGV("VideoEditorVideoDecoder_render no error"); 1697 } else { 1698 ALOGV("VideoEditorVideoDecoder_render ERROR 0x%X", err); 1699 } 1700 ALOGV("VideoEditorVideoDecoder_render end"); 1701 return err; 1702 } 1703 1704 M4OSA_ERR VideoEditorVideoDecoder_getInterface(M4DECODER_VideoType decoderType, 1705 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1706 M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL; 1707 1708 pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc( 1709 sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL, 1710 (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" ); 1711 if (M4OSA_NULL == pDecoderInterface) { 1712 return M4ERR_ALLOC; 1713 } 1714 1715 *pDecoderType = decoderType; 1716 1717 pDecoderInterface->m_pFctCreate = VideoEditorVideoDecoder_create; 1718 pDecoderInterface->m_pFctDestroy = VideoEditorVideoDecoder_destroy; 1719 pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption; 1720 pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption; 1721 pDecoderInterface->m_pFctDecode = VideoEditorVideoDecoder_decode; 1722 pDecoderInterface->m_pFctRender = VideoEditorVideoDecoder_render; 1723 1724 *pDecInterface = (M4OSA_Context)pDecoderInterface; 1725 return M4NO_ERROR; 1726 } 1727 1728 M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_VideoType decoderType, 1729 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1730 M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL; 1731 1732 pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc( 1733 sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL, 1734 (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" ); 1735 if (M4OSA_NULL == pDecoderInterface) { 1736 return M4ERR_ALLOC; 1737 } 1738 1739 *pDecoderType = decoderType; 1740 1741 pDecoderInterface->m_pFctCreate = VideoEditorVideoSoftwareDecoder_create; 1742 pDecoderInterface->m_pFctDestroy = VideoEditorVideoDecoder_destroy; 1743 pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption; 1744 pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption; 1745 pDecoderInterface->m_pFctDecode = VideoEditorVideoDecoder_decode; 1746 pDecoderInterface->m_pFctRender = VideoEditorVideoDecoder_render; 1747 1748 *pDecInterface = (M4OSA_Context)pDecoderInterface; 1749 return M4NO_ERROR; 1750 } 1751 extern "C" { 1752 1753 M4OSA_ERR VideoEditorVideoDecoder_getInterface_MPEG4( 1754 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1755 return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeMPEG4, 1756 pDecoderType, pDecInterface); 1757 } 1758 1759 M4OSA_ERR VideoEditorVideoDecoder_getInterface_H264( 1760 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1761 return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeAVC, 1762 pDecoderType, pDecInterface); 1763 1764 } 1765 1766 M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface_MPEG4( 1767 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1768 return VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_kVideoTypeMPEG4, 1769 pDecoderType, pDecInterface); 1770 } 1771 1772 M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface_H264( 1773 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1774 return VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_kVideoTypeAVC, 1775 pDecoderType, pDecInterface); 1776 1777 } 1778 1779 M4OSA_ERR VideoEditorVideoDecoder_getVideoDecodersAndCapabilities( 1780 M4DECODER_VideoDecoders** decoders) { 1781 return queryVideoDecoderCapabilities(decoders); 1782 } 1783 1784 } // extern "C" 1785