VideoEditorVideoDecoder.cpp revision 7c9d8018755adf1857571125ba1b3598c96ea506
1/* 2 * Copyright (C) 2011 NXP Software 3 * Copyright (C) 2011 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17/** 18************************************************************************* 19* @file VideoEditorVideoDecoder.cpp 20* @brief StageFright shell video decoder 21************************************************************************* 22*/ 23#define LOG_NDEBUG 1 24#define LOG_TAG "VIDEOEDITOR_VIDEODECODER" 25 26/******************* 27 * HEADERS * 28 *******************/ 29 30#include "VideoEditorVideoDecoder_internal.h" 31#include "VideoEditorUtils.h" 32#include "M4VD_Tools.h" 33 34#include <media/stagefright/MetaData.h> 35#include <media/stagefright/MediaDefs.h> 36 37/******************** 38 * DEFINITIONS * 39 ********************/ 40#define OMX_QCOM_COLOR_FormatYVU420SemiPlanar 0x7FA30C00 41#define MAX_DEC_BUFFERS 10 42 43/******************** 44 * SOURCE CLASS * 45 ********************/ 46using namespace android; 47 48class VideoEditorVideoDecoderSource : public MediaSource { 49 public: 50 VideoEditorVideoDecoderSource(const sp<MetaData> &format, 51 VIDEOEDITOR_CodecType codecType, void *decoderShellContext); 52 virtual status_t start(MetaData *params = NULL); 53 virtual status_t stop(); 54 virtual sp<MetaData> getFormat(); 55 virtual status_t read( 56 MediaBuffer **buffer, const ReadOptions *options = NULL); 57 58 protected : 59 virtual ~VideoEditorVideoDecoderSource(); 60 61 private: 62 sp<MetaData> mFormat; 63 MediaBuffer* mBuffer; 64 MediaBufferGroup* mGroup; 65 Mutex mLock; 66 VideoEditorVideoDecoder_Context* mpDecShellContext; 67 int32_t mMaxAUSize; 68 bool mStarted; 69 VIDEOEDITOR_CodecType mCodecType; 70 VideoEditorVideoDecoderSource(const MediaSource &); 71 VideoEditorVideoDecoderSource &operator=(const MediaSource &); 72}; 73 74VideoEditorVideoDecoderSource::VideoEditorVideoDecoderSource( 75 const sp<MetaData> &format, VIDEOEDITOR_CodecType codecType, 76 void *decoderShellContext) : 77 mFormat(format), 78 mBuffer(NULL), 79 mGroup(NULL), 80 mStarted(false), 81 mCodecType(codecType) { 82 mpDecShellContext = (VideoEditorVideoDecoder_Context*) decoderShellContext; 83} 84 85VideoEditorVideoDecoderSource::~VideoEditorVideoDecoderSource() { 86 if (mStarted == true) { 87 stop(); 88 } 89} 90 91status_t VideoEditorVideoDecoderSource::start( 92 MetaData *params) { 93 94 LOGV("VideoEditorVideoDecoderSource::start() begin "); 95 if (!mStarted) { 96 if(mFormat->findInt32(kKeyMaxInputSize, &mMaxAUSize) == false) { 97 LOGW("FATAL: Should never happen "); 98 mMaxAUSize = 10000; 99 } 100 101 mGroup = new MediaBufferGroup; 102 if(mGroup == NULL) { 103 LOGE("FATAL: memory limitation ! "); 104 return NO_MEMORY; 105 } 106 LOGV("VideoEditorVideoDecoderSource:adding buffer to group MaxSize= %d", 107 mMaxAUSize); 108 mGroup->add_buffer(new MediaBuffer(mMaxAUSize)); 109 110 mStarted = true; 111 } 112 LOGV("VideoEditorVideoDecoderSource::start() end OK"); 113 return OK; 114} 115 116status_t VideoEditorVideoDecoderSource::stop() { 117 int ref_count = 0; 118 int i; 119 120 LOGV("VideoEditorVideoDecoderSource::stop() begin"); 121 if (mStarted) { 122 if(mBuffer != NULL) { 123 ref_count = mBuffer->refcount(); 124 LOGV("MediaBuffer refcount is %d",ref_count); 125 for (i=0; i< ref_count; i++) { 126 mBuffer->release(); 127 } 128 129 mBuffer = NULL; 130 } 131 delete mGroup; 132 mGroup = NULL; 133 mStarted = false; 134 } 135 LOGV("VideoEditorVideoDecoderSource::stop() end"); 136 return OK; 137} 138 139sp<MetaData> VideoEditorVideoDecoderSource::getFormat() { 140 Mutex::Autolock autolock(mLock); 141 142 return mFormat; 143} 144 145status_t VideoEditorVideoDecoderSource::read(MediaBuffer** buffer_out, 146 const ReadOptions *options) { 147 148 Mutex::Autolock autolock(mLock); 149 //We donot use read options on decoder hence dont impliment this option here 150 M4_AccessUnit* pAccessUnit = mpDecShellContext->m_pNextAccessUnitToDecode; 151 M4OSA_UInt32 lSize = 0; 152 M4OSA_ERR lerr = M4NO_ERROR; 153 int64_t frameTime; 154 155 *buffer_out = NULL; 156 157 LOGV("VideoEditorVideoDecoderSource::read begin"); 158 159 if (options) { 160 int64_t time = 0; 161 ReadOptions::SeekMode mode = ReadOptions::SEEK_CLOSEST_SYNC; 162 bool hasOptions = FALSE; 163 hasOptions = options->getSeekTo(&time, &mode); 164 if (hasOptions) { 165 LOGV("VideoEditorVideoDecoderSource: Options is not NULL %lld %d", 166 time, mode); 167 } else { 168 LOGV("VideoEditorVideoDecoderSource: Options is not NULL ****"); 169 } 170 } 171 lerr = mGroup->acquire_buffer(&mBuffer); 172 if (lerr != OK) { 173 return lerr; 174 } 175 LOGV("VideoEditorVideoDecoderSource: got a buffer from group"); 176 177 if (mStarted) { 178 //getNext AU from reader. 179 lerr = mpDecShellContext->m_pReader->m_pFctGetNextAu( 180 mpDecShellContext->m_pReader->m_readerContext, 181 (M4_StreamHandler*)mpDecShellContext->m_pVideoStreamhandler, 182 pAccessUnit); 183 if (lerr == M4WAR_NO_DATA_YET) { 184 LOGV("VideoEditorVideoDecoderSource::read() M4WAR_NO_DATA_YET"); 185 mBuffer->set_range(0, 0); 186 mBuffer->meta_data()->clear(); 187 188 *buffer_out = mBuffer; 189 } 190 if (lerr == M4WAR_NO_MORE_AU) { 191 LOGV("VideoEditorVideoDecoderSource::read() returning err = " 192 "ERROR_END_OF_STREAM;"); 193 *buffer_out = NULL; 194 return ERROR_END_OF_STREAM; 195 } 196 LOGV("VideoEditorVideoDecoderSource: getNextAU succesful ts = %lf", 197 pAccessUnit->m_CTS); 198 199 //copy the reader AU buffer to mBuffer 200 lSize = (pAccessUnit->m_size > (M4OSA_UInt32)mMaxAUSize)\ 201 ? (M4OSA_UInt32)mMaxAUSize : pAccessUnit->m_size; 202 LOGV("VideoDecoderSource:Read() copying AU to i/p buffer of decoder," 203 "Bufer Add = 0x%x, size = %d", mBuffer->data(), lSize); 204 M4OSA_memcpy((M4OSA_MemAddr8)mBuffer->data(),pAccessUnit->m_dataAddress, 205 lSize); 206 207 mBuffer->set_range(0, lSize); 208 mBuffer->meta_data()->clear(); 209 frameTime = (int64_t)pAccessUnit->m_CTS; 210 mBuffer->meta_data()->setInt64(kKeyTime, (int64_t)frameTime*1000); 211 212 // Replace the AU start code for H264 213 if (VIDEOEDITOR_kH264VideoDec == mCodecType) { 214 uint8_t *data =(uint8_t *)mBuffer->data() + mBuffer->range_offset(); 215 data[0]=0; 216 data[1]=0; 217 data[2]=0; 218 data[3]=1; 219 } 220 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 221 (pAccessUnit->m_attribute == 0x04)? 1 : 0); 222 *buffer_out = mBuffer; 223 } 224 LOGV("VideoEditorVideoDecoderSource::read end"); 225 return OK; 226} 227/******************** 228 * TOOLS * 229 ********************/ 230 231static M4OSA_UInt32 VideoEditorVideoDecoder_GetBitsFromMemory( 232 VIDEOEDITOR_VIDEO_Bitstream_ctxt* parsingCtxt, M4OSA_UInt32 nb_bits) { 233 return (M4VD_Tools_GetBitsFromMemory((M4VS_Bitstream_ctxt*) parsingCtxt, 234 nb_bits)); 235} 236 237M4OSA_ERR VideoEditorVideoDecoder_internalParseVideoDSI(M4OSA_UInt8* pVol, 238 M4OSA_Int32 aVolSize, M4DECODER_MPEG4_DecoderConfigInfo* pDci, 239 M4DECODER_VideoSize* pVideoSize) { 240 241 VIDEOEDITOR_VIDEO_Bitstream_ctxt parsingCtxt; 242 M4OSA_UInt32 code, j; 243 M4OSA_MemAddr8 start; 244 M4OSA_UInt8 i; 245 M4OSA_UInt32 time_incr_length; 246 M4OSA_UInt8 vol_verid=0, b_hierarchy_type; 247 248 /* Parsing variables */ 249 M4OSA_UInt8 video_object_layer_shape = 0; 250 M4OSA_UInt8 sprite_enable = 0; 251 M4OSA_UInt8 reduced_resolution_vop_enable = 0; 252 M4OSA_UInt8 scalability = 0; 253 M4OSA_UInt8 enhancement_type = 0; 254 M4OSA_UInt8 complexity_estimation_disable = 0; 255 M4OSA_UInt8 interlaced = 0; 256 M4OSA_UInt8 sprite_warping_points = 0; 257 M4OSA_UInt8 sprite_brightness_change = 0; 258 M4OSA_UInt8 quant_precision = 0; 259 260 /* Fill the structure with default parameters */ 261 pVideoSize->m_uiWidth = 0; 262 pVideoSize->m_uiHeight = 0; 263 264 pDci->uiTimeScale = 0; 265 pDci->uiProfile = 0; 266 pDci->uiUseOfResynchMarker = 0; 267 pDci->bDataPartition = M4OSA_FALSE; 268 pDci->bUseOfRVLC = M4OSA_FALSE; 269 270 /* Reset the bitstream context */ 271 parsingCtxt.stream_byte = 0; 272 parsingCtxt.stream_index = 8; 273 parsingCtxt.in = (M4OSA_MemAddr8) pVol; 274 275 start = (M4OSA_MemAddr8) pVol; 276 277 /* Start parsing */ 278 while (parsingCtxt.in - start < aVolSize) { 279 code = VideoEditorVideoDecoder_GetBitsFromMemory(&parsingCtxt, 8); 280 if (code == 0) { 281 code = VideoEditorVideoDecoder_GetBitsFromMemory(&parsingCtxt, 8); 282 if (code == 0) { 283 code = VideoEditorVideoDecoder_GetBitsFromMemory(&parsingCtxt,8); 284 if (code == 1) { 285 /* start code found */ 286 code = VideoEditorVideoDecoder_GetBitsFromMemory( 287 &parsingCtxt, 8); 288 289 /* ----- 0x20..0x2F : video_object_layer_start_code ----- */ 290 291 if ((code > 0x1F) && (code < 0x30)) { 292 code = VideoEditorVideoDecoder_GetBitsFromMemory( 293 &parsingCtxt, 1); 294 code = VideoEditorVideoDecoder_GetBitsFromMemory( 295 &parsingCtxt, 8); 296 code = VideoEditorVideoDecoder_GetBitsFromMemory( 297 &parsingCtxt, 1); 298 if (code == 1) { 299 code = VideoEditorVideoDecoder_GetBitsFromMemory( 300 &parsingCtxt, 4); 301 vol_verid = (M4OSA_UInt8)code; 302 code = VideoEditorVideoDecoder_GetBitsFromMemory( 303 &parsingCtxt, 3); 304 } 305 code = VideoEditorVideoDecoder_GetBitsFromMemory( 306 &parsingCtxt, 4); 307 if (code == 15) { 308 code = VideoEditorVideoDecoder_GetBitsFromMemory( 309 &parsingCtxt, 16); 310 } 311 code = VideoEditorVideoDecoder_GetBitsFromMemory( 312 &parsingCtxt, 1); 313 if (code == 1) { 314 code = VideoEditorVideoDecoder_GetBitsFromMemory( 315 &parsingCtxt, 3); 316 code = VideoEditorVideoDecoder_GetBitsFromMemory( 317 &parsingCtxt, 1); 318 if (code == 1) { 319 code = VideoEditorVideoDecoder_GetBitsFromMemory( 320 &parsingCtxt, 32); 321 code = VideoEditorVideoDecoder_GetBitsFromMemory( 322 &parsingCtxt, 31); 323 code = VideoEditorVideoDecoder_GetBitsFromMemory( 324 &parsingCtxt, 16); 325 } 326 } 327 code = VideoEditorVideoDecoder_GetBitsFromMemory( 328 &parsingCtxt, 2); 329 /* Need to save it for vop parsing */ 330 video_object_layer_shape = (M4OSA_UInt8)code; 331 332 if (code != 0) { 333 return 0; /* only rectangular case supported */ 334 } 335 336 code = VideoEditorVideoDecoder_GetBitsFromMemory( 337 &parsingCtxt, 1); 338 code = VideoEditorVideoDecoder_GetBitsFromMemory( 339 &parsingCtxt, 16); 340 pDci->uiTimeScale = code; 341 342 /* Computes time increment length */ 343 j = code - 1; 344 for (i = 0; (i < 32) && (j != 0); j >>=1) { 345 i++; 346 } 347 time_incr_length = (i == 0) ? 1 : i; 348 349 code = VideoEditorVideoDecoder_GetBitsFromMemory( 350 &parsingCtxt, 1); 351 code = VideoEditorVideoDecoder_GetBitsFromMemory( 352 &parsingCtxt, 1); 353 if (code == 1) { 354 code = VideoEditorVideoDecoder_GetBitsFromMemory( 355 &parsingCtxt, time_incr_length); 356 } 357 358 if(video_object_layer_shape != 1) { /* 1 = Binary */ 359 if(video_object_layer_shape == 0) { 360 code = VideoEditorVideoDecoder_GetBitsFromMemory( 361 &parsingCtxt, 1);/* Marker bit */ 362 code = VideoEditorVideoDecoder_GetBitsFromMemory( 363 &parsingCtxt, 13);/* Width */ 364 pVideoSize->m_uiWidth = code; 365 code = VideoEditorVideoDecoder_GetBitsFromMemory( 366 &parsingCtxt, 1);/* Marker bit */ 367 code = VideoEditorVideoDecoder_GetBitsFromMemory( 368 &parsingCtxt, 13);/* Height */ 369 pVideoSize->m_uiHeight = code; 370 code = VideoEditorVideoDecoder_GetBitsFromMemory( 371 &parsingCtxt, 1);/* Marker bit */ 372 } 373 } 374 375 code = VideoEditorVideoDecoder_GetBitsFromMemory( 376 &parsingCtxt, 1);/* interlaced */ 377 interlaced = (M4OSA_UInt8)code; 378 code = VideoEditorVideoDecoder_GetBitsFromMemory( 379 &parsingCtxt, 1);/* OBMC disable */ 380 381 if(vol_verid == 1) { 382 code = VideoEditorVideoDecoder_GetBitsFromMemory( 383 &parsingCtxt, 1);/* sprite enable */ 384 sprite_enable = (M4OSA_UInt8)code; 385 } else { 386 code = VideoEditorVideoDecoder_GetBitsFromMemory( 387 &parsingCtxt, 2);/* sprite enable */ 388 sprite_enable = (M4OSA_UInt8)code; 389 } 390 if ((sprite_enable == 1) || (sprite_enable == 2)) { 391 if (sprite_enable != 2) { 392 393 code = VideoEditorVideoDecoder_GetBitsFromMemory( 394 &parsingCtxt, 13);/* sprite width */ 395 code = VideoEditorVideoDecoder_GetBitsFromMemory( 396 &parsingCtxt, 1);/* Marker bit */ 397 code = VideoEditorVideoDecoder_GetBitsFromMemory( 398 &parsingCtxt, 13);/* sprite height */ 399 code = VideoEditorVideoDecoder_GetBitsFromMemory( 400 &parsingCtxt, 1);/* Marker bit */ 401 code = VideoEditorVideoDecoder_GetBitsFromMemory( 402 &parsingCtxt, 13);/* sprite l coordinate */ 403 code = VideoEditorVideoDecoder_GetBitsFromMemory( 404 &parsingCtxt, 1);/* Marker bit */ 405 code = VideoEditorVideoDecoder_GetBitsFromMemory( 406 &parsingCtxt, 13);/* sprite top coordinate */ 407 code = VideoEditorVideoDecoder_GetBitsFromMemory( 408 &parsingCtxt, 1);/* Marker bit */ 409 } 410 411 code = VideoEditorVideoDecoder_GetBitsFromMemory( 412 &parsingCtxt, 6);/* sprite warping points */ 413 sprite_warping_points = (M4OSA_UInt8)code; 414 code = VideoEditorVideoDecoder_GetBitsFromMemory( 415 &parsingCtxt, 2);/* sprite warping accuracy */ 416 code = VideoEditorVideoDecoder_GetBitsFromMemory( 417 &parsingCtxt, 1);/* sprite brightness change */ 418 sprite_brightness_change = (M4OSA_UInt8)code; 419 if (sprite_enable != 2) { 420 code = VideoEditorVideoDecoder_GetBitsFromMemory( 421 &parsingCtxt, 1); 422 } 423 } 424 if ((vol_verid != 1) && (video_object_layer_shape != 0)){ 425 code = VideoEditorVideoDecoder_GetBitsFromMemory( 426 &parsingCtxt, 1);/* sadct disable */ 427 } 428 429 code = VideoEditorVideoDecoder_GetBitsFromMemory( 430 &parsingCtxt, 1); /* not 8 bits */ 431 if (code) { 432 code = VideoEditorVideoDecoder_GetBitsFromMemory( 433 &parsingCtxt, 4);/* quant precision */ 434 quant_precision = (M4OSA_UInt8)code; 435 code = VideoEditorVideoDecoder_GetBitsFromMemory( 436 &parsingCtxt, 4);/* bits per pixel */ 437 } 438 439 /* greyscale not supported */ 440 if(video_object_layer_shape == 3) { 441 code = VideoEditorVideoDecoder_GetBitsFromMemory( 442 &parsingCtxt, 3); 443 } 444 445 code = VideoEditorVideoDecoder_GetBitsFromMemory( 446 &parsingCtxt, 1);/* quant type */ 447 if (code) { 448 code = VideoEditorVideoDecoder_GetBitsFromMemory( 449 &parsingCtxt, 1);/* load intra quant mat */ 450 if (code) { 451 code = VideoEditorVideoDecoder_GetBitsFromMemory( 452 &parsingCtxt, 8);/* */ 453 i = 1; 454 while (i < 64) { 455 code = 456 VideoEditorVideoDecoder_GetBitsFromMemory( 457 &parsingCtxt, 8); 458 if (code == 0) { 459 break; 460 } 461 i++; 462 } 463 } 464 465 code = VideoEditorVideoDecoder_GetBitsFromMemory( 466 &parsingCtxt, 1);/* load non intra quant mat */ 467 if (code) { 468 code = VideoEditorVideoDecoder_GetBitsFromMemory( 469 &parsingCtxt, 8);/* */ 470 i = 1; 471 while (i < 64) { 472 code = 473 VideoEditorVideoDecoder_GetBitsFromMemory( 474 &parsingCtxt, 8); 475 if (code == 0) { 476 break; 477 } 478 i++; 479 } 480 } 481 } 482 483 if (vol_verid != 1) { 484 code = VideoEditorVideoDecoder_GetBitsFromMemory( 485 &parsingCtxt, 1);/* quarter sample */ 486 } 487 488 code = VideoEditorVideoDecoder_GetBitsFromMemory( 489 &parsingCtxt, 1);/* complexity estimation disable */ 490 complexity_estimation_disable = (M4OSA_UInt8)code; 491 if (!code) { 492 //return M4ERR_NOT_IMPLEMENTED; 493 } 494 495 code = VideoEditorVideoDecoder_GetBitsFromMemory( 496 &parsingCtxt, 1);/* resync marker disable */ 497 pDci->uiUseOfResynchMarker = (code) ? 0 : 1; 498 499 code = VideoEditorVideoDecoder_GetBitsFromMemory( 500 &parsingCtxt, 1);/* data partitionned */ 501 pDci->bDataPartition = (code) ? M4OSA_TRUE : M4OSA_FALSE; 502 if (code) { 503 code = VideoEditorVideoDecoder_GetBitsFromMemory( 504 &parsingCtxt, 1);/* reversible VLC */ 505 pDci->bUseOfRVLC = (code) ? M4OSA_TRUE : M4OSA_FALSE; 506 } 507 508 if (vol_verid != 1) { 509 code = VideoEditorVideoDecoder_GetBitsFromMemory( 510 &parsingCtxt, 1);/* newpred */ 511 if (code) { 512 //return M4ERR_PARAMETER; 513 } 514 515 code = VideoEditorVideoDecoder_GetBitsFromMemory( 516 &parsingCtxt, 1); 517 reduced_resolution_vop_enable = (M4OSA_UInt8)code; 518 } 519 520 code = VideoEditorVideoDecoder_GetBitsFromMemory( 521 &parsingCtxt, 1);/* scalability */ 522 scalability = (M4OSA_UInt8)code; 523 if (code) { 524 code = VideoEditorVideoDecoder_GetBitsFromMemory( 525 &parsingCtxt, 1);/* hierarchy type */ 526 b_hierarchy_type = (M4OSA_UInt8)code; 527 code = VideoEditorVideoDecoder_GetBitsFromMemory( 528 &parsingCtxt, 4);/* ref layer id */ 529 code = VideoEditorVideoDecoder_GetBitsFromMemory( 530 &parsingCtxt, 1);/* ref sampling direct */ 531 code = VideoEditorVideoDecoder_GetBitsFromMemory( 532 &parsingCtxt, 5);/* hor sampling factor N */ 533 code = VideoEditorVideoDecoder_GetBitsFromMemory( 534 &parsingCtxt, 5);/* hor sampling factor M */ 535 code = VideoEditorVideoDecoder_GetBitsFromMemory( 536 &parsingCtxt, 5);/* vert sampling factor N */ 537 code = VideoEditorVideoDecoder_GetBitsFromMemory( 538 &parsingCtxt, 5);/* vert sampling factor M */ 539 code = VideoEditorVideoDecoder_GetBitsFromMemory( 540 &parsingCtxt, 1);/* enhancement type */ 541 enhancement_type = (M4OSA_UInt8)code; 542 if ((!b_hierarchy_type) && 543 (video_object_layer_shape == 1)) { 544 code = VideoEditorVideoDecoder_GetBitsFromMemory( 545 &parsingCtxt, 1);/* use ref shape */ 546 code = VideoEditorVideoDecoder_GetBitsFromMemory( 547 &parsingCtxt, 1);/* use ref texture */ 548 code = VideoEditorVideoDecoder_GetBitsFromMemory( 549 &parsingCtxt, 5); 550 code = VideoEditorVideoDecoder_GetBitsFromMemory( 551 &parsingCtxt, 5); 552 code = VideoEditorVideoDecoder_GetBitsFromMemory( 553 &parsingCtxt, 5); 554 code = VideoEditorVideoDecoder_GetBitsFromMemory( 555 &parsingCtxt, 5); 556 } 557 } 558 break; 559 } 560 561 /* ----- 0xB0 : visual_object_sequence_start_code ----- */ 562 563 else if(code == 0xB0) { 564 code = VideoEditorVideoDecoder_GetBitsFromMemory( 565 &parsingCtxt, 8);/* profile_and_level_indication */ 566 pDci->uiProfile = (M4OSA_UInt8)code; 567 } 568 569 /* ----- 0xB5 : visual_object_start_code ----- */ 570 571 else if(code == 0xB5) { 572 code = VideoEditorVideoDecoder_GetBitsFromMemory( 573 &parsingCtxt, 1);/* is object layer identifier */ 574 if (code == 1) { 575 code = VideoEditorVideoDecoder_GetBitsFromMemory( 576 &parsingCtxt, 4); /* visual object verid */ 577 vol_verid = (M4OSA_UInt8)code; 578 code = VideoEditorVideoDecoder_GetBitsFromMemory( 579 &parsingCtxt, 3); 580 } else { 581 code = VideoEditorVideoDecoder_GetBitsFromMemory( 582 &parsingCtxt, 7); /* Realign on byte */ 583 vol_verid = 1; 584 } 585 } 586 587 /* ----- end ----- */ 588 } else { 589 if ((code >> 2) == 0x20) { 590 /* H263 ...-> wrong*/ 591 break; 592 } 593 } 594 } 595 } 596 } 597 return M4NO_ERROR; 598} 599 600M4VIFI_UInt8 M4VIFI_SemiplanarYVU420toYUV420(void *user_data, 601 M4VIFI_UInt8 *inyuv, M4VIFI_ImagePlane *PlaneOut ) { 602 M4VIFI_UInt8 return_code = M4VIFI_OK; 603 M4VIFI_UInt8 *outyuv = 604 ((M4VIFI_UInt8*)&(PlaneOut[0].pac_data[PlaneOut[0].u_topleft])); 605 int32_t width = PlaneOut[0].u_width; 606 int32_t height = PlaneOut[0].u_height; 607 608 int32_t outYsize = width * height; 609 uint32_t *outy = (uint32_t *) outyuv; 610 uint16_t *outcb = 611 (uint16_t *) &(PlaneOut[1].pac_data[PlaneOut[1].u_topleft]); 612 uint16_t *outcr = 613 (uint16_t *) &(PlaneOut[2].pac_data[PlaneOut[2].u_topleft]); 614 615 /* Y copying */ 616 memcpy(outy, inyuv, outYsize); 617 618 /* U & V copying */ 619 uint32_t *inyuv_4 = (uint32_t *) (inyuv + outYsize); 620 for (int32_t i = height >> 1; i > 0; --i) { 621 for (int32_t j = width >> 2; j > 0; --j) { 622 uint32_t temp = *inyuv_4++; 623 uint32_t tempU = temp & 0xFF; 624 tempU = tempU | ((temp >> 8) & 0xFF00); 625 626 uint32_t tempV = (temp >> 8) & 0xFF; 627 tempV = tempV | ((temp >> 16) & 0xFF00); 628 629 // Flip U and V 630 *outcb++ = tempV; 631 *outcr++ = tempU; 632 } 633 } 634 return return_code; 635} 636 637M4OSA_ERR VideoEditorVideoDecoder_ParseAVCDSI(M4OSA_UInt8* pDSI, 638 M4OSA_Int32 DSISize, M4DECODER_AVCProfileLevel *profile) { 639 M4OSA_ERR err = M4NO_ERROR; 640 M4OSA_Bool NALSPS_and_Profile0Found = M4OSA_FALSE; 641 M4OSA_UInt16 index; 642 M4OSA_Bool constraintSet3; 643 644 for(index = 0; index < (DSISize-1); index++) { 645 if(((pDSI[index] & 0x1f) == 0x07) && (pDSI[index+1] == 0x42)) { 646 NALSPS_and_Profile0Found = M4OSA_TRUE; 647 break; 648 } 649 } 650 if(M4OSA_FALSE == NALSPS_and_Profile0Found) { 651 LOGV("VideoEditorVideoDecoder_ParseAVCDSI: index bad = %d", index); 652 *profile = M4DECODER_AVC_kProfile_and_Level_Out_Of_Range; 653 } else { 654 LOGV("VideoEditorVideoDecoder_ParseAVCDSI: index = %d", index); 655 constraintSet3 = (pDSI[index+2] & 0x10); 656 LOGV("VideoEditorVideoDecoder_ParseAVCDSI: level = %d", pDSI[index+3]); 657 switch(pDSI[index+3]) { 658 case 10: 659 *profile = M4DECODER_AVC_kProfile_0_Level_1; 660 break; 661 case 11: 662 if(constraintSet3) { 663 *profile = M4DECODER_AVC_kProfile_0_Level_1b; 664 } else { 665 *profile = M4DECODER_AVC_kProfile_0_Level_1_1; 666 } 667 break; 668 case 12: 669 *profile = M4DECODER_AVC_kProfile_0_Level_1_2; 670 break; 671 case 13: 672 *profile = M4DECODER_AVC_kProfile_0_Level_1_3; 673 break; 674 case 20: 675 *profile = M4DECODER_AVC_kProfile_0_Level_2; 676 break; 677 case 21: 678 *profile = M4DECODER_AVC_kProfile_0_Level_2_1; 679 break; 680 case 22: 681 *profile = M4DECODER_AVC_kProfile_0_Level_2_2; 682 break; 683 case 30: 684 *profile = M4DECODER_AVC_kProfile_0_Level_3; 685 break; 686 case 31: 687 *profile = M4DECODER_AVC_kProfile_0_Level_3_1; 688 break; 689 case 32: 690 *profile = M4DECODER_AVC_kProfile_0_Level_3_2; 691 break; 692 case 40: 693 *profile = M4DECODER_AVC_kProfile_0_Level_4; 694 break; 695 case 41: 696 *profile = M4DECODER_AVC_kProfile_0_Level_4_1; 697 break; 698 case 42: 699 *profile = M4DECODER_AVC_kProfile_0_Level_4_2; 700 break; 701 case 50: 702 *profile = M4DECODER_AVC_kProfile_0_Level_5; 703 break; 704 case 51: 705 *profile = M4DECODER_AVC_kProfile_0_Level_5_1; 706 break; 707 default: 708 *profile = M4DECODER_AVC_kProfile_and_Level_Out_Of_Range; 709 } 710 } 711 return err; 712} 713/******************** 714 * ENGINE INTERFACE * 715 ********************/ 716M4OSA_ERR VideoEditorVideoDecoder_configureFromMetadata(M4OSA_Context pContext, 717 MetaData* meta) { 718 M4OSA_ERR err = M4NO_ERROR; 719 VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL; 720 bool success = OK; 721 int32_t width = 0; 722 int32_t height = 0; 723 int32_t frameSize = 0; 724 725 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 726 VIDEOEDITOR_CHECK(M4OSA_NULL != meta, M4ERR_PARAMETER); 727 728 LOGV("VideoEditorVideoDecoder_configureFromMetadata begin"); 729 730 pDecShellContext = (VideoEditorVideoDecoder_Context*)pContext; 731 732 // Get the parameters 733 success = meta->findInt32(kKeyWidth, &width); 734 success &= meta->findInt32(kKeyHeight, &height); 735 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 736 737 LOGV("VideoDecoder_configureFromMetadata : W=%d H=%d", width, height); 738 VIDEOEDITOR_CHECK((0 != width) && (0 != height), M4ERR_PARAMETER); 739 740 LOGV("VideoDecoder_configureFromMetadata : W=%d H=%d", width, height); 741 742 if( (M4OSA_NULL != pDecShellContext->m_pDecBufferPool) && 743 (pDecShellContext->m_pVideoStreamhandler->m_videoWidth == \ 744 (uint32_t)width) && 745 (pDecShellContext->m_pVideoStreamhandler->m_videoHeight == \ 746 (uint32_t)height) ) { 747 // No need to reconfigure 748 goto cleanUp; 749 } 750 LOGV("VideoDecoder_configureFromMetadata reset: W=%d H=%d", width, height); 751 // Update the stream handler parameters 752 pDecShellContext->m_pVideoStreamhandler->m_videoWidth = width; 753 pDecShellContext->m_pVideoStreamhandler->m_videoHeight = height; 754 frameSize = (width * height * 3) / 2; 755 756 // Configure the buffer pool 757 if( M4OSA_NULL != pDecShellContext->m_pDecBufferPool ) { 758 LOGV("VideoDecoder_configureFromMetadata : reset the buffer pool"); 759 VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool); 760 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 761 } 762 err = VIDEOEDITOR_BUFFER_allocatePool(&pDecShellContext->m_pDecBufferPool, 763 MAX_DEC_BUFFERS, (M4OSA_Char*)"VIDEOEDITOR_DecodedBufferPool"); 764 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 765 err = VIDEOEDITOR_BUFFER_initPoolBuffers(pDecShellContext->m_pDecBufferPool, 766 frameSize + width * 2); 767 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 768 769cleanUp: 770 if( M4NO_ERROR == err ) { 771 LOGV("VideoEditorVideoDecoder_configureFromMetadata no error"); 772 } else { 773 if( M4OSA_NULL != pDecShellContext->m_pDecBufferPool ) { 774 VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool); 775 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 776 } 777 LOGV("VideoEditorVideoDecoder_configureFromMetadata ERROR 0x%X", err); 778 } 779 LOGV("VideoEditorVideoDecoder_configureFromMetadata end"); 780 return err; 781} 782 783M4OSA_ERR VideoEditorVideoDecoder_destroy(M4OSA_Context pContext) { 784 M4OSA_ERR err = M4NO_ERROR; 785 VideoEditorVideoDecoder_Context* pDecShellContext = 786 (VideoEditorVideoDecoder_Context*)pContext; 787 788 // Input parameters check 789 LOGV("VideoEditorVideoDecoder_destroy begin"); 790 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 791 792 // Destroy the graph 793 if( pDecShellContext->mVideoDecoder != NULL ) { 794 LOGV("### VideoEditorVideoDecoder_destroy : releasing decoder"); 795 pDecShellContext->mVideoDecoder->stop(); 796 pDecShellContext->mVideoDecoder.clear(); 797 } 798 pDecShellContext->mClient.disconnect(); 799 pDecShellContext->mReaderSource.clear(); 800 801 // Release memory 802 if( pDecShellContext->m_pDecBufferPool != M4OSA_NULL ) { 803 VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool); 804 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 805 } 806 SAFE_FREE(pDecShellContext); 807 pContext = NULL; 808 809cleanUp: 810 if( M4NO_ERROR == err ) { 811 LOGV("VideoEditorVideoDecoder_destroy no error"); 812 } else { 813 LOGV("VideoEditorVideoDecoder_destroy ERROR 0x%X", err); 814 } 815 LOGV("VideoEditorVideoDecoder_destroy end"); 816 return err; 817} 818 819M4OSA_ERR VideoEditorVideoDecoder_create(M4OSA_Context *pContext, 820 M4_StreamHandler *pStreamHandler, 821 M4READER_DataInterface *pReaderDataInterface, 822 M4_AccessUnit *pAccessUnit, M4OSA_Void *pUserData) { 823 M4OSA_ERR err = M4NO_ERROR; 824 VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL; 825 status_t status = OK; 826 bool success = TRUE; 827 int32_t colorFormat = 0; 828 M4OSA_UInt32 size = 0; 829 sp<MetaData> decoderMetadata = NULL; 830 831 LOGV("VideoEditorVideoDecoder_create begin"); 832 // Input parameters check 833 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 834 VIDEOEDITOR_CHECK(M4OSA_NULL != pStreamHandler, M4ERR_PARAMETER); 835 VIDEOEDITOR_CHECK(M4OSA_NULL != pReaderDataInterface, M4ERR_PARAMETER); 836 837 // Context allocation & initialization 838 SAFE_MALLOC(pDecShellContext, VideoEditorVideoDecoder_Context, 1, 839 "VideoEditorVideoDecoder"); 840 pDecShellContext->m_pVideoStreamhandler = 841 (M4_VideoStreamHandler*)pStreamHandler; 842 pDecShellContext->m_pNextAccessUnitToDecode = pAccessUnit; 843 pDecShellContext->m_pReader = pReaderDataInterface; 844 pDecShellContext->m_lastDecodedCTS = -1; 845 pDecShellContext->m_lastRenderCts = -1; 846 switch( pStreamHandler->m_streamType ) { 847 case M4DA_StreamTypeVideoH263: 848 pDecShellContext->mDecoderType = VIDEOEDITOR_kH263VideoDec; 849 break; 850 case M4DA_StreamTypeVideoMpeg4: 851 pDecShellContext->mDecoderType = VIDEOEDITOR_kMpeg4VideoDec; 852 // Parse the VOL header 853 err = VideoEditorVideoDecoder_internalParseVideoDSI( 854 (M4OSA_UInt8*)pDecShellContext->m_pVideoStreamhandler->\ 855 m_basicProperties.m_pDecoderSpecificInfo, 856 pDecShellContext->m_pVideoStreamhandler->\ 857 m_basicProperties.m_decoderSpecificInfoSize, 858 &pDecShellContext->m_Dci, &pDecShellContext->m_VideoSize); 859 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 860 break; 861 case M4DA_StreamTypeVideoMpeg4Avc: 862 pDecShellContext->mDecoderType = VIDEOEDITOR_kH264VideoDec; 863 break; 864 default: 865 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 866 M4ERR_PARAMETER); 867 break; 868 } 869 870 pDecShellContext->mNbInputFrames = 0; 871 pDecShellContext->mFirstInputCts = -1.0; 872 pDecShellContext->mLastInputCts = -1.0; 873 pDecShellContext->mNbRenderedFrames = 0; 874 pDecShellContext->mFirstRenderedCts = -1.0; 875 pDecShellContext->mLastRenderedCts = -1.0; 876 pDecShellContext->mNbOutputFrames = 0; 877 pDecShellContext->mFirstOutputCts = -1; 878 pDecShellContext->mLastOutputCts = -1; 879 880 /** 881 * StageFright graph building 882 */ 883 decoderMetadata = new MetaData; 884 switch( pDecShellContext->mDecoderType ) { 885 case VIDEOEDITOR_kH263VideoDec: 886 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 887 break; 888 case VIDEOEDITOR_kMpeg4VideoDec: 889 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 890 decoderMetadata->setData(kKeyESDS, kTypeESDS, 891 pStreamHandler->m_pESDSInfo, 892 pStreamHandler->m_ESDSInfoSize); 893 break; 894 case VIDEOEDITOR_kH264VideoDec: 895 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 896 decoderMetadata->setData(kKeyAVCC, kTypeAVCC, 897 pStreamHandler->m_pH264DecoderSpecificInfo, 898 pStreamHandler->m_H264decoderSpecificInfoSize); 899 break; 900 default: 901 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 902 M4ERR_PARAMETER); 903 break; 904 } 905 906 decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize); 907 decoderMetadata->setInt32(kKeyWidth, 908 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 909 decoderMetadata->setInt32(kKeyHeight, 910 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 911 912 // Create the decoder source 913 pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource( 914 decoderMetadata, pDecShellContext->mDecoderType, 915 (void *)pDecShellContext); 916 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(), 917 M4ERR_SF_DECODER_RSRC_FAIL); 918 919 // Connect to the OMX client 920 status = pDecShellContext->mClient.connect(); 921 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 922 923 // Create the decoder 924 pDecShellContext->mVideoDecoder = OMXCodec::Create( 925 pDecShellContext->mClient.interface(), 926 decoderMetadata, false, pDecShellContext->mReaderSource); 927 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(), 928 M4ERR_SF_DECODER_RSRC_FAIL); 929 930 931 // Get the output color format 932 success = pDecShellContext->mVideoDecoder->getFormat()->findInt32( 933 kKeyColorFormat, &colorFormat); 934 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 935 pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; 936 937 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth, 938 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 939 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight, 940 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 941 942 // Configure the buffer pool from the metadata 943 err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext, 944 pDecShellContext->mVideoDecoder->getFormat().get()); 945 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 946 947 // Start the graph 948 status = pDecShellContext->mVideoDecoder->start(); 949 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 950 951 *pContext = (M4OSA_Context)pDecShellContext; 952 953cleanUp: 954 if( M4NO_ERROR == err ) { 955 LOGV("VideoEditorVideoDecoder_create no error"); 956 } else { 957 VideoEditorVideoDecoder_destroy(pDecShellContext); 958 *pContext = M4OSA_NULL; 959 LOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err); 960 } 961 LOGV("VideoEditorVideoDecoder_create : DONE"); 962 return err; 963} 964 965M4OSA_ERR VideoEditorVideoDecoder_getOption(M4OSA_Context context, 966 M4OSA_OptionID optionId, M4OSA_DataOption pValue) { 967 M4OSA_ERR lerr = M4NO_ERROR; 968 VideoEditorVideoDecoder_Context* pDecShellContext = 969 (VideoEditorVideoDecoder_Context*) context; 970 M4_VersionInfo* pVersionInfo; 971 M4DECODER_VideoSize* pVideoSize; 972 M4OSA_UInt32* pNextFrameCts; 973 M4OSA_UInt32 *plastDecodedFrameCts; 974 M4DECODER_AVCProfileLevel* profile; 975 M4DECODER_MPEG4_DecoderConfigInfo* pDecConfInfo; 976 977 LOGV("VideoEditorVideoDecoder_getOption begin"); 978 979 switch (optionId) { 980 case M4DECODER_kOptionID_AVCLastDecodedFrameCTS: 981 plastDecodedFrameCts = (M4OSA_UInt32 *) pValue; 982 *plastDecodedFrameCts = pDecShellContext->m_lastDecodedCTS; 983 break; 984 985 case M4DECODER_kOptionID_Version: 986 pVersionInfo = (M4_VersionInfo*)pValue; 987 988 pVersionInfo->m_major = VIDEOEDITOR_VIDEC_SHELL_VER_MAJOR; 989 pVersionInfo->m_minor= VIDEOEDITOR_VIDEC_SHELL_VER_MINOR; 990 pVersionInfo->m_revision = VIDEOEDITOR_VIDEC_SHELL_VER_REVISION; 991 pVersionInfo->m_structSize=sizeof(M4_VersionInfo); 992 break; 993 994 case M4DECODER_kOptionID_VideoSize: 995 /** Only VPS uses this Option ID. */ 996 pVideoSize = (M4DECODER_VideoSize*)pValue; 997 pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyWidth, 998 (int32_t*)(&pVideoSize->m_uiWidth)); 999 pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyHeight, 1000 (int32_t*)(&pVideoSize->m_uiHeight)); 1001 LOGV("VideoEditorVideoDecoder_getOption : W=%d H=%d", 1002 pVideoSize->m_uiWidth, pVideoSize->m_uiHeight); 1003 break; 1004 1005 case M4DECODER_kOptionID_NextRenderedFrameCTS: 1006 /** How to get this information. SF decoder does not provide this. * 1007 ** Let us provide last decoded frame CTS as of now. * 1008 ** Only VPS uses this Option ID. */ 1009 pNextFrameCts = (M4OSA_UInt32 *)pValue; 1010 *pNextFrameCts = pDecShellContext->m_lastDecodedCTS; 1011 break; 1012 case M4DECODER_kOptionID_AVCProfileAndLevel: 1013 profile = (M4DECODER_AVCProfileLevel *) pValue; 1014 VideoEditorVideoDecoder_ParseAVCDSI ( 1015 pDecShellContext->m_pVideoStreamhandler->\ 1016 m_basicProperties.m_pDecoderSpecificInfo, 1017 pDecShellContext->m_pVideoStreamhandler->\ 1018 m_basicProperties.m_decoderSpecificInfoSize, 1019 profile); 1020 break; 1021 case M4DECODER_MPEG4_kOptionID_DecoderConfigInfo: 1022 if(pDecShellContext->mDecoderType == VIDEOEDITOR_kMpeg4VideoDec) { 1023 (*(M4DECODER_MPEG4_DecoderConfigInfo*)pValue) = 1024 pDecShellContext->m_Dci; 1025 } 1026 break; 1027 default: 1028 lerr = M4ERR_BAD_OPTION_ID; 1029 break; 1030 1031 } 1032 1033 LOGV("VideoEditorVideoDecoder_getOption: end with err = 0x%x", lerr); 1034 return lerr; 1035} 1036 1037M4OSA_ERR VideoEditorVideoDecoder_setOption(M4OSA_Context context, 1038 M4OSA_OptionID optionId, M4OSA_DataOption pValue) { 1039 M4OSA_ERR lerr = M4NO_ERROR; 1040 VideoEditorVideoDecoder_Context *pDecShellContext = 1041 (VideoEditorVideoDecoder_Context*) context; 1042 1043 LOGV("VideoEditorVideoDecoder_setOption begin"); 1044 1045 switch (optionId) { 1046 case M4DECODER_kOptionID_OutputFilter: { 1047 M4DECODER_OutputFilter* pOutputFilter = 1048 (M4DECODER_OutputFilter*) pValue; 1049 pDecShellContext->m_pFilter = 1050 (M4VIFI_PlanConverterFunctionType*)pOutputFilter->\ 1051 m_pFilterFunction; 1052 pDecShellContext->m_pFilterUserData = 1053 pOutputFilter->m_pFilterUserData; 1054 } 1055 break; 1056 case M4DECODER_kOptionID_DeblockingFilter: 1057 break; 1058 default: 1059 lerr = M4ERR_BAD_CONTEXT; 1060 break; 1061 } 1062 1063 LOGV("VideoEditorVideoDecoder_setOption: end with err = 0x%x", lerr); 1064 return lerr; 1065} 1066 1067M4OSA_ERR VideoEditorVideoDecoder_decode(M4OSA_Context context, 1068 M4_MediaTime* pTime, M4OSA_Bool bJump) { 1069 M4OSA_ERR lerr = M4NO_ERROR; 1070 VideoEditorVideoDecoder_Context* pDecShellContext = 1071 (VideoEditorVideoDecoder_Context*) context; 1072 int64_t lFrameTime; 1073 VIDEOEDITOR_BUFFER_Buffer* tmpDecBuffer; 1074 MediaSource::ReadOptions decShellOptions; 1075 MediaBuffer* pDecoderBuffer = NULL; 1076 status_t errStatus; 1077 1078 1079 LOGV("VideoEditorVideoDecoder_decode begin"); 1080 1081 if( M4OSA_TRUE == pDecShellContext->mReachedEOS ) { 1082 // Do not call read(), it could lead to a freeze 1083 LOGV("VideoEditorVideoDecoder_decode : EOS already reached"); 1084 lerr = M4WAR_NO_MORE_AU; 1085 goto VIDEOEDITOR_VideoDecode_cleanUP; 1086 } 1087 if(pDecShellContext->m_lastDecodedCTS >= *pTime) { 1088 LOGV("VideoDecoder_decode: Already decoded up to this time CTS = %lf.", 1089 pDecShellContext->m_lastDecodedCTS); 1090 goto VIDEOEDITOR_VideoDecode_cleanUP; 1091 } 1092 if(M4OSA_TRUE == bJump) { 1093 LOGV("VideoEditorVideoDecoder_decode: Jump called"); 1094 pDecShellContext->m_lastDecodedCTS = -1; 1095 pDecShellContext->m_lastRenderCts = -1; 1096 } 1097 1098 pDecShellContext->mNbInputFrames++; 1099 if (0 > pDecShellContext->mFirstInputCts){ 1100 pDecShellContext->mFirstInputCts = *pTime; 1101 } 1102 pDecShellContext->mLastInputCts = *pTime; 1103 1104 while (pDecShellContext->m_lastDecodedCTS < *pTime) { 1105 LOGV("VideoEditorVideoDecoder_decode, frameCTS = %lf, DecodeUpTo = %lf", 1106 pDecShellContext->m_lastDecodedCTS, *pTime); 1107 lerr = VIDEOEDITOR_BUFFER_getBuffer(pDecShellContext->m_pDecBufferPool, 1108 VIDEOEDITOR_BUFFER_kEmpty, &tmpDecBuffer); 1109 if (lerr == (M4OSA_UInt32)M4ERR_NO_BUFFER_AVAILABLE) { 1110 lerr = VIDEOEDITOR_BUFFER_getOldestBuffer( 1111 pDecShellContext->m_pDecBufferPool, 1112 VIDEOEDITOR_BUFFER_kFilled, &tmpDecBuffer); 1113 tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kEmpty; 1114 lerr = M4NO_ERROR; 1115 } 1116 1117 if (lerr != M4NO_ERROR) { 1118 goto VIDEOEDITOR_VideoDecode_cleanUP; 1119 } 1120 1121 if (pDecoderBuffer != NULL) { 1122 pDecoderBuffer->release(); 1123 pDecoderBuffer = NULL; 1124 } 1125 1126 decShellOptions.reset(); 1127 errStatus = pDecShellContext->mVideoDecoder->read(&pDecoderBuffer, 1128 &decShellOptions); 1129 if (errStatus == ERROR_END_OF_STREAM) { 1130 LOGV("End of stream reached, returning M4WAR_NO_MORE_AU "); 1131 pDecShellContext->mReachedEOS = M4OSA_TRUE; 1132 lerr = M4WAR_NO_MORE_AU; 1133 goto VIDEOEDITOR_VideoDecode_cleanUP; 1134 } else if ( INFO_FORMAT_CHANGED == errStatus ) { 1135 LOGV("VideoDecoder_decode:source returns INFO_FORMAT_CHANGED:TODO"); 1136 1137#if 1 1138 LOGV("VideoDecoder_decode : source returns INFO_FORMAT_CHANGED"); 1139 lerr = VideoEditorVideoDecoder_configureFromMetadata( 1140 pDecShellContext, 1141 pDecShellContext->mVideoDecoder->getFormat().get()); 1142 if( M4NO_ERROR != lerr ) { 1143 LOGV("!!! VideoEditorVideoDecoder_decode ERROR : " 1144 "VideoDecoder_configureFromMetadata returns 0x%X", lerr); 1145 break; 1146 } 1147#endif 1148 continue; 1149 } 1150 1151 if( 0 < pDecoderBuffer->range_length() ) { 1152 LOGV("VIDEOEDITOR_VideoDecoder frame buffer size = %d", 1153 pDecoderBuffer->range_length()); 1154 1155 pDecoderBuffer->meta_data()->findInt64(kKeyTime, &lFrameTime); 1156 pDecShellContext->m_lastDecodedCTS = (M4_MediaTime)(lFrameTime/1000); 1157 LOGV("VideoEditorVideoDecoder_decode,decoded frametime = %lf,size = %d", 1158 (M4_MediaTime)lFrameTime, pDecoderBuffer->size() ); 1159 1160 switch ( pDecShellContext->decOuputColorFormat ) { 1161 case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: { 1162 M4VIFI_ImagePlane tmpPlane[3]; 1163 // Prepare the output image for conversion 1164 if( pDecoderBuffer->range_length() != ( 1165 pDecShellContext->m_pVideoStreamhandler->m_videoWidth * 1166 pDecShellContext->m_pVideoStreamhandler->m_videoHeight \ 1167 * 3)/2 ) { 1168 LOGV("VideoEditorVideoDecoder_decod invalid frame size S=%d" 1169 "W=%d H=%d", pDecoderBuffer->range_length(), 1170 pDecShellContext->m_pVideoStreamhandler->m_videoWidth, 1171 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1172 lerr = M4ERR_PARAMETER; 1173 goto VIDEOEDITOR_VideoDecode_cleanUP; 1174 } 1175 tmpPlane[0].u_width = 1176 pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1177 tmpPlane[0].u_height = 1178 pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1179 tmpPlane[0].u_topleft = 0; 1180 tmpPlane[0].u_stride = tmpPlane[0].u_width; 1181 tmpPlane[0].pac_data = (M4VIFI_UInt8*)tmpDecBuffer->pData; 1182 tmpPlane[1].u_width = tmpPlane[0].u_width/2; 1183 tmpPlane[1].u_height = tmpPlane[0].u_height/2; 1184 tmpPlane[1].u_topleft = 0; 1185 tmpPlane[1].u_stride = tmpPlane[0].u_stride/2; 1186 tmpPlane[1].pac_data = tmpPlane[0].pac_data + 1187 (tmpPlane[0].u_stride * tmpPlane[0].u_height); 1188 tmpPlane[2].u_width = tmpPlane[1].u_width; 1189 tmpPlane[2].u_height = tmpPlane[1].u_height; 1190 tmpPlane[2].u_topleft = 0; 1191 tmpPlane[2].u_stride = tmpPlane[1].u_stride; 1192 tmpPlane[2].pac_data = tmpPlane[1].pac_data + 1193 (tmpPlane[1].u_stride * tmpPlane[1].u_height); 1194 M4VIFI_SemiplanarYVU420toYUV420(M4OSA_NULL, 1195 (M4VIFI_UInt8 *)pDecoderBuffer->data() + \ 1196 pDecoderBuffer->range_offset(), &tmpPlane[0]); 1197 break; 1198 } 1199 case OMX_COLOR_FormatYUV420Planar: 1200 M4OSA_memcpy((M4OSA_MemAddr8)tmpDecBuffer->pData, 1201 (M4OSA_MemAddr8) pDecoderBuffer->data() + 1202 pDecoderBuffer->range_offset(), 1203 (M4OSA_UInt32)pDecoderBuffer->range_length()); 1204 break; 1205 default: 1206 LOGV("VideoDecoder_decode: unexpected color format 0x%X", 1207 pDecShellContext->decOuputColorFormat); 1208 return M4ERR_PARAMETER; 1209 } 1210 1211 tmpDecBuffer->buffCTS = pDecShellContext->m_lastDecodedCTS; 1212 tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kFilled; 1213 tmpDecBuffer->size = pDecoderBuffer->size(); 1214 1215 } else { 1216 LOGV("VideoEditorVideoDecoder_decode : empty buffer was returned"); 1217 } 1218 } 1219 pDecShellContext->mNbOutputFrames++; 1220 if ( 0 > pDecShellContext->mFirstOutputCts ) { 1221 pDecShellContext->mFirstOutputCts = *pTime; 1222 } 1223 pDecShellContext->mLastOutputCts = *pTime; 1224 1225VIDEOEDITOR_VideoDecode_cleanUP: 1226 *pTime = pDecShellContext->m_lastDecodedCTS; 1227 if (pDecoderBuffer != NULL) { 1228 pDecoderBuffer->release(); 1229 pDecoderBuffer = NULL; 1230 } 1231 1232 LOGV("VideoEditorVideoDecoder_decode: end with 0x%x", lerr); 1233 return lerr; 1234} 1235 1236M4OSA_ERR VideoEditorVideoDecoder_render(M4OSA_Context context, 1237 M4_MediaTime* pTime, M4VIFI_ImagePlane* pOutputPlane, 1238 M4OSA_Bool bForceRender) { 1239 M4OSA_ERR err = M4NO_ERROR; 1240 VideoEditorVideoDecoder_Context* pDecShellContext = 1241 (VideoEditorVideoDecoder_Context*) context; 1242 M4OSA_UInt32 lindex, i; 1243 M4OSA_UInt8* p_buf_src, *p_buf_dest; 1244 M4VIFI_ImagePlane tmpPlaneIn, tmpPlaneOut; 1245 VIDEOEDITOR_BUFFER_Buffer* pTmpVIDEOEDITORBuffer, *pRenderVIDEOEDITORBuffer 1246 = M4OSA_NULL; 1247 M4_MediaTime candidateTimeStamp = -1; 1248 M4OSA_Bool bFound = M4OSA_FALSE; 1249 1250 LOGV("VideoEditorVideoDecoder_render begin"); 1251 // Input parameters check 1252 VIDEOEDITOR_CHECK(M4OSA_NULL != context, M4ERR_PARAMETER); 1253 VIDEOEDITOR_CHECK(M4OSA_NULL != pTime, M4ERR_PARAMETER); 1254 VIDEOEDITOR_CHECK(M4OSA_NULL != pOutputPlane, M4ERR_PARAMETER); 1255 1256 // The output buffer is already allocated, just copy the data 1257 if ( (*pTime <= pDecShellContext->m_lastRenderCts) && 1258 (M4OSA_FALSE == bForceRender) ) { 1259 LOGV("VIDEOEDITOR_VIDEO_render Frame in the past"); 1260 err = M4WAR_VIDEORENDERER_NO_NEW_FRAME; 1261 goto cleanUp; 1262 } 1263 LOGV("VideoDecoder_render: lastRendered time = %lf,requested render time = " 1264 "%lf", pDecShellContext->m_lastRenderCts, *pTime); 1265 1266 /** 1267 * Find the buffer appropriate for rendering. */ 1268 for (i=0; i < pDecShellContext->m_pDecBufferPool->NB; i++) { 1269 pTmpVIDEOEDITORBuffer = &pDecShellContext->m_pDecBufferPool\ 1270 ->pNXPBuffer[i]; 1271 if (pTmpVIDEOEDITORBuffer->state == VIDEOEDITOR_BUFFER_kFilled) { 1272 /** Free all those buffers older than last rendered frame. */ 1273 if (pTmpVIDEOEDITORBuffer->buffCTS < pDecShellContext->\ 1274 m_lastRenderCts) { 1275 pTmpVIDEOEDITORBuffer->state = VIDEOEDITOR_BUFFER_kEmpty; 1276 } 1277 1278 /** Get the buffer with appropriate timestamp */ 1279 if ( (pTmpVIDEOEDITORBuffer->buffCTS >= pDecShellContext->\ 1280 m_lastRenderCts) && 1281 (pTmpVIDEOEDITORBuffer->buffCTS <= *pTime) && 1282 (pTmpVIDEOEDITORBuffer->buffCTS > candidateTimeStamp)) { 1283 bFound = M4OSA_TRUE; 1284 pRenderVIDEOEDITORBuffer = pTmpVIDEOEDITORBuffer; 1285 candidateTimeStamp = pTmpVIDEOEDITORBuffer->buffCTS; 1286 LOGV("VideoDecoder_render: found a buffer with timestamp = %lf", 1287 candidateTimeStamp); 1288 } 1289 } 1290 } 1291 if (M4OSA_FALSE == bFound) { 1292 err = M4WAR_VIDEORENDERER_NO_NEW_FRAME; 1293 goto cleanUp; 1294 } 1295 1296 LOGV("VideoEditorVideoDecoder_render 3 ouput %d %d %d %d", 1297 pOutputPlane[0].u_width, pOutputPlane[0].u_height, 1298 pOutputPlane[0].u_topleft, pOutputPlane[0].u_stride); 1299 1300 pDecShellContext->m_lastRenderCts = candidateTimeStamp; 1301 1302 if( M4OSA_NULL != pDecShellContext->m_pFilter ) { 1303 // Filtering was requested 1304 M4VIFI_ImagePlane tmpPlane[3]; 1305 // Prepare the output image for conversion 1306 tmpPlane[0].u_width = 1307 pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1308 tmpPlane[0].u_height = 1309 pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1310 tmpPlane[0].u_topleft = 0; 1311 tmpPlane[0].u_stride = tmpPlane[0].u_width; 1312 tmpPlane[0].pac_data = (M4VIFI_UInt8*)pRenderVIDEOEDITORBuffer->pData; 1313 tmpPlane[1].u_width = tmpPlane[0].u_width/2; 1314 tmpPlane[1].u_height = tmpPlane[0].u_height/2; 1315 tmpPlane[1].u_topleft = 0; 1316 tmpPlane[1].u_stride = tmpPlane[0].u_stride/2; 1317 tmpPlane[1].pac_data = tmpPlane[0].pac_data + 1318 (tmpPlane[0].u_stride * tmpPlane[0].u_height); 1319 tmpPlane[2].u_width = tmpPlane[1].u_width; 1320 tmpPlane[2].u_height = tmpPlane[1].u_height; 1321 tmpPlane[2].u_topleft = 0; 1322 tmpPlane[2].u_stride = tmpPlane[1].u_stride; 1323 tmpPlane[2].pac_data = tmpPlane[1].pac_data + 1324 (tmpPlane[1].u_stride * tmpPlane[1].u_height); 1325 1326 LOGV("VideoEditorVideoDecoder_render w = %d H = %d", 1327 tmpPlane[0].u_width,tmpPlane[0].u_height); 1328 pDecShellContext->m_pFilter(M4OSA_NULL, &tmpPlane[0], pOutputPlane); 1329 } else { 1330 // Just copy the YUV420P buffer 1331 M4OSA_MemAddr8 tempBuffPtr = 1332 (M4OSA_MemAddr8)pRenderVIDEOEDITORBuffer->pData; 1333 M4OSA_UInt32 tempWidth = 1334 pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1335 M4OSA_UInt32 tempHeight = 1336 pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1337 1338 M4OSA_memcpy((M4OSA_MemAddr8) pOutputPlane[0].pac_data, tempBuffPtr, 1339 tempWidth * tempHeight); 1340 tempBuffPtr += (tempWidth * tempHeight); 1341 M4OSA_memcpy((M4OSA_MemAddr8) pOutputPlane[1].pac_data, tempBuffPtr, 1342 (tempWidth/2) * (tempHeight/2)); 1343 tempBuffPtr += ((tempWidth/2) * (tempHeight/2)); 1344 M4OSA_memcpy((M4OSA_MemAddr8) pOutputPlane[2].pac_data, tempBuffPtr, 1345 (tempWidth/2) * (tempHeight/2)); 1346 } 1347 1348 pDecShellContext->mNbRenderedFrames++; 1349 if ( 0 > pDecShellContext->mFirstRenderedCts ) { 1350 pDecShellContext->mFirstRenderedCts = *pTime; 1351 } 1352 pDecShellContext->mLastRenderedCts = *pTime; 1353 1354cleanUp: 1355 if( M4NO_ERROR == err ) { 1356 *pTime = pDecShellContext->m_lastRenderCts; 1357 LOGV("VideoEditorVideoDecoder_render no error"); 1358 } else { 1359 LOGV("VideoEditorVideoDecoder_render ERROR 0x%X", err); 1360 } 1361 LOGV("VideoEditorVideoDecoder_render end"); 1362 return err; 1363} 1364 1365M4OSA_ERR VideoEditorVideoDecoder_getInterface(M4DECODER_VideoType decoderType, 1366 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1367 M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL; 1368 1369 pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_malloc( 1370 sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL, 1371 (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" ); 1372 if (M4OSA_NULL == pDecoderInterface) { 1373 return M4ERR_ALLOC; 1374 } 1375 1376 *pDecoderType = decoderType; 1377 1378 pDecoderInterface->m_pFctCreate = VideoEditorVideoDecoder_create; 1379 pDecoderInterface->m_pFctDestroy = VideoEditorVideoDecoder_destroy; 1380 pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption; 1381 pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption; 1382 pDecoderInterface->m_pFctDecode = VideoEditorVideoDecoder_decode; 1383 pDecoderInterface->m_pFctRender = VideoEditorVideoDecoder_render; 1384 1385 *pDecInterface = (M4OSA_Context)pDecoderInterface; 1386 return M4NO_ERROR; 1387} 1388 1389extern "C" { 1390 1391M4OSA_ERR VideoEditorVideoDecoder_getInterface_MPEG4( 1392 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1393 return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeMPEG4, 1394 pDecoderType, pDecInterface); 1395} 1396 1397M4OSA_ERR VideoEditorVideoDecoder_getInterface_H264( 1398 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1399 return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeAVC, 1400 pDecoderType, pDecInterface); 1401 1402} 1403 1404} // extern "C" 1405