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