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