VideoEditorVideoDecoder.cpp revision 0a25bd5bacf5408ca205b15e53cfb6dc2fc1d171
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16/** 17************************************************************************* 18* @file VideoEditorVideoDecoder.cpp 19* @brief StageFright shell video decoder 20************************************************************************* 21*/ 22#define LOG_NDEBUG 1 23#define LOG_TAG "VIDEOEDITOR_VIDEODECODER" 24/******************* 25 * HEADERS * 26 *******************/ 27 28#include "VideoEditorVideoDecoder_internal.h" 29#include "VideoEditorUtils.h" 30#include "M4VD_Tools.h" 31 32#include <media/stagefright/MetaData.h> 33#include <media/stagefright/MediaDefs.h> 34#include <media/stagefright/MediaDebug.h> 35/******************** 36 * DEFINITIONS * 37 ********************/ 38#define MAX_DEC_BUFFERS 10 39 40/******************** 41 * SOURCE CLASS * 42 ********************/ 43using namespace android; 44static M4OSA_ERR copyBufferToQueue( 45 VideoEditorVideoDecoder_Context* pDecShellContext, 46 MediaBuffer* pDecodedBuffer); 47 48class 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 81VideoEditorVideoDecoderSource::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 92VideoEditorVideoDecoderSource::~VideoEditorVideoDecoderSource() { 93 if (mStarted == true) { 94 stop(); 95 } 96} 97 98status_t VideoEditorVideoDecoderSource::start( 99 MetaData *params) { 100 101 if (!mStarted) { 102 if (mFormat->findInt32(kKeyMaxInputSize, &mMaxAUSize) == false) { 103 LOGE("Could not find kKeyMaxInputSize"); 104 return ERROR_MALFORMED; 105 } 106 107 mGroup = new MediaBufferGroup; 108 if (mGroup == NULL) { 109 LOGE("FATAL: memory limitation ! "); 110 return NO_MEMORY; 111 } 112 113 mGroup->add_buffer(new MediaBuffer(mMaxAUSize)); 114 115 mStarted = true; 116 } 117 return OK; 118} 119 120status_t VideoEditorVideoDecoderSource::stop() { 121 if (mStarted) { 122 if (mBuffer != NULL) { 123 124 // FIXME: 125 // Why do we need to check on the ref count? 126 int ref_count = mBuffer->refcount(); 127 LOGV("MediaBuffer refcount is %d",ref_count); 128 for (int i = 0; i < ref_count; ++i) { 129 mBuffer->release(); 130 } 131 132 mBuffer = NULL; 133 } 134 delete mGroup; 135 mGroup = NULL; 136 mStarted = false; 137 } 138 return OK; 139} 140 141sp<MetaData> VideoEditorVideoDecoderSource::getFormat() { 142 Mutex::Autolock autolock(mLock); 143 144 return mFormat; 145} 146 147status_t VideoEditorVideoDecoderSource::read(MediaBuffer** buffer_out, 148 const ReadOptions *options) { 149 150 Mutex::Autolock autolock(mLock); 151 if (options != NULL) { 152 int64_t time_us; 153 MediaSource::ReadOptions::SeekMode mode; 154 options->getSeekTo(&time_us, &mode); 155 if (mode != MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC) { 156 LOGE("Unexpected read options"); 157 return BAD_VALUE; 158 } 159 160 M4OSA_ERR err; 161 M4OSA_Int32 rapTime = time_us / 1000; 162 163 /*--- Retrieve the previous RAP time ---*/ 164 err = mpDecShellContext->m_pReaderGlobal->m_pFctGetPrevRapTime( 165 mpDecShellContext->m_pReader->m_readerContext, 166 (M4_StreamHandler*)mpDecShellContext->m_pVideoStreamhandler, 167 &rapTime); 168 169 if (err == M4WAR_READER_INFORMATION_NOT_PRESENT) { 170 /* No RAP table, jump backward and predecode */ 171 rapTime -= 40000; 172 if(rapTime < 0) rapTime = 0; 173 } else if (err != OK) { 174 LOGE("get rap time error = 0x%x\n", (uint32_t)err); 175 return UNKNOWN_ERROR; 176 } 177 178 err = mpDecShellContext->m_pReaderGlobal->m_pFctJump( 179 mpDecShellContext->m_pReader->m_readerContext, 180 (M4_StreamHandler*)mpDecShellContext->m_pVideoStreamhandler, 181 &rapTime); 182 183 if (err != OK) { 184 LOGE("jump err = 0x%x\n", (uint32_t)err); 185 return BAD_VALUE; 186 } 187 } 188 189 *buffer_out = NULL; 190 191 M4OSA_ERR lerr = mGroup->acquire_buffer(&mBuffer); 192 if (lerr != OK) { 193 return lerr; 194 } 195 mBuffer->meta_data()->clear(); // clear all the meta data 196 197 if (mStarted) { 198 //getNext AU from reader. 199 M4_AccessUnit* pAccessUnit = mpDecShellContext->m_pNextAccessUnitToDecode; 200 lerr = mpDecShellContext->m_pReader->m_pFctGetNextAu( 201 mpDecShellContext->m_pReader->m_readerContext, 202 (M4_StreamHandler*)mpDecShellContext->m_pVideoStreamhandler, 203 pAccessUnit); 204 if (lerr == M4WAR_NO_DATA_YET || lerr == M4WAR_NO_MORE_AU) { 205 *buffer_out = NULL; 206 return ERROR_END_OF_STREAM; 207 } 208 209 //copy the reader AU buffer to mBuffer 210 M4OSA_UInt32 lSize = (pAccessUnit->m_size > (M4OSA_UInt32)mMaxAUSize)\ 211 ? (M4OSA_UInt32)mMaxAUSize : pAccessUnit->m_size; 212 memcpy((void *)mBuffer->data(),(void *)pAccessUnit->m_dataAddress, 213 lSize); 214 215 mBuffer->set_range(0, lSize); 216 int64_t frameTimeUs = (int64_t) (pAccessUnit->m_CTS * 1000); 217 mBuffer->meta_data()->setInt64(kKeyTime, frameTimeUs); 218 219 // Replace the AU start code for H264 220 if (VIDEOEDITOR_kH264VideoDec == mCodecType) { 221 uint8_t *data =(uint8_t *)mBuffer->data() + mBuffer->range_offset(); 222 data[0]=0; 223 data[1]=0; 224 data[2]=0; 225 data[3]=1; 226 } 227 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 228 (pAccessUnit->m_attribute == 0x04)? 1 : 0); 229 *buffer_out = mBuffer; 230 } 231 return OK; 232} 233 234static 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 240M4OSA_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 603M4VIFI_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} 639void logSupportDecodersAndCapabilities(M4DECODER_VideoDecoders* decoders) { 640 VideoDecoder *pDecoder; 641 VideoComponentCapabilities *pOmxComponents = NULL; 642 VideoProfileLevel *pProfileLevel = NULL; 643 pDecoder = decoders->decoder; 644 for (size_t i = 0; i< decoders->decoderNumber; i++) { 645 LOGV("Supported Codec[%d] :%d", i, pDecoder->codec); 646 pOmxComponents = pDecoder->component; 647 for(size_t j = 0; j < pDecoder->componentNumber; j++) { 648 pProfileLevel = pOmxComponents->profileLevel; 649 LOGV("-->component %d", j); 650 for(size_t k = 0; k < pOmxComponents->profileNumber; k++) { 651 LOGV("-->profile:%ld maxLevel:%ld", pProfileLevel->mProfile, 652 pProfileLevel->mLevel); 653 pProfileLevel++; 654 } 655 pOmxComponents++; 656 } 657 pDecoder++; 658 } 659} 660M4OSA_ERR queryVideoDecoderCapabilities 661 (M4DECODER_VideoDecoders** decoders) { 662 M4OSA_ERR err = M4NO_ERROR; 663 const char *kMimeTypes[] = { 664 MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4, 665 MEDIA_MIMETYPE_VIDEO_H263 666 }; 667 668 int32_t supportFormats = sizeof(kMimeTypes) / sizeof(kMimeTypes[0]); 669 M4DECODER_VideoDecoders *pDecoders; 670 VideoDecoder *pDecoder; 671 VideoComponentCapabilities *pOmxComponents = NULL; 672 VideoProfileLevel *pProfileLevel = NULL; 673 OMXClient client; 674 status_t status = OK; 675 SAFE_MALLOC(pDecoders, M4DECODER_VideoDecoders, 1, "VideoDecoders"); 676 SAFE_MALLOC(pDecoder, VideoDecoder, supportFormats, 677 "VideoDecoder"); 678 pDecoders->decoder = pDecoder; 679 680 pDecoders->decoderNumber= supportFormats; 681 status = client.connect(); 682 CHECK(status == OK); 683 for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]); 684 ++k) { 685 Vector<CodecCapabilities> results; 686 CHECK_EQ(QueryCodecs(client.interface(), kMimeTypes[k], 687 true, // queryDecoders 688 &results), (status_t)OK); 689 690 if (results.size()) { 691 SAFE_MALLOC(pOmxComponents, VideoComponentCapabilities, 692 results.size(), "VideoComponentCapabilities"); 693 LOGV("K=%d",k); 694 pDecoder->component = pOmxComponents; 695 pDecoder->componentNumber = results.size(); 696 } 697 698 for (size_t i = 0; i < results.size(); ++i) { 699 LOGV(" decoder '%s' supports ", 700 results[i].mComponentName.string()); 701 702 if (results[i].mProfileLevels.size() == 0) { 703 LOGV("NOTHING.\n"); 704 continue; 705 } 706 // Count the supported profiles 707 int32_t profileNumber = 0; 708 int32_t profile = -1; 709 for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) { 710 const CodecProfileLevel &profileLevel = 711 results[i].mProfileLevels[j]; 712 if (profileLevel.mProfile != profile) { 713 profile = profileLevel.mProfile; 714 profileNumber++; 715 } 716 } 717 SAFE_MALLOC(pProfileLevel, VideoProfileLevel, 718 profileNumber, "VideoProfileLevel"); 719 720 721 722 pOmxComponents->profileLevel = pProfileLevel; 723 724 pOmxComponents->profileNumber = profileNumber; 725 726 // Get the max Level for each profile. 727 int32_t maxLevel = -1; 728 profile = -1; 729 profileNumber = 0; 730 for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) { 731 const CodecProfileLevel &profileLevel = 732 results[i].mProfileLevels[j]; 733 if (profile == -1 && maxLevel == -1) { 734 profile = profileLevel.mProfile; 735 maxLevel = profileLevel.mLevel; 736 } 737 if (profileLevel.mProfile != profile) { 738 // Save the current profile and the max level for this profile. 739 LOGV("profile :%d maxLevel;%d", profile, maxLevel); 740 pProfileLevel->mProfile = profile; 741 pProfileLevel->mLevel = maxLevel; 742 profileNumber++; 743 pProfileLevel++; 744 profile = profileLevel.mProfile; 745 maxLevel = profileLevel.mLevel; 746 } else { 747 if (profileLevel.mLevel > maxLevel) { 748 maxLevel = profileLevel.mLevel; 749 } 750 } 751 752 } 753 pOmxComponents++; 754 } 755 if (!strcmp(MEDIA_MIMETYPE_VIDEO_AVC, kMimeTypes[k])) 756 pDecoder->codec = M4DA_StreamTypeVideoMpeg4Avc; 757 if (!strcmp(MEDIA_MIMETYPE_VIDEO_MPEG4, kMimeTypes[k])) 758 pDecoder->codec = M4DA_StreamTypeVideoMpeg4; 759 if (!strcmp(MEDIA_MIMETYPE_VIDEO_H263, kMimeTypes[k])) 760 pDecoder->codec = M4DA_StreamTypeVideoH263; 761 762 pDecoder++; 763 } 764 765 logSupportDecodersAndCapabilities(pDecoders); 766 *decoders = pDecoders; 767cleanUp: 768 return err; 769} 770/******************** 771 * ENGINE INTERFACE * 772 ********************/ 773M4OSA_ERR VideoEditorVideoDecoder_configureFromMetadata(M4OSA_Context pContext, 774 MetaData* meta) { 775 M4OSA_ERR err = M4NO_ERROR; 776 VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL; 777 bool success = OK; 778 int32_t width = 0; 779 int32_t height = 0; 780 int32_t frameSize = 0; 781 int32_t vWidth, vHeight; 782 int32_t cropLeft, cropTop, cropRight, cropBottom; 783 784 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 785 VIDEOEDITOR_CHECK(M4OSA_NULL != meta, M4ERR_PARAMETER); 786 787 LOGV("VideoEditorVideoDecoder_configureFromMetadata begin"); 788 789 pDecShellContext = (VideoEditorVideoDecoder_Context*)pContext; 790 791 success = meta->findInt32(kKeyWidth, &vWidth); 792 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 793 success = meta->findInt32(kKeyHeight, &vHeight); 794 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 795 796 LOGV("vWidth = %d, vHeight = %d", vWidth, vHeight); 797 798 pDecShellContext->mGivenWidth = vWidth; 799 pDecShellContext->mGivenHeight = vHeight; 800 801 if (!meta->findRect( 802 kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) { 803 804 cropLeft = cropTop = 0; 805 cropRight = vWidth - 1; 806 cropBottom = vHeight - 1; 807 808 LOGV("got dimensions only %d x %d", width, height); 809 } else { 810 LOGV("got crop rect %d, %d, %d, %d", 811 cropLeft, cropTop, cropRight, cropBottom); 812 } 813 814 pDecShellContext->mCropRect.left = cropLeft; 815 pDecShellContext->mCropRect.right = cropRight; 816 pDecShellContext->mCropRect.top = cropTop; 817 pDecShellContext->mCropRect.bottom = cropBottom; 818 819 width = cropRight - cropLeft + 1; 820 height = cropBottom - cropTop + 1; 821 822 LOGV("VideoDecoder_configureFromMetadata : W=%d H=%d", width, height); 823 VIDEOEDITOR_CHECK((0 != width) && (0 != height), M4ERR_PARAMETER); 824 825 if( (M4OSA_NULL != pDecShellContext->m_pDecBufferPool) && 826 (pDecShellContext->m_pVideoStreamhandler->m_videoWidth == \ 827 (uint32_t)width) && 828 (pDecShellContext->m_pVideoStreamhandler->m_videoHeight == \ 829 (uint32_t)height) ) { 830 // No need to reconfigure 831 goto cleanUp; 832 } 833 LOGV("VideoDecoder_configureFromMetadata reset: W=%d H=%d", width, height); 834 // Update the stream handler parameters 835 pDecShellContext->m_pVideoStreamhandler->m_videoWidth = width; 836 pDecShellContext->m_pVideoStreamhandler->m_videoHeight = height; 837 frameSize = (width * height * 3) / 2; 838 839 // Configure the buffer pool 840 if( M4OSA_NULL != pDecShellContext->m_pDecBufferPool ) { 841 LOGV("VideoDecoder_configureFromMetadata : reset the buffer pool"); 842 VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool); 843 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 844 } 845 err = VIDEOEDITOR_BUFFER_allocatePool(&pDecShellContext->m_pDecBufferPool, 846 MAX_DEC_BUFFERS, (M4OSA_Char*)"VIDEOEDITOR_DecodedBufferPool"); 847 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 848 err = VIDEOEDITOR_BUFFER_initPoolBuffers(pDecShellContext->m_pDecBufferPool, 849 frameSize + pDecShellContext->mGivenWidth * 2); 850 851 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 852 853cleanUp: 854 if( M4NO_ERROR == err ) { 855 LOGV("VideoEditorVideoDecoder_configureFromMetadata no error"); 856 } else { 857 if( M4OSA_NULL != pDecShellContext->m_pDecBufferPool ) { 858 VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool); 859 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 860 } 861 LOGV("VideoEditorVideoDecoder_configureFromMetadata ERROR 0x%X", err); 862 } 863 LOGV("VideoEditorVideoDecoder_configureFromMetadata end"); 864 return err; 865} 866 867M4OSA_ERR VideoEditorVideoDecoder_destroy(M4OSA_Context pContext) { 868 M4OSA_ERR err = M4NO_ERROR; 869 VideoEditorVideoDecoder_Context* pDecShellContext = 870 (VideoEditorVideoDecoder_Context*)pContext; 871 872 // Input parameters check 873 LOGV("VideoEditorVideoDecoder_destroy begin"); 874 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 875 876 // Release the color converter 877 delete pDecShellContext->mI420ColorConverter; 878 879 // Destroy the graph 880 if( pDecShellContext->mVideoDecoder != NULL ) { 881 LOGV("### VideoEditorVideoDecoder_destroy : releasing decoder"); 882 pDecShellContext->mVideoDecoder->stop(); 883 pDecShellContext->mVideoDecoder.clear(); 884 } 885 pDecShellContext->mClient.disconnect(); 886 pDecShellContext->mReaderSource.clear(); 887 888 // Release memory 889 if( pDecShellContext->m_pDecBufferPool != M4OSA_NULL ) { 890 VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool); 891 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 892 } 893 SAFE_FREE(pDecShellContext); 894 pContext = NULL; 895 896cleanUp: 897 if( M4NO_ERROR == err ) { 898 LOGV("VideoEditorVideoDecoder_destroy no error"); 899 } else { 900 LOGV("VideoEditorVideoDecoder_destroy ERROR 0x%X", err); 901 } 902 LOGV("VideoEditorVideoDecoder_destroy end"); 903 return err; 904} 905 906M4OSA_ERR VideoEditorVideoDecoder_create(M4OSA_Context *pContext, 907 M4_StreamHandler *pStreamHandler, 908 M4READER_GlobalInterface *pReaderGlobalInterface, 909 M4READER_DataInterface *pReaderDataInterface, 910 M4_AccessUnit *pAccessUnit, M4OSA_Void *pUserData) { 911 M4OSA_ERR err = M4NO_ERROR; 912 VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL; 913 status_t status = OK; 914 bool success = TRUE; 915 int32_t colorFormat = 0; 916 M4OSA_UInt32 size = 0; 917 sp<MetaData> decoderMetadata = NULL; 918 int decoderOutput = OMX_COLOR_FormatYUV420Planar; 919 920 LOGV("VideoEditorVideoDecoder_create begin"); 921 // Input parameters check 922 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 923 VIDEOEDITOR_CHECK(M4OSA_NULL != pStreamHandler, M4ERR_PARAMETER); 924 VIDEOEDITOR_CHECK(M4OSA_NULL != pReaderDataInterface, M4ERR_PARAMETER); 925 926 // Context allocation & initialization 927 SAFE_MALLOC(pDecShellContext, VideoEditorVideoDecoder_Context, 1, 928 "VideoEditorVideoDecoder"); 929 pDecShellContext->m_pVideoStreamhandler = 930 (M4_VideoStreamHandler*)pStreamHandler; 931 pDecShellContext->m_pNextAccessUnitToDecode = pAccessUnit; 932 pDecShellContext->m_pReaderGlobal = pReaderGlobalInterface; 933 pDecShellContext->m_pReader = pReaderDataInterface; 934 pDecShellContext->m_lastDecodedCTS = -1; 935 pDecShellContext->m_lastRenderCts = -1; 936 switch( pStreamHandler->m_streamType ) { 937 case M4DA_StreamTypeVideoH263: 938 pDecShellContext->mDecoderType = VIDEOEDITOR_kH263VideoDec; 939 break; 940 case M4DA_StreamTypeVideoMpeg4: 941 pDecShellContext->mDecoderType = VIDEOEDITOR_kMpeg4VideoDec; 942 // Parse the VOL header 943 err = VideoEditorVideoDecoder_internalParseVideoDSI( 944 (M4OSA_UInt8*)pDecShellContext->m_pVideoStreamhandler->\ 945 m_basicProperties.m_pDecoderSpecificInfo, 946 pDecShellContext->m_pVideoStreamhandler->\ 947 m_basicProperties.m_decoderSpecificInfoSize, 948 &pDecShellContext->m_Dci, &pDecShellContext->m_VideoSize); 949 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 950 break; 951 case M4DA_StreamTypeVideoMpeg4Avc: 952 pDecShellContext->mDecoderType = VIDEOEDITOR_kH264VideoDec; 953 break; 954 default: 955 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 956 M4ERR_PARAMETER); 957 break; 958 } 959 960 pDecShellContext->mNbInputFrames = 0; 961 pDecShellContext->mFirstInputCts = -1.0; 962 pDecShellContext->mLastInputCts = -1.0; 963 pDecShellContext->mNbRenderedFrames = 0; 964 pDecShellContext->mFirstRenderedCts = -1.0; 965 pDecShellContext->mLastRenderedCts = -1.0; 966 pDecShellContext->mNbOutputFrames = 0; 967 pDecShellContext->mFirstOutputCts = -1; 968 pDecShellContext->mLastOutputCts = -1; 969 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 970 971 /** 972 * StageFright graph building 973 */ 974 decoderMetadata = new MetaData; 975 switch( pDecShellContext->mDecoderType ) { 976 case VIDEOEDITOR_kH263VideoDec: 977 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 978 break; 979 case VIDEOEDITOR_kMpeg4VideoDec: 980 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 981 decoderMetadata->setData(kKeyESDS, kTypeESDS, 982 pStreamHandler->m_pESDSInfo, 983 pStreamHandler->m_ESDSInfoSize); 984 break; 985 case VIDEOEDITOR_kH264VideoDec: 986 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 987 decoderMetadata->setData(kKeyAVCC, kTypeAVCC, 988 pStreamHandler->m_pH264DecoderSpecificInfo, 989 pStreamHandler->m_H264decoderSpecificInfoSize); 990 break; 991 default: 992 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 993 M4ERR_PARAMETER); 994 break; 995 } 996 997 decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize); 998 decoderMetadata->setInt32(kKeyWidth, 999 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 1000 decoderMetadata->setInt32(kKeyHeight, 1001 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1002 1003 // Create the decoder source 1004 pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource( 1005 decoderMetadata, pDecShellContext->mDecoderType, 1006 (void *)pDecShellContext); 1007 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(), 1008 M4ERR_SF_DECODER_RSRC_FAIL); 1009 1010 // Connect to the OMX client 1011 status = pDecShellContext->mClient.connect(); 1012 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 1013 1014 // Create the decoder 1015 pDecShellContext->mVideoDecoder = OMXCodec::Create( 1016 pDecShellContext->mClient.interface(), 1017 decoderMetadata, false, pDecShellContext->mReaderSource); 1018 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(), 1019 M4ERR_SF_DECODER_RSRC_FAIL); 1020 1021 1022 // Get the output color format 1023 success = pDecShellContext->mVideoDecoder->getFormat()->findInt32( 1024 kKeyColorFormat, &colorFormat); 1025 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 1026 pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; 1027 1028 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth, 1029 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 1030 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight, 1031 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1032 1033 // Get the color converter 1034 pDecShellContext->mI420ColorConverter = new I420ColorConverter; 1035 if (pDecShellContext->mI420ColorConverter->isLoaded()) { 1036 decoderOutput = pDecShellContext->mI420ColorConverter->getDecoderOutputFormat(); 1037 } 1038 1039 if (decoderOutput == OMX_COLOR_FormatYUV420Planar) { 1040 delete pDecShellContext->mI420ColorConverter; 1041 pDecShellContext->mI420ColorConverter = NULL; 1042 } 1043 1044 LOGI("decoder output format = 0x%X\n", decoderOutput); 1045 1046 // Configure the buffer pool from the metadata 1047 err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext, 1048 pDecShellContext->mVideoDecoder->getFormat().get()); 1049 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 1050 1051 // Start the graph 1052 status = pDecShellContext->mVideoDecoder->start(); 1053 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 1054 1055 *pContext = (M4OSA_Context)pDecShellContext; 1056 1057cleanUp: 1058 if( M4NO_ERROR == err ) { 1059 LOGV("VideoEditorVideoDecoder_create no error"); 1060 } else { 1061 VideoEditorVideoDecoder_destroy(pDecShellContext); 1062 *pContext = M4OSA_NULL; 1063 LOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err); 1064 } 1065 LOGV("VideoEditorVideoDecoder_create : DONE"); 1066 return err; 1067} 1068 1069M4OSA_ERR VideoEditorVideoSoftwareDecoder_create(M4OSA_Context *pContext, 1070 M4_StreamHandler *pStreamHandler, 1071 M4READER_GlobalInterface *pReaderGlobalInterface, 1072 M4READER_DataInterface *pReaderDataInterface, 1073 M4_AccessUnit *pAccessUnit, M4OSA_Void *pUserData) { 1074 M4OSA_ERR err = M4NO_ERROR; 1075 VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL; 1076 status_t status = OK; 1077 bool success = TRUE; 1078 int32_t colorFormat = 0; 1079 M4OSA_UInt32 size = 0; 1080 sp<MetaData> decoderMetadata = NULL; 1081 1082 LOGV("VideoEditorVideoDecoder_create begin"); 1083 // Input parameters check 1084 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 1085 VIDEOEDITOR_CHECK(M4OSA_NULL != pStreamHandler, M4ERR_PARAMETER); 1086 VIDEOEDITOR_CHECK(M4OSA_NULL != pReaderDataInterface, M4ERR_PARAMETER); 1087 1088 // Context allocation & initialization 1089 SAFE_MALLOC(pDecShellContext, VideoEditorVideoDecoder_Context, 1, 1090 "VideoEditorVideoDecoder"); 1091 pDecShellContext->m_pVideoStreamhandler = 1092 (M4_VideoStreamHandler*)pStreamHandler; 1093 pDecShellContext->m_pNextAccessUnitToDecode = pAccessUnit; 1094 pDecShellContext->m_pReaderGlobal = pReaderGlobalInterface; 1095 pDecShellContext->m_pReader = pReaderDataInterface; 1096 pDecShellContext->m_lastDecodedCTS = -1; 1097 pDecShellContext->m_lastRenderCts = -1; 1098 switch( pStreamHandler->m_streamType ) { 1099 case M4DA_StreamTypeVideoH263: 1100 pDecShellContext->mDecoderType = VIDEOEDITOR_kH263VideoDec; 1101 break; 1102 case M4DA_StreamTypeVideoMpeg4: 1103 pDecShellContext->mDecoderType = VIDEOEDITOR_kMpeg4VideoDec; 1104 // Parse the VOL header 1105 err = VideoEditorVideoDecoder_internalParseVideoDSI( 1106 (M4OSA_UInt8*)pDecShellContext->m_pVideoStreamhandler->\ 1107 m_basicProperties.m_pDecoderSpecificInfo, 1108 pDecShellContext->m_pVideoStreamhandler->\ 1109 m_basicProperties.m_decoderSpecificInfoSize, 1110 &pDecShellContext->m_Dci, &pDecShellContext->m_VideoSize); 1111 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 1112 break; 1113 case M4DA_StreamTypeVideoMpeg4Avc: 1114 pDecShellContext->mDecoderType = VIDEOEDITOR_kH264VideoDec; 1115 break; 1116 default: 1117 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 1118 M4ERR_PARAMETER); 1119 break; 1120 } 1121 1122 pDecShellContext->mNbInputFrames = 0; 1123 pDecShellContext->mFirstInputCts = -1.0; 1124 pDecShellContext->mLastInputCts = -1.0; 1125 pDecShellContext->mNbRenderedFrames = 0; 1126 pDecShellContext->mFirstRenderedCts = -1.0; 1127 pDecShellContext->mLastRenderedCts = -1.0; 1128 pDecShellContext->mNbOutputFrames = 0; 1129 pDecShellContext->mFirstOutputCts = -1; 1130 pDecShellContext->mLastOutputCts = -1; 1131 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 1132 1133 /** 1134 * StageFright graph building 1135 */ 1136 decoderMetadata = new MetaData; 1137 switch( pDecShellContext->mDecoderType ) { 1138 case VIDEOEDITOR_kH263VideoDec: 1139 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 1140 break; 1141 case VIDEOEDITOR_kMpeg4VideoDec: 1142 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 1143 decoderMetadata->setData(kKeyESDS, kTypeESDS, 1144 pStreamHandler->m_pESDSInfo, 1145 pStreamHandler->m_ESDSInfoSize); 1146 break; 1147 case VIDEOEDITOR_kH264VideoDec: 1148 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 1149 decoderMetadata->setData(kKeyAVCC, kTypeAVCC, 1150 pStreamHandler->m_pH264DecoderSpecificInfo, 1151 pStreamHandler->m_H264decoderSpecificInfoSize); 1152 break; 1153 default: 1154 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 1155 M4ERR_PARAMETER); 1156 break; 1157 } 1158 1159 decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize); 1160 decoderMetadata->setInt32(kKeyWidth, 1161 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 1162 decoderMetadata->setInt32(kKeyHeight, 1163 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1164 1165 // Create the decoder source 1166 pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource( 1167 decoderMetadata, pDecShellContext->mDecoderType, 1168 (void *)pDecShellContext); 1169 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(), 1170 M4ERR_SF_DECODER_RSRC_FAIL); 1171 1172 // Connect to the OMX client 1173 status = pDecShellContext->mClient.connect(); 1174 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 1175 1176 LOGI("Using software codecs only"); 1177 // Create the decoder 1178 pDecShellContext->mVideoDecoder = OMXCodec::Create( 1179 pDecShellContext->mClient.interface(), 1180 decoderMetadata, false, pDecShellContext->mReaderSource,NULL,OMXCodec::kSoftwareCodecsOnly); 1181 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(), 1182 M4ERR_SF_DECODER_RSRC_FAIL); 1183 1184 // Get the output color format 1185 success = pDecShellContext->mVideoDecoder->getFormat()->findInt32( 1186 kKeyColorFormat, &colorFormat); 1187 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 1188 pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; 1189 1190 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth, 1191 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 1192 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight, 1193 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1194 1195 // Configure the buffer pool from the metadata 1196 err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext, 1197 pDecShellContext->mVideoDecoder->getFormat().get()); 1198 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 1199 1200 // Start the graph 1201 status = pDecShellContext->mVideoDecoder->start(); 1202 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 1203 1204 *pContext = (M4OSA_Context)pDecShellContext; 1205 1206cleanUp: 1207 if( M4NO_ERROR == err ) { 1208 LOGV("VideoEditorVideoDecoder_create no error"); 1209 } else { 1210 VideoEditorVideoDecoder_destroy(pDecShellContext); 1211 *pContext = M4OSA_NULL; 1212 LOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err); 1213 } 1214 LOGV("VideoEditorVideoDecoder_create : DONE"); 1215 return err; 1216} 1217 1218 1219M4OSA_ERR VideoEditorVideoDecoder_getOption(M4OSA_Context context, 1220 M4OSA_OptionID optionId, M4OSA_DataOption pValue) { 1221 M4OSA_ERR lerr = M4NO_ERROR; 1222 VideoEditorVideoDecoder_Context* pDecShellContext = 1223 (VideoEditorVideoDecoder_Context*) context; 1224 M4_VersionInfo* pVersionInfo; 1225 M4DECODER_VideoSize* pVideoSize; 1226 M4OSA_UInt32* pNextFrameCts; 1227 M4OSA_UInt32 *plastDecodedFrameCts; 1228 M4DECODER_AVCProfileLevel* profile; 1229 M4DECODER_MPEG4_DecoderConfigInfo* pDecConfInfo; 1230 1231 LOGV("VideoEditorVideoDecoder_getOption begin"); 1232 1233 switch (optionId) { 1234 case M4DECODER_kOptionID_AVCLastDecodedFrameCTS: 1235 plastDecodedFrameCts = (M4OSA_UInt32 *) pValue; 1236 *plastDecodedFrameCts = pDecShellContext->m_lastDecodedCTS; 1237 break; 1238 1239 case M4DECODER_kOptionID_Version: 1240 pVersionInfo = (M4_VersionInfo*)pValue; 1241 1242 pVersionInfo->m_major = VIDEOEDITOR_VIDEC_SHELL_VER_MAJOR; 1243 pVersionInfo->m_minor= VIDEOEDITOR_VIDEC_SHELL_VER_MINOR; 1244 pVersionInfo->m_revision = VIDEOEDITOR_VIDEC_SHELL_VER_REVISION; 1245 pVersionInfo->m_structSize=sizeof(M4_VersionInfo); 1246 break; 1247 1248 case M4DECODER_kOptionID_VideoSize: 1249 /** Only VPS uses this Option ID. */ 1250 pVideoSize = (M4DECODER_VideoSize*)pValue; 1251 pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyWidth, 1252 (int32_t*)(&pVideoSize->m_uiWidth)); 1253 pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyHeight, 1254 (int32_t*)(&pVideoSize->m_uiHeight)); 1255 LOGV("VideoEditorVideoDecoder_getOption : W=%d H=%d", 1256 pVideoSize->m_uiWidth, pVideoSize->m_uiHeight); 1257 break; 1258 1259 case M4DECODER_kOptionID_NextRenderedFrameCTS: 1260 /** How to get this information. SF decoder does not provide this. * 1261 ** Let us provide last decoded frame CTS as of now. * 1262 ** Only VPS uses this Option ID. */ 1263 pNextFrameCts = (M4OSA_UInt32 *)pValue; 1264 *pNextFrameCts = pDecShellContext->m_lastDecodedCTS; 1265 break; 1266 case M4DECODER_MPEG4_kOptionID_DecoderConfigInfo: 1267 if(pDecShellContext->mDecoderType == VIDEOEDITOR_kMpeg4VideoDec) { 1268 (*(M4DECODER_MPEG4_DecoderConfigInfo*)pValue) = 1269 pDecShellContext->m_Dci; 1270 } 1271 break; 1272 default: 1273 lerr = M4ERR_BAD_OPTION_ID; 1274 break; 1275 1276 } 1277 1278 LOGV("VideoEditorVideoDecoder_getOption: end with err = 0x%x", lerr); 1279 return lerr; 1280} 1281 1282M4OSA_ERR VideoEditorVideoDecoder_setOption(M4OSA_Context context, 1283 M4OSA_OptionID optionId, M4OSA_DataOption pValue) { 1284 M4OSA_ERR lerr = M4NO_ERROR; 1285 VideoEditorVideoDecoder_Context *pDecShellContext = 1286 (VideoEditorVideoDecoder_Context*) context; 1287 1288 LOGV("VideoEditorVideoDecoder_setOption begin"); 1289 1290 switch (optionId) { 1291 case M4DECODER_kOptionID_OutputFilter: { 1292 M4DECODER_OutputFilter* pOutputFilter = 1293 (M4DECODER_OutputFilter*) pValue; 1294 pDecShellContext->m_pFilter = 1295 (M4VIFI_PlanConverterFunctionType*)pOutputFilter->\ 1296 m_pFilterFunction; 1297 pDecShellContext->m_pFilterUserData = 1298 pOutputFilter->m_pFilterUserData; 1299 } 1300 break; 1301 case M4DECODER_kOptionID_DeblockingFilter: 1302 break; 1303 default: 1304 lerr = M4ERR_BAD_CONTEXT; 1305 break; 1306 } 1307 1308 LOGV("VideoEditorVideoDecoder_setOption: end with err = 0x%x", lerr); 1309 return lerr; 1310} 1311 1312M4OSA_ERR VideoEditorVideoDecoder_decode(M4OSA_Context context, 1313 M4_MediaTime* pTime, M4OSA_Bool bJump, M4OSA_UInt32 tolerance) { 1314 M4OSA_ERR lerr = M4NO_ERROR; 1315 VideoEditorVideoDecoder_Context* pDecShellContext = 1316 (VideoEditorVideoDecoder_Context*) context; 1317 int64_t lFrameTime; 1318 MediaBuffer* pDecoderBuffer = NULL; 1319 MediaBuffer* pNextBuffer = NULL; 1320 status_t errStatus; 1321 bool needSeek = bJump; 1322 1323 LOGV("VideoEditorVideoDecoder_decode begin"); 1324 1325 if( M4OSA_TRUE == pDecShellContext->mReachedEOS ) { 1326 // Do not call read(), it could lead to a freeze 1327 LOGV("VideoEditorVideoDecoder_decode : EOS already reached"); 1328 lerr = M4WAR_NO_MORE_AU; 1329 goto VIDEOEDITOR_VideoDecode_cleanUP; 1330 } 1331 if(pDecShellContext->m_lastDecodedCTS >= *pTime) { 1332 LOGV("VideoDecoder_decode: Already decoded up to this time CTS = %lf.", 1333 pDecShellContext->m_lastDecodedCTS); 1334 goto VIDEOEDITOR_VideoDecode_cleanUP; 1335 } 1336 if(M4OSA_TRUE == bJump) { 1337 LOGV("VideoEditorVideoDecoder_decode: Jump called"); 1338 pDecShellContext->m_lastDecodedCTS = -1; 1339 pDecShellContext->m_lastRenderCts = -1; 1340 } 1341 1342 pDecShellContext->mNbInputFrames++; 1343 if (0 > pDecShellContext->mFirstInputCts){ 1344 pDecShellContext->mFirstInputCts = *pTime; 1345 } 1346 pDecShellContext->mLastInputCts = *pTime; 1347 1348 while (pDecoderBuffer == NULL || pDecShellContext->m_lastDecodedCTS + tolerance < *pTime) { 1349 LOGV("VideoEditorVideoDecoder_decode, frameCTS = %lf, DecodeUpTo = %lf", 1350 pDecShellContext->m_lastDecodedCTS, *pTime); 1351 1352 // Read the buffer from the stagefright decoder 1353 if (needSeek) { 1354 MediaSource::ReadOptions options; 1355 int64_t time_us = *pTime * 1000; 1356 options.setSeekTo(time_us, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); 1357 errStatus = pDecShellContext->mVideoDecoder->read(&pNextBuffer, &options); 1358 needSeek = false; 1359 } else { 1360 errStatus = pDecShellContext->mVideoDecoder->read(&pNextBuffer); 1361 } 1362 1363 // Handle EOS and format change 1364 if (errStatus == ERROR_END_OF_STREAM) { 1365 LOGV("End of stream reached, returning M4WAR_NO_MORE_AU "); 1366 pDecShellContext->mReachedEOS = M4OSA_TRUE; 1367 lerr = M4WAR_NO_MORE_AU; 1368 // If we decoded a buffer before EOS, we still need to put it 1369 // into the queue. 1370 if (pDecoderBuffer && bJump) { 1371 copyBufferToQueue(pDecShellContext, pDecoderBuffer); 1372 } 1373 goto VIDEOEDITOR_VideoDecode_cleanUP; 1374 } else if (INFO_FORMAT_CHANGED == errStatus) { 1375 LOGV("VideoDecoder_decode : source returns INFO_FORMAT_CHANGED"); 1376 lerr = VideoEditorVideoDecoder_configureFromMetadata( 1377 pDecShellContext, 1378 pDecShellContext->mVideoDecoder->getFormat().get()); 1379 if( M4NO_ERROR != lerr ) { 1380 LOGV("!!! VideoEditorVideoDecoder_decode ERROR : " 1381 "VideoDecoder_configureFromMetadata returns 0x%X", lerr); 1382 break; 1383 } 1384 continue; 1385 } 1386 1387 // Now we have a good next buffer, release the previous one. 1388 if (pDecoderBuffer != NULL) { 1389 pDecoderBuffer->release(); 1390 pDecoderBuffer = NULL; 1391 } 1392 pDecoderBuffer = pNextBuffer; 1393 1394 // Record the timestamp of last decoded buffer 1395 pDecoderBuffer->meta_data()->findInt64(kKeyTime, &lFrameTime); 1396 pDecShellContext->m_lastDecodedCTS = (M4_MediaTime)(lFrameTime/1000); 1397 LOGV("VideoEditorVideoDecoder_decode,decoded frametime = %lf,size = %d", 1398 (M4_MediaTime)lFrameTime, pDecoderBuffer->size() ); 1399 1400 // If bJump is false, we need to save every decoded buffer 1401 if (!bJump) { 1402 lerr = copyBufferToQueue(pDecShellContext, pDecoderBuffer); 1403 if (lerr != M4NO_ERROR) { 1404 goto VIDEOEDITOR_VideoDecode_cleanUP; 1405 } 1406 } 1407 } 1408 1409 // If bJump is true, we only need to copy the last buffer 1410 if (bJump) { 1411 lerr = copyBufferToQueue(pDecShellContext, pDecoderBuffer); 1412 if (lerr != M4NO_ERROR) { 1413 goto VIDEOEDITOR_VideoDecode_cleanUP; 1414 } 1415 } 1416 1417 pDecShellContext->mNbOutputFrames++; 1418 if ( 0 > pDecShellContext->mFirstOutputCts ) { 1419 pDecShellContext->mFirstOutputCts = *pTime; 1420 } 1421 pDecShellContext->mLastOutputCts = *pTime; 1422 1423VIDEOEDITOR_VideoDecode_cleanUP: 1424 *pTime = pDecShellContext->m_lastDecodedCTS; 1425 if (pDecoderBuffer != NULL) { 1426 pDecoderBuffer->release(); 1427 pDecoderBuffer = NULL; 1428 } 1429 1430 LOGV("VideoEditorVideoDecoder_decode: end with 0x%x", lerr); 1431 return lerr; 1432} 1433 1434static M4OSA_ERR copyBufferToQueue( 1435 VideoEditorVideoDecoder_Context* pDecShellContext, 1436 MediaBuffer* pDecoderBuffer) { 1437 1438 M4OSA_ERR lerr = M4NO_ERROR; 1439 VIDEOEDITOR_BUFFER_Buffer* tmpDecBuffer; 1440 1441 // Get a buffer from the queue 1442 lerr = VIDEOEDITOR_BUFFER_getBuffer(pDecShellContext->m_pDecBufferPool, 1443 VIDEOEDITOR_BUFFER_kEmpty, &tmpDecBuffer); 1444 if (lerr == (M4OSA_UInt32)M4ERR_NO_BUFFER_AVAILABLE) { 1445 lerr = VIDEOEDITOR_BUFFER_getOldestBuffer( 1446 pDecShellContext->m_pDecBufferPool, 1447 VIDEOEDITOR_BUFFER_kFilled, &tmpDecBuffer); 1448 tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kEmpty; 1449 lerr = M4NO_ERROR; 1450 } 1451 1452 if (lerr != M4NO_ERROR) return lerr; 1453 1454 // Color convert or copy from the given MediaBuffer to our buffer 1455 if (pDecShellContext->mI420ColorConverter) { 1456 if (pDecShellContext->mI420ColorConverter->convertDecoderOutputToI420( 1457 (uint8_t *)pDecoderBuffer->data(),// ?? + pDecoderBuffer->range_offset(), // decoderBits 1458 pDecShellContext->mGivenWidth, // decoderWidth 1459 pDecShellContext->mGivenHeight, // decoderHeight 1460 pDecShellContext->mCropRect, // decoderRect 1461 tmpDecBuffer->pData /* dstBits */) < 0) { 1462 LOGE("convertDecoderOutputToI420 failed"); 1463 lerr = M4ERR_NOT_IMPLEMENTED; 1464 } 1465 } else if (pDecShellContext->decOuputColorFormat == OMX_COLOR_FormatYUV420Planar) { 1466 int32_t width = pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1467 int32_t height = pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1468 int32_t yPlaneSize = width * height; 1469 int32_t uvPlaneSize = width * height / 4; 1470 int32_t offsetSrc = 0; 1471 1472 if (( width == pDecShellContext->mGivenWidth ) && 1473 ( height == pDecShellContext->mGivenHeight )) 1474 { 1475 M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset(); 1476 1477 memcpy((void *)tmpDecBuffer->pData, (void *)pTmpBuff, yPlaneSize); 1478 1479 offsetSrc += pDecShellContext->mGivenWidth * pDecShellContext->mGivenHeight; 1480 memcpy((void *)((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize), 1481 (void *)(pTmpBuff + offsetSrc), uvPlaneSize); 1482 1483 offsetSrc += (pDecShellContext->mGivenWidth >> 1) * (pDecShellContext->mGivenHeight >> 1); 1484 memcpy((void *)((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize + uvPlaneSize), 1485 (void *)(pTmpBuff + offsetSrc), uvPlaneSize); 1486 } 1487 else 1488 { 1489 M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset(); 1490 M4OSA_MemAddr8 pTmpBuffDst = (M4OSA_MemAddr8)tmpDecBuffer->pData; 1491 int32_t index; 1492 1493 for ( index = 0; index < height; index++) 1494 { 1495 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width); 1496 pTmpBuffDst += width; 1497 pTmpBuff += pDecShellContext->mGivenWidth; 1498 } 1499 1500 pTmpBuff += (pDecShellContext->mGivenWidth * ( pDecShellContext->mGivenHeight - height)); 1501 for ( index = 0; index < height >> 1; index++) 1502 { 1503 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width >> 1); 1504 pTmpBuffDst += width >> 1; 1505 pTmpBuff += pDecShellContext->mGivenWidth >> 1; 1506 } 1507 1508 pTmpBuff += ((pDecShellContext->mGivenWidth * (pDecShellContext->mGivenHeight - height)) / 4); 1509 for ( index = 0; index < height >> 1; index++) 1510 { 1511 memcpy((void *)pTmpBuffDst, (void *)pTmpBuff, width >> 1); 1512 pTmpBuffDst += width >> 1; 1513 pTmpBuff += pDecShellContext->mGivenWidth >> 1; 1514 } 1515 } 1516 } else { 1517 LOGE("VideoDecoder_decode: unexpected color format 0x%X", 1518 pDecShellContext->decOuputColorFormat); 1519 lerr = M4ERR_PARAMETER; 1520 } 1521 1522 tmpDecBuffer->buffCTS = pDecShellContext->m_lastDecodedCTS; 1523 tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kFilled; 1524 tmpDecBuffer->size = pDecoderBuffer->size(); 1525 1526 return lerr; 1527} 1528 1529M4OSA_ERR VideoEditorVideoDecoder_render(M4OSA_Context context, 1530 M4_MediaTime* pTime, M4VIFI_ImagePlane* pOutputPlane, 1531 M4OSA_Bool bForceRender) { 1532 M4OSA_ERR err = M4NO_ERROR; 1533 VideoEditorVideoDecoder_Context* pDecShellContext = 1534 (VideoEditorVideoDecoder_Context*) context; 1535 M4OSA_UInt32 lindex, i; 1536 M4OSA_UInt8* p_buf_src, *p_buf_dest; 1537 M4VIFI_ImagePlane tmpPlaneIn, tmpPlaneOut; 1538 VIDEOEDITOR_BUFFER_Buffer* pTmpVIDEOEDITORBuffer, *pRenderVIDEOEDITORBuffer 1539 = M4OSA_NULL; 1540 M4_MediaTime candidateTimeStamp = -1; 1541 M4OSA_Bool bFound = M4OSA_FALSE; 1542 1543 LOGV("VideoEditorVideoDecoder_render begin"); 1544 // Input parameters check 1545 VIDEOEDITOR_CHECK(M4OSA_NULL != context, M4ERR_PARAMETER); 1546 VIDEOEDITOR_CHECK(M4OSA_NULL != pTime, M4ERR_PARAMETER); 1547 VIDEOEDITOR_CHECK(M4OSA_NULL != pOutputPlane, M4ERR_PARAMETER); 1548 1549 // The output buffer is already allocated, just copy the data 1550 if ( (*pTime <= pDecShellContext->m_lastRenderCts) && 1551 (M4OSA_FALSE == bForceRender) ) { 1552 LOGV("VIDEOEDITOR_VIDEO_render Frame in the past"); 1553 err = M4WAR_VIDEORENDERER_NO_NEW_FRAME; 1554 goto cleanUp; 1555 } 1556 LOGV("VideoDecoder_render: lastRendered time = %lf,requested render time = " 1557 "%lf", pDecShellContext->m_lastRenderCts, *pTime); 1558 1559 /** 1560 * Find the buffer appropriate for rendering. */ 1561 for (i=0; i < pDecShellContext->m_pDecBufferPool->NB; i++) { 1562 pTmpVIDEOEDITORBuffer = &pDecShellContext->m_pDecBufferPool\ 1563 ->pNXPBuffer[i]; 1564 if (pTmpVIDEOEDITORBuffer->state == VIDEOEDITOR_BUFFER_kFilled) { 1565 /** Free all those buffers older than last rendered frame. */ 1566 if (pTmpVIDEOEDITORBuffer->buffCTS < pDecShellContext->\ 1567 m_lastRenderCts) { 1568 pTmpVIDEOEDITORBuffer->state = VIDEOEDITOR_BUFFER_kEmpty; 1569 } 1570 1571 /** Get the buffer with appropriate timestamp */ 1572 if ( (pTmpVIDEOEDITORBuffer->buffCTS >= pDecShellContext->\ 1573 m_lastRenderCts) && 1574 (pTmpVIDEOEDITORBuffer->buffCTS <= *pTime) && 1575 (pTmpVIDEOEDITORBuffer->buffCTS > candidateTimeStamp)) { 1576 bFound = M4OSA_TRUE; 1577 pRenderVIDEOEDITORBuffer = pTmpVIDEOEDITORBuffer; 1578 candidateTimeStamp = pTmpVIDEOEDITORBuffer->buffCTS; 1579 LOGV("VideoDecoder_render: found a buffer with timestamp = %lf", 1580 candidateTimeStamp); 1581 } 1582 } 1583 } 1584 if (M4OSA_FALSE == bFound) { 1585 err = M4WAR_VIDEORENDERER_NO_NEW_FRAME; 1586 goto cleanUp; 1587 } 1588 1589 LOGV("VideoEditorVideoDecoder_render 3 ouput %d %d %d %d", 1590 pOutputPlane[0].u_width, pOutputPlane[0].u_height, 1591 pOutputPlane[0].u_topleft, pOutputPlane[0].u_stride); 1592 1593 pDecShellContext->m_lastRenderCts = candidateTimeStamp; 1594 1595 if( M4OSA_NULL != pDecShellContext->m_pFilter ) { 1596 // Filtering was requested 1597 M4VIFI_ImagePlane tmpPlane[3]; 1598 // Prepare the output image for conversion 1599 tmpPlane[0].u_width = 1600 pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1601 tmpPlane[0].u_height = 1602 pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1603 tmpPlane[0].u_topleft = 0; 1604 tmpPlane[0].u_stride = tmpPlane[0].u_width; 1605 tmpPlane[0].pac_data = (M4VIFI_UInt8*)pRenderVIDEOEDITORBuffer->pData; 1606 tmpPlane[1].u_width = tmpPlane[0].u_width/2; 1607 tmpPlane[1].u_height = tmpPlane[0].u_height/2; 1608 tmpPlane[1].u_topleft = 0; 1609 tmpPlane[1].u_stride = tmpPlane[0].u_stride/2; 1610 tmpPlane[1].pac_data = tmpPlane[0].pac_data + 1611 (tmpPlane[0].u_stride * tmpPlane[0].u_height); 1612 tmpPlane[2].u_width = tmpPlane[1].u_width; 1613 tmpPlane[2].u_height = tmpPlane[1].u_height; 1614 tmpPlane[2].u_topleft = 0; 1615 tmpPlane[2].u_stride = tmpPlane[1].u_stride; 1616 tmpPlane[2].pac_data = tmpPlane[1].pac_data + 1617 (tmpPlane[1].u_stride * tmpPlane[1].u_height); 1618 1619 LOGV("VideoEditorVideoDecoder_render w = %d H = %d", 1620 tmpPlane[0].u_width,tmpPlane[0].u_height); 1621 pDecShellContext->m_pFilter(M4OSA_NULL, &tmpPlane[0], pOutputPlane); 1622 } else { 1623 // Just copy the YUV420P buffer 1624 M4OSA_MemAddr8 tempBuffPtr = 1625 (M4OSA_MemAddr8)pRenderVIDEOEDITORBuffer->pData; 1626 M4OSA_UInt32 tempWidth = 1627 pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1628 M4OSA_UInt32 tempHeight = 1629 pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1630 1631 memcpy((void *) pOutputPlane[0].pac_data, (void *)tempBuffPtr, 1632 tempWidth * tempHeight); 1633 tempBuffPtr += (tempWidth * tempHeight); 1634 memcpy((void *) pOutputPlane[1].pac_data, (void *)tempBuffPtr, 1635 (tempWidth/2) * (tempHeight/2)); 1636 tempBuffPtr += ((tempWidth/2) * (tempHeight/2)); 1637 memcpy((void *) pOutputPlane[2].pac_data, (void *)tempBuffPtr, 1638 (tempWidth/2) * (tempHeight/2)); 1639 } 1640 1641 pDecShellContext->mNbRenderedFrames++; 1642 if ( 0 > pDecShellContext->mFirstRenderedCts ) { 1643 pDecShellContext->mFirstRenderedCts = *pTime; 1644 } 1645 pDecShellContext->mLastRenderedCts = *pTime; 1646 1647cleanUp: 1648 if( M4NO_ERROR == err ) { 1649 *pTime = pDecShellContext->m_lastRenderCts; 1650 LOGV("VideoEditorVideoDecoder_render no error"); 1651 } else { 1652 LOGV("VideoEditorVideoDecoder_render ERROR 0x%X", err); 1653 } 1654 LOGV("VideoEditorVideoDecoder_render end"); 1655 return err; 1656} 1657 1658M4OSA_ERR VideoEditorVideoDecoder_getInterface(M4DECODER_VideoType decoderType, 1659 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1660 M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL; 1661 1662 pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc( 1663 sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL, 1664 (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" ); 1665 if (M4OSA_NULL == pDecoderInterface) { 1666 return M4ERR_ALLOC; 1667 } 1668 1669 *pDecoderType = decoderType; 1670 1671 pDecoderInterface->m_pFctCreate = VideoEditorVideoDecoder_create; 1672 pDecoderInterface->m_pFctDestroy = VideoEditorVideoDecoder_destroy; 1673 pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption; 1674 pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption; 1675 pDecoderInterface->m_pFctDecode = VideoEditorVideoDecoder_decode; 1676 pDecoderInterface->m_pFctRender = VideoEditorVideoDecoder_render; 1677 1678 *pDecInterface = (M4OSA_Context)pDecoderInterface; 1679 return M4NO_ERROR; 1680} 1681 1682M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_VideoType decoderType, 1683 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1684 M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL; 1685 1686 pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_32bitAlignedMalloc( 1687 sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL, 1688 (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" ); 1689 if (M4OSA_NULL == pDecoderInterface) { 1690 return M4ERR_ALLOC; 1691 } 1692 1693 *pDecoderType = decoderType; 1694 1695 pDecoderInterface->m_pFctCreate = VideoEditorVideoSoftwareDecoder_create; 1696 pDecoderInterface->m_pFctDestroy = VideoEditorVideoDecoder_destroy; 1697 pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption; 1698 pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption; 1699 pDecoderInterface->m_pFctDecode = VideoEditorVideoDecoder_decode; 1700 pDecoderInterface->m_pFctRender = VideoEditorVideoDecoder_render; 1701 1702 *pDecInterface = (M4OSA_Context)pDecoderInterface; 1703 return M4NO_ERROR; 1704} 1705extern "C" { 1706 1707M4OSA_ERR VideoEditorVideoDecoder_getInterface_MPEG4( 1708 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1709 return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeMPEG4, 1710 pDecoderType, pDecInterface); 1711} 1712 1713M4OSA_ERR VideoEditorVideoDecoder_getInterface_H264( 1714 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1715 return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeAVC, 1716 pDecoderType, pDecInterface); 1717 1718} 1719 1720M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface_MPEG4( 1721 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1722 return VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_kVideoTypeMPEG4, 1723 pDecoderType, pDecInterface); 1724} 1725 1726M4OSA_ERR VideoEditorVideoDecoder_getSoftwareInterface_H264( 1727 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1728 return VideoEditorVideoDecoder_getSoftwareInterface(M4DECODER_kVideoTypeAVC, 1729 pDecoderType, pDecInterface); 1730 1731} 1732 1733M4OSA_ERR VideoEditorVideoDecoder_getVideoDecodersAndCapabilities( 1734 M4DECODER_VideoDecoders** decoders) { 1735 return queryVideoDecoderCapabilities(decoders); 1736} 1737 1738} // extern "C" 1739