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