• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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