VideoEditorVideoDecoder.cpp revision 35cb2de64cb6482a08f446e80733e7d344a0dcac
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 int32_t vWidth, vHeight; 725 int32_t cropLeft, cropTop, cropRight, cropBottom; 726 727 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 728 VIDEOEDITOR_CHECK(M4OSA_NULL != meta, M4ERR_PARAMETER); 729 730 LOGV("VideoEditorVideoDecoder_configureFromMetadata begin"); 731 732 pDecShellContext = (VideoEditorVideoDecoder_Context*)pContext; 733 734 success = meta->findInt32(kKeyWidth, &vWidth); 735 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 736 success = meta->findInt32(kKeyHeight, &vHeight); 737 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 738 739 pDecShellContext->mGivenWidth = vWidth; 740 pDecShellContext->mGivenHeight = vHeight; 741 742 if (!meta->findRect( 743 kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) { 744 745 cropLeft = cropTop = 0; 746 cropRight = vWidth - 1; 747 cropBottom = vHeight - 1; 748 749 LOGI("got dimensions only %d x %d", width, height); 750 } else { 751 LOGI("got crop rect %d, %d, %d, %d", 752 cropLeft, cropTop, cropRight, cropBottom); 753 } 754 755 width = cropRight - cropLeft + 1; 756 height = cropBottom - cropTop + 1; 757 758 LOGV("VideoDecoder_configureFromMetadata : W=%d H=%d", width, height); 759 VIDEOEDITOR_CHECK((0 != width) && (0 != height), M4ERR_PARAMETER); 760 761 LOGV("VideoDecoder_configureFromMetadata : W=%d H=%d", width, height); 762 763 if( (M4OSA_NULL != pDecShellContext->m_pDecBufferPool) && 764 (pDecShellContext->m_pVideoStreamhandler->m_videoWidth == \ 765 (uint32_t)width) && 766 (pDecShellContext->m_pVideoStreamhandler->m_videoHeight == \ 767 (uint32_t)height) ) { 768 // No need to reconfigure 769 goto cleanUp; 770 } 771 LOGV("VideoDecoder_configureFromMetadata reset: W=%d H=%d", width, height); 772 // Update the stream handler parameters 773 pDecShellContext->m_pVideoStreamhandler->m_videoWidth = width; 774 pDecShellContext->m_pVideoStreamhandler->m_videoHeight = height; 775 frameSize = (width * height * 3) / 2; 776 777 // Configure the buffer pool 778 if( M4OSA_NULL != pDecShellContext->m_pDecBufferPool ) { 779 LOGV("VideoDecoder_configureFromMetadata : reset the buffer pool"); 780 VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool); 781 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 782 } 783 err = VIDEOEDITOR_BUFFER_allocatePool(&pDecShellContext->m_pDecBufferPool, 784 MAX_DEC_BUFFERS, (M4OSA_Char*)"VIDEOEDITOR_DecodedBufferPool"); 785 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 786 err = VIDEOEDITOR_BUFFER_initPoolBuffers(pDecShellContext->m_pDecBufferPool, 787 frameSize + pDecShellContext->mGivenWidth * 2); 788 789 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 790 791cleanUp: 792 if( M4NO_ERROR == err ) { 793 LOGV("VideoEditorVideoDecoder_configureFromMetadata no error"); 794 } else { 795 if( M4OSA_NULL != pDecShellContext->m_pDecBufferPool ) { 796 VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool); 797 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 798 } 799 LOGV("VideoEditorVideoDecoder_configureFromMetadata ERROR 0x%X", err); 800 } 801 LOGV("VideoEditorVideoDecoder_configureFromMetadata end"); 802 return err; 803} 804 805M4OSA_ERR VideoEditorVideoDecoder_destroy(M4OSA_Context pContext) { 806 M4OSA_ERR err = M4NO_ERROR; 807 VideoEditorVideoDecoder_Context* pDecShellContext = 808 (VideoEditorVideoDecoder_Context*)pContext; 809 810 // Input parameters check 811 LOGV("VideoEditorVideoDecoder_destroy begin"); 812 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 813 814 // Destroy the graph 815 if( pDecShellContext->mVideoDecoder != NULL ) { 816 LOGV("### VideoEditorVideoDecoder_destroy : releasing decoder"); 817 pDecShellContext->mVideoDecoder->stop(); 818 pDecShellContext->mVideoDecoder.clear(); 819 } 820 pDecShellContext->mClient.disconnect(); 821 pDecShellContext->mReaderSource.clear(); 822 823 // Release memory 824 if( pDecShellContext->m_pDecBufferPool != M4OSA_NULL ) { 825 VIDEOEDITOR_BUFFER_freePool(pDecShellContext->m_pDecBufferPool); 826 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 827 } 828 SAFE_FREE(pDecShellContext); 829 pContext = NULL; 830 831cleanUp: 832 if( M4NO_ERROR == err ) { 833 LOGV("VideoEditorVideoDecoder_destroy no error"); 834 } else { 835 LOGV("VideoEditorVideoDecoder_destroy ERROR 0x%X", err); 836 } 837 LOGV("VideoEditorVideoDecoder_destroy end"); 838 return err; 839} 840 841M4OSA_ERR VideoEditorVideoDecoder_create(M4OSA_Context *pContext, 842 M4_StreamHandler *pStreamHandler, 843 M4READER_DataInterface *pReaderDataInterface, 844 M4_AccessUnit *pAccessUnit, M4OSA_Void *pUserData) { 845 M4OSA_ERR err = M4NO_ERROR; 846 VideoEditorVideoDecoder_Context* pDecShellContext = M4OSA_NULL; 847 status_t status = OK; 848 bool success = TRUE; 849 int32_t colorFormat = 0; 850 M4OSA_UInt32 size = 0; 851 sp<MetaData> decoderMetadata = NULL; 852 853 LOGV("VideoEditorVideoDecoder_create begin"); 854 // Input parameters check 855 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 856 VIDEOEDITOR_CHECK(M4OSA_NULL != pStreamHandler, M4ERR_PARAMETER); 857 VIDEOEDITOR_CHECK(M4OSA_NULL != pReaderDataInterface, M4ERR_PARAMETER); 858 859 // Context allocation & initialization 860 SAFE_MALLOC(pDecShellContext, VideoEditorVideoDecoder_Context, 1, 861 "VideoEditorVideoDecoder"); 862 pDecShellContext->m_pVideoStreamhandler = 863 (M4_VideoStreamHandler*)pStreamHandler; 864 pDecShellContext->m_pNextAccessUnitToDecode = pAccessUnit; 865 pDecShellContext->m_pReader = pReaderDataInterface; 866 pDecShellContext->m_lastDecodedCTS = -1; 867 pDecShellContext->m_lastRenderCts = -1; 868 switch( pStreamHandler->m_streamType ) { 869 case M4DA_StreamTypeVideoH263: 870 pDecShellContext->mDecoderType = VIDEOEDITOR_kH263VideoDec; 871 break; 872 case M4DA_StreamTypeVideoMpeg4: 873 pDecShellContext->mDecoderType = VIDEOEDITOR_kMpeg4VideoDec; 874 // Parse the VOL header 875 err = VideoEditorVideoDecoder_internalParseVideoDSI( 876 (M4OSA_UInt8*)pDecShellContext->m_pVideoStreamhandler->\ 877 m_basicProperties.m_pDecoderSpecificInfo, 878 pDecShellContext->m_pVideoStreamhandler->\ 879 m_basicProperties.m_decoderSpecificInfoSize, 880 &pDecShellContext->m_Dci, &pDecShellContext->m_VideoSize); 881 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 882 break; 883 case M4DA_StreamTypeVideoMpeg4Avc: 884 pDecShellContext->mDecoderType = VIDEOEDITOR_kH264VideoDec; 885 break; 886 default: 887 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 888 M4ERR_PARAMETER); 889 break; 890 } 891 892 pDecShellContext->mNbInputFrames = 0; 893 pDecShellContext->mFirstInputCts = -1.0; 894 pDecShellContext->mLastInputCts = -1.0; 895 pDecShellContext->mNbRenderedFrames = 0; 896 pDecShellContext->mFirstRenderedCts = -1.0; 897 pDecShellContext->mLastRenderedCts = -1.0; 898 pDecShellContext->mNbOutputFrames = 0; 899 pDecShellContext->mFirstOutputCts = -1; 900 pDecShellContext->mLastOutputCts = -1; 901 pDecShellContext->m_pDecBufferPool = M4OSA_NULL; 902 903 /** 904 * StageFright graph building 905 */ 906 decoderMetadata = new MetaData; 907 switch( pDecShellContext->mDecoderType ) { 908 case VIDEOEDITOR_kH263VideoDec: 909 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 910 break; 911 case VIDEOEDITOR_kMpeg4VideoDec: 912 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 913 decoderMetadata->setData(kKeyESDS, kTypeESDS, 914 pStreamHandler->m_pESDSInfo, 915 pStreamHandler->m_ESDSInfoSize); 916 break; 917 case VIDEOEDITOR_kH264VideoDec: 918 decoderMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 919 decoderMetadata->setData(kKeyAVCC, kTypeAVCC, 920 pStreamHandler->m_pH264DecoderSpecificInfo, 921 pStreamHandler->m_H264decoderSpecificInfoSize); 922 break; 923 default: 924 VIDEOEDITOR_CHECK(!"VideoDecoder_create : incorrect stream type", 925 M4ERR_PARAMETER); 926 break; 927 } 928 929 decoderMetadata->setInt32(kKeyMaxInputSize, pStreamHandler->m_maxAUSize); 930 decoderMetadata->setInt32(kKeyWidth, 931 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 932 decoderMetadata->setInt32(kKeyHeight, 933 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 934 935 // Create the decoder source 936 pDecShellContext->mReaderSource = new VideoEditorVideoDecoderSource( 937 decoderMetadata, pDecShellContext->mDecoderType, 938 (void *)pDecShellContext); 939 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mReaderSource.get(), 940 M4ERR_SF_DECODER_RSRC_FAIL); 941 942 // Connect to the OMX client 943 status = pDecShellContext->mClient.connect(); 944 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 945 946 // Create the decoder 947 pDecShellContext->mVideoDecoder = OMXCodec::Create( 948 pDecShellContext->mClient.interface(), 949 decoderMetadata, false, pDecShellContext->mReaderSource); 950 VIDEOEDITOR_CHECK(NULL != pDecShellContext->mVideoDecoder.get(), 951 M4ERR_SF_DECODER_RSRC_FAIL); 952 953 954 // Get the output color format 955 success = pDecShellContext->mVideoDecoder->getFormat()->findInt32( 956 kKeyColorFormat, &colorFormat); 957 VIDEOEDITOR_CHECK(TRUE == success, M4ERR_PARAMETER); 958 pDecShellContext->decOuputColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; 959 960 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyWidth, 961 pDecShellContext->m_pVideoStreamhandler->m_videoWidth); 962 pDecShellContext->mVideoDecoder->getFormat()->setInt32(kKeyHeight, 963 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 964 965 // Configure the buffer pool from the metadata 966 err = VideoEditorVideoDecoder_configureFromMetadata(pDecShellContext, 967 pDecShellContext->mVideoDecoder->getFormat().get()); 968 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 969 970 // Start the graph 971 status = pDecShellContext->mVideoDecoder->start(); 972 VIDEOEDITOR_CHECK(OK == status, M4ERR_SF_DECODER_RSRC_FAIL); 973 974 *pContext = (M4OSA_Context)pDecShellContext; 975 976cleanUp: 977 if( M4NO_ERROR == err ) { 978 LOGV("VideoEditorVideoDecoder_create no error"); 979 } else { 980 VideoEditorVideoDecoder_destroy(pDecShellContext); 981 *pContext = M4OSA_NULL; 982 LOGV("VideoEditorVideoDecoder_create ERROR 0x%X", err); 983 } 984 LOGV("VideoEditorVideoDecoder_create : DONE"); 985 return err; 986} 987 988M4OSA_ERR VideoEditorVideoDecoder_getOption(M4OSA_Context context, 989 M4OSA_OptionID optionId, M4OSA_DataOption pValue) { 990 M4OSA_ERR lerr = M4NO_ERROR; 991 VideoEditorVideoDecoder_Context* pDecShellContext = 992 (VideoEditorVideoDecoder_Context*) context; 993 M4_VersionInfo* pVersionInfo; 994 M4DECODER_VideoSize* pVideoSize; 995 M4OSA_UInt32* pNextFrameCts; 996 M4OSA_UInt32 *plastDecodedFrameCts; 997 M4DECODER_AVCProfileLevel* profile; 998 M4DECODER_MPEG4_DecoderConfigInfo* pDecConfInfo; 999 1000 LOGV("VideoEditorVideoDecoder_getOption begin"); 1001 1002 switch (optionId) { 1003 case M4DECODER_kOptionID_AVCLastDecodedFrameCTS: 1004 plastDecodedFrameCts = (M4OSA_UInt32 *) pValue; 1005 *plastDecodedFrameCts = pDecShellContext->m_lastDecodedCTS; 1006 break; 1007 1008 case M4DECODER_kOptionID_Version: 1009 pVersionInfo = (M4_VersionInfo*)pValue; 1010 1011 pVersionInfo->m_major = VIDEOEDITOR_VIDEC_SHELL_VER_MAJOR; 1012 pVersionInfo->m_minor= VIDEOEDITOR_VIDEC_SHELL_VER_MINOR; 1013 pVersionInfo->m_revision = VIDEOEDITOR_VIDEC_SHELL_VER_REVISION; 1014 pVersionInfo->m_structSize=sizeof(M4_VersionInfo); 1015 break; 1016 1017 case M4DECODER_kOptionID_VideoSize: 1018 /** Only VPS uses this Option ID. */ 1019 pVideoSize = (M4DECODER_VideoSize*)pValue; 1020 pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyWidth, 1021 (int32_t*)(&pVideoSize->m_uiWidth)); 1022 pDecShellContext->mVideoDecoder->getFormat()->findInt32(kKeyHeight, 1023 (int32_t*)(&pVideoSize->m_uiHeight)); 1024 LOGV("VideoEditorVideoDecoder_getOption : W=%d H=%d", 1025 pVideoSize->m_uiWidth, pVideoSize->m_uiHeight); 1026 break; 1027 1028 case M4DECODER_kOptionID_NextRenderedFrameCTS: 1029 /** How to get this information. SF decoder does not provide this. * 1030 ** Let us provide last decoded frame CTS as of now. * 1031 ** Only VPS uses this Option ID. */ 1032 pNextFrameCts = (M4OSA_UInt32 *)pValue; 1033 *pNextFrameCts = pDecShellContext->m_lastDecodedCTS; 1034 break; 1035 case M4DECODER_kOptionID_AVCProfileAndLevel: 1036 profile = (M4DECODER_AVCProfileLevel *) pValue; 1037 VideoEditorVideoDecoder_ParseAVCDSI ( 1038 pDecShellContext->m_pVideoStreamhandler->\ 1039 m_basicProperties.m_pDecoderSpecificInfo, 1040 pDecShellContext->m_pVideoStreamhandler->\ 1041 m_basicProperties.m_decoderSpecificInfoSize, 1042 profile); 1043 break; 1044 case M4DECODER_MPEG4_kOptionID_DecoderConfigInfo: 1045 if(pDecShellContext->mDecoderType == VIDEOEDITOR_kMpeg4VideoDec) { 1046 (*(M4DECODER_MPEG4_DecoderConfigInfo*)pValue) = 1047 pDecShellContext->m_Dci; 1048 } 1049 break; 1050 default: 1051 lerr = M4ERR_BAD_OPTION_ID; 1052 break; 1053 1054 } 1055 1056 LOGV("VideoEditorVideoDecoder_getOption: end with err = 0x%x", lerr); 1057 return lerr; 1058} 1059 1060M4OSA_ERR VideoEditorVideoDecoder_setOption(M4OSA_Context context, 1061 M4OSA_OptionID optionId, M4OSA_DataOption pValue) { 1062 M4OSA_ERR lerr = M4NO_ERROR; 1063 VideoEditorVideoDecoder_Context *pDecShellContext = 1064 (VideoEditorVideoDecoder_Context*) context; 1065 1066 LOGV("VideoEditorVideoDecoder_setOption begin"); 1067 1068 switch (optionId) { 1069 case M4DECODER_kOptionID_OutputFilter: { 1070 M4DECODER_OutputFilter* pOutputFilter = 1071 (M4DECODER_OutputFilter*) pValue; 1072 pDecShellContext->m_pFilter = 1073 (M4VIFI_PlanConverterFunctionType*)pOutputFilter->\ 1074 m_pFilterFunction; 1075 pDecShellContext->m_pFilterUserData = 1076 pOutputFilter->m_pFilterUserData; 1077 } 1078 break; 1079 case M4DECODER_kOptionID_DeblockingFilter: 1080 break; 1081 default: 1082 lerr = M4ERR_BAD_CONTEXT; 1083 break; 1084 } 1085 1086 LOGV("VideoEditorVideoDecoder_setOption: end with err = 0x%x", lerr); 1087 return lerr; 1088} 1089 1090M4OSA_ERR VideoEditorVideoDecoder_decode(M4OSA_Context context, 1091 M4_MediaTime* pTime, M4OSA_Bool bJump) { 1092 M4OSA_ERR lerr = M4NO_ERROR; 1093 VideoEditorVideoDecoder_Context* pDecShellContext = 1094 (VideoEditorVideoDecoder_Context*) context; 1095 int64_t lFrameTime; 1096 VIDEOEDITOR_BUFFER_Buffer* tmpDecBuffer; 1097 MediaSource::ReadOptions decShellOptions; 1098 MediaBuffer* pDecoderBuffer = NULL; 1099 status_t errStatus; 1100 1101 1102 LOGV("VideoEditorVideoDecoder_decode begin"); 1103 1104 if( M4OSA_TRUE == pDecShellContext->mReachedEOS ) { 1105 // Do not call read(), it could lead to a freeze 1106 LOGV("VideoEditorVideoDecoder_decode : EOS already reached"); 1107 lerr = M4WAR_NO_MORE_AU; 1108 goto VIDEOEDITOR_VideoDecode_cleanUP; 1109 } 1110 if(pDecShellContext->m_lastDecodedCTS >= *pTime) { 1111 LOGV("VideoDecoder_decode: Already decoded up to this time CTS = %lf.", 1112 pDecShellContext->m_lastDecodedCTS); 1113 goto VIDEOEDITOR_VideoDecode_cleanUP; 1114 } 1115 if(M4OSA_TRUE == bJump) { 1116 LOGV("VideoEditorVideoDecoder_decode: Jump called"); 1117 pDecShellContext->m_lastDecodedCTS = -1; 1118 pDecShellContext->m_lastRenderCts = -1; 1119 } 1120 1121 pDecShellContext->mNbInputFrames++; 1122 if (0 > pDecShellContext->mFirstInputCts){ 1123 pDecShellContext->mFirstInputCts = *pTime; 1124 } 1125 pDecShellContext->mLastInputCts = *pTime; 1126 1127 while (pDecShellContext->m_lastDecodedCTS < *pTime) { 1128 LOGV("VideoEditorVideoDecoder_decode, frameCTS = %lf, DecodeUpTo = %lf", 1129 pDecShellContext->m_lastDecodedCTS, *pTime); 1130 lerr = VIDEOEDITOR_BUFFER_getBuffer(pDecShellContext->m_pDecBufferPool, 1131 VIDEOEDITOR_BUFFER_kEmpty, &tmpDecBuffer); 1132 if (lerr == (M4OSA_UInt32)M4ERR_NO_BUFFER_AVAILABLE) { 1133 lerr = VIDEOEDITOR_BUFFER_getOldestBuffer( 1134 pDecShellContext->m_pDecBufferPool, 1135 VIDEOEDITOR_BUFFER_kFilled, &tmpDecBuffer); 1136 tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kEmpty; 1137 lerr = M4NO_ERROR; 1138 } 1139 1140 if (lerr != M4NO_ERROR) { 1141 goto VIDEOEDITOR_VideoDecode_cleanUP; 1142 } 1143 1144 if (pDecoderBuffer != NULL) { 1145 pDecoderBuffer->release(); 1146 pDecoderBuffer = NULL; 1147 } 1148 1149 decShellOptions.reset(); 1150 errStatus = pDecShellContext->mVideoDecoder->read(&pDecoderBuffer, 1151 &decShellOptions); 1152 if (errStatus == ERROR_END_OF_STREAM) { 1153 LOGV("End of stream reached, returning M4WAR_NO_MORE_AU "); 1154 pDecShellContext->mReachedEOS = M4OSA_TRUE; 1155 lerr = M4WAR_NO_MORE_AU; 1156 goto VIDEOEDITOR_VideoDecode_cleanUP; 1157 } else if ( INFO_FORMAT_CHANGED == errStatus ) { 1158 LOGV("VideoDecoder_decode:source returns INFO_FORMAT_CHANGED:TODO"); 1159 1160#if 1 1161 LOGV("VideoDecoder_decode : source returns INFO_FORMAT_CHANGED"); 1162 lerr = VideoEditorVideoDecoder_configureFromMetadata( 1163 pDecShellContext, 1164 pDecShellContext->mVideoDecoder->getFormat().get()); 1165 if( M4NO_ERROR != lerr ) { 1166 LOGV("!!! VideoEditorVideoDecoder_decode ERROR : " 1167 "VideoDecoder_configureFromMetadata returns 0x%X", lerr); 1168 break; 1169 } 1170#endif 1171 continue; 1172 } 1173 1174 if( 0 < pDecoderBuffer->range_length() ) { 1175 LOGV("VIDEOEDITOR_VideoDecoder frame buffer size = %d", 1176 pDecoderBuffer->range_length()); 1177 1178 pDecoderBuffer->meta_data()->findInt64(kKeyTime, &lFrameTime); 1179 pDecShellContext->m_lastDecodedCTS = (M4_MediaTime)(lFrameTime/1000); 1180 LOGV("VideoEditorVideoDecoder_decode,decoded frametime = %lf,size = %d", 1181 (M4_MediaTime)lFrameTime, pDecoderBuffer->size() ); 1182 1183 switch ( pDecShellContext->decOuputColorFormat ) { 1184 case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: { 1185 M4VIFI_ImagePlane tmpPlane[3]; 1186 // Prepare the output image for conversion 1187 if( pDecoderBuffer->range_length() != ( 1188 pDecShellContext->m_pVideoStreamhandler->m_videoWidth * 1189 pDecShellContext->m_pVideoStreamhandler->m_videoHeight \ 1190 * 3)/2 ) { 1191 LOGV("VideoEditorVideoDecoder_decod invalid frame size S=%d" 1192 "W=%d H=%d", pDecoderBuffer->range_length(), 1193 pDecShellContext->m_pVideoStreamhandler->m_videoWidth, 1194 pDecShellContext->m_pVideoStreamhandler->m_videoHeight); 1195 lerr = M4ERR_PARAMETER; 1196 goto VIDEOEDITOR_VideoDecode_cleanUP; 1197 } 1198 tmpPlane[0].u_width = 1199 pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1200 tmpPlane[0].u_height = 1201 pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1202 tmpPlane[0].u_topleft = 0; 1203 tmpPlane[0].u_stride = tmpPlane[0].u_width; 1204 tmpPlane[0].pac_data = (M4VIFI_UInt8*)tmpDecBuffer->pData; 1205 tmpPlane[1].u_width = tmpPlane[0].u_width/2; 1206 tmpPlane[1].u_height = tmpPlane[0].u_height/2; 1207 tmpPlane[1].u_topleft = 0; 1208 tmpPlane[1].u_stride = tmpPlane[0].u_stride/2; 1209 tmpPlane[1].pac_data = tmpPlane[0].pac_data + 1210 (tmpPlane[0].u_stride * tmpPlane[0].u_height); 1211 tmpPlane[2].u_width = tmpPlane[1].u_width; 1212 tmpPlane[2].u_height = tmpPlane[1].u_height; 1213 tmpPlane[2].u_topleft = 0; 1214 tmpPlane[2].u_stride = tmpPlane[1].u_stride; 1215 tmpPlane[2].pac_data = tmpPlane[1].pac_data + 1216 (tmpPlane[1].u_stride * tmpPlane[1].u_height); 1217 M4VIFI_SemiplanarYVU420toYUV420(M4OSA_NULL, 1218 (M4VIFI_UInt8 *)pDecoderBuffer->data() + \ 1219 pDecoderBuffer->range_offset(), &tmpPlane[0]); 1220 break; 1221 } 1222 case OMX_COLOR_FormatYUV420Planar: 1223 { 1224 int32_t width = pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1225 int32_t height = pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1226 int32_t yPlaneSize = width * height; 1227 int32_t uvPlaneSize = width * height / 4; 1228 int32_t offsetSrc = 0; 1229 1230 M4OSA_MemAddr8 pTmpBuff = (M4OSA_MemAddr8)pDecoderBuffer->data() + pDecoderBuffer->range_offset(); 1231 1232 M4OSA_memcpy((M4OSA_MemAddr8)tmpDecBuffer->pData, pTmpBuff, yPlaneSize); 1233 1234 offsetSrc += pDecShellContext->mGivenWidth * pDecShellContext->mGivenHeight; 1235 M4OSA_memcpy((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize, 1236 pTmpBuff + offsetSrc, uvPlaneSize); 1237 1238 offsetSrc += (pDecShellContext->mGivenWidth >> 1) * (pDecShellContext->mGivenHeight >> 1); 1239 M4OSA_memcpy((M4OSA_MemAddr8)tmpDecBuffer->pData + yPlaneSize + uvPlaneSize, 1240 pTmpBuff + offsetSrc, uvPlaneSize); 1241 1242 break; 1243 } 1244 default: 1245 LOGV("VideoDecoder_decode: unexpected color format 0x%X", 1246 pDecShellContext->decOuputColorFormat); 1247 return M4ERR_PARAMETER; 1248 } 1249 1250 tmpDecBuffer->buffCTS = pDecShellContext->m_lastDecodedCTS; 1251 tmpDecBuffer->state = VIDEOEDITOR_BUFFER_kFilled; 1252 tmpDecBuffer->size = pDecoderBuffer->size(); 1253 1254 } else { 1255 LOGV("VideoEditorVideoDecoder_decode : empty buffer was returned"); 1256 } 1257 } 1258 pDecShellContext->mNbOutputFrames++; 1259 if ( 0 > pDecShellContext->mFirstOutputCts ) { 1260 pDecShellContext->mFirstOutputCts = *pTime; 1261 } 1262 pDecShellContext->mLastOutputCts = *pTime; 1263 1264VIDEOEDITOR_VideoDecode_cleanUP: 1265 *pTime = pDecShellContext->m_lastDecodedCTS; 1266 if (pDecoderBuffer != NULL) { 1267 pDecoderBuffer->release(); 1268 pDecoderBuffer = NULL; 1269 } 1270 1271 LOGV("VideoEditorVideoDecoder_decode: end with 0x%x", lerr); 1272 return lerr; 1273} 1274 1275M4OSA_ERR VideoEditorVideoDecoder_render(M4OSA_Context context, 1276 M4_MediaTime* pTime, M4VIFI_ImagePlane* pOutputPlane, 1277 M4OSA_Bool bForceRender) { 1278 M4OSA_ERR err = M4NO_ERROR; 1279 VideoEditorVideoDecoder_Context* pDecShellContext = 1280 (VideoEditorVideoDecoder_Context*) context; 1281 M4OSA_UInt32 lindex, i; 1282 M4OSA_UInt8* p_buf_src, *p_buf_dest; 1283 M4VIFI_ImagePlane tmpPlaneIn, tmpPlaneOut; 1284 VIDEOEDITOR_BUFFER_Buffer* pTmpVIDEOEDITORBuffer, *pRenderVIDEOEDITORBuffer 1285 = M4OSA_NULL; 1286 M4_MediaTime candidateTimeStamp = -1; 1287 M4OSA_Bool bFound = M4OSA_FALSE; 1288 1289 LOGV("VideoEditorVideoDecoder_render begin"); 1290 // Input parameters check 1291 VIDEOEDITOR_CHECK(M4OSA_NULL != context, M4ERR_PARAMETER); 1292 VIDEOEDITOR_CHECK(M4OSA_NULL != pTime, M4ERR_PARAMETER); 1293 VIDEOEDITOR_CHECK(M4OSA_NULL != pOutputPlane, M4ERR_PARAMETER); 1294 1295 // The output buffer is already allocated, just copy the data 1296 if ( (*pTime <= pDecShellContext->m_lastRenderCts) && 1297 (M4OSA_FALSE == bForceRender) ) { 1298 LOGV("VIDEOEDITOR_VIDEO_render Frame in the past"); 1299 err = M4WAR_VIDEORENDERER_NO_NEW_FRAME; 1300 goto cleanUp; 1301 } 1302 LOGV("VideoDecoder_render: lastRendered time = %lf,requested render time = " 1303 "%lf", pDecShellContext->m_lastRenderCts, *pTime); 1304 1305 /** 1306 * Find the buffer appropriate for rendering. */ 1307 for (i=0; i < pDecShellContext->m_pDecBufferPool->NB; i++) { 1308 pTmpVIDEOEDITORBuffer = &pDecShellContext->m_pDecBufferPool\ 1309 ->pNXPBuffer[i]; 1310 if (pTmpVIDEOEDITORBuffer->state == VIDEOEDITOR_BUFFER_kFilled) { 1311 /** Free all those buffers older than last rendered frame. */ 1312 if (pTmpVIDEOEDITORBuffer->buffCTS < pDecShellContext->\ 1313 m_lastRenderCts) { 1314 pTmpVIDEOEDITORBuffer->state = VIDEOEDITOR_BUFFER_kEmpty; 1315 } 1316 1317 /** Get the buffer with appropriate timestamp */ 1318 if ( (pTmpVIDEOEDITORBuffer->buffCTS >= pDecShellContext->\ 1319 m_lastRenderCts) && 1320 (pTmpVIDEOEDITORBuffer->buffCTS <= *pTime) && 1321 (pTmpVIDEOEDITORBuffer->buffCTS > candidateTimeStamp)) { 1322 bFound = M4OSA_TRUE; 1323 pRenderVIDEOEDITORBuffer = pTmpVIDEOEDITORBuffer; 1324 candidateTimeStamp = pTmpVIDEOEDITORBuffer->buffCTS; 1325 LOGV("VideoDecoder_render: found a buffer with timestamp = %lf", 1326 candidateTimeStamp); 1327 } 1328 } 1329 } 1330 if (M4OSA_FALSE == bFound) { 1331 err = M4WAR_VIDEORENDERER_NO_NEW_FRAME; 1332 goto cleanUp; 1333 } 1334 1335 LOGV("VideoEditorVideoDecoder_render 3 ouput %d %d %d %d", 1336 pOutputPlane[0].u_width, pOutputPlane[0].u_height, 1337 pOutputPlane[0].u_topleft, pOutputPlane[0].u_stride); 1338 1339 pDecShellContext->m_lastRenderCts = candidateTimeStamp; 1340 1341 if( M4OSA_NULL != pDecShellContext->m_pFilter ) { 1342 // Filtering was requested 1343 M4VIFI_ImagePlane tmpPlane[3]; 1344 // Prepare the output image for conversion 1345 tmpPlane[0].u_width = 1346 pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1347 tmpPlane[0].u_height = 1348 pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1349 tmpPlane[0].u_topleft = 0; 1350 tmpPlane[0].u_stride = tmpPlane[0].u_width; 1351 tmpPlane[0].pac_data = (M4VIFI_UInt8*)pRenderVIDEOEDITORBuffer->pData; 1352 tmpPlane[1].u_width = tmpPlane[0].u_width/2; 1353 tmpPlane[1].u_height = tmpPlane[0].u_height/2; 1354 tmpPlane[1].u_topleft = 0; 1355 tmpPlane[1].u_stride = tmpPlane[0].u_stride/2; 1356 tmpPlane[1].pac_data = tmpPlane[0].pac_data + 1357 (tmpPlane[0].u_stride * tmpPlane[0].u_height); 1358 tmpPlane[2].u_width = tmpPlane[1].u_width; 1359 tmpPlane[2].u_height = tmpPlane[1].u_height; 1360 tmpPlane[2].u_topleft = 0; 1361 tmpPlane[2].u_stride = tmpPlane[1].u_stride; 1362 tmpPlane[2].pac_data = tmpPlane[1].pac_data + 1363 (tmpPlane[1].u_stride * tmpPlane[1].u_height); 1364 1365 LOGV("VideoEditorVideoDecoder_render w = %d H = %d", 1366 tmpPlane[0].u_width,tmpPlane[0].u_height); 1367 pDecShellContext->m_pFilter(M4OSA_NULL, &tmpPlane[0], pOutputPlane); 1368 } else { 1369 // Just copy the YUV420P buffer 1370 M4OSA_MemAddr8 tempBuffPtr = 1371 (M4OSA_MemAddr8)pRenderVIDEOEDITORBuffer->pData; 1372 M4OSA_UInt32 tempWidth = 1373 pDecShellContext->m_pVideoStreamhandler->m_videoWidth; 1374 M4OSA_UInt32 tempHeight = 1375 pDecShellContext->m_pVideoStreamhandler->m_videoHeight; 1376 1377 M4OSA_memcpy((M4OSA_MemAddr8) pOutputPlane[0].pac_data, tempBuffPtr, 1378 tempWidth * tempHeight); 1379 tempBuffPtr += (tempWidth * tempHeight); 1380 M4OSA_memcpy((M4OSA_MemAddr8) pOutputPlane[1].pac_data, tempBuffPtr, 1381 (tempWidth/2) * (tempHeight/2)); 1382 tempBuffPtr += ((tempWidth/2) * (tempHeight/2)); 1383 M4OSA_memcpy((M4OSA_MemAddr8) pOutputPlane[2].pac_data, tempBuffPtr, 1384 (tempWidth/2) * (tempHeight/2)); 1385 } 1386 1387 pDecShellContext->mNbRenderedFrames++; 1388 if ( 0 > pDecShellContext->mFirstRenderedCts ) { 1389 pDecShellContext->mFirstRenderedCts = *pTime; 1390 } 1391 pDecShellContext->mLastRenderedCts = *pTime; 1392 1393cleanUp: 1394 if( M4NO_ERROR == err ) { 1395 *pTime = pDecShellContext->m_lastRenderCts; 1396 LOGV("VideoEditorVideoDecoder_render no error"); 1397 } else { 1398 LOGV("VideoEditorVideoDecoder_render ERROR 0x%X", err); 1399 } 1400 LOGV("VideoEditorVideoDecoder_render end"); 1401 return err; 1402} 1403 1404M4OSA_ERR VideoEditorVideoDecoder_getInterface(M4DECODER_VideoType decoderType, 1405 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1406 M4DECODER_VideoInterface* pDecoderInterface = M4OSA_NULL; 1407 1408 pDecoderInterface = (M4DECODER_VideoInterface*)M4OSA_malloc( 1409 sizeof(M4DECODER_VideoInterface), M4DECODER_EXTERNAL, 1410 (M4OSA_Char*)"VideoEditorVideoDecoder_getInterface" ); 1411 if (M4OSA_NULL == pDecoderInterface) { 1412 return M4ERR_ALLOC; 1413 } 1414 1415 *pDecoderType = decoderType; 1416 1417 pDecoderInterface->m_pFctCreate = VideoEditorVideoDecoder_create; 1418 pDecoderInterface->m_pFctDestroy = VideoEditorVideoDecoder_destroy; 1419 pDecoderInterface->m_pFctGetOption = VideoEditorVideoDecoder_getOption; 1420 pDecoderInterface->m_pFctSetOption = VideoEditorVideoDecoder_setOption; 1421 pDecoderInterface->m_pFctDecode = VideoEditorVideoDecoder_decode; 1422 pDecoderInterface->m_pFctRender = VideoEditorVideoDecoder_render; 1423 1424 *pDecInterface = (M4OSA_Context)pDecoderInterface; 1425 return M4NO_ERROR; 1426} 1427 1428extern "C" { 1429 1430M4OSA_ERR VideoEditorVideoDecoder_getInterface_MPEG4( 1431 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1432 return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeMPEG4, 1433 pDecoderType, pDecInterface); 1434} 1435 1436M4OSA_ERR VideoEditorVideoDecoder_getInterface_H264( 1437 M4DECODER_VideoType *pDecoderType, M4OSA_Context *pDecInterface) { 1438 return VideoEditorVideoDecoder_getInterface(M4DECODER_kVideoTypeAVC, 1439 pDecoderType, pDecInterface); 1440 1441} 1442 1443} // extern "C" 1444