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