OSDN Git Service

471160e4f0cb3d4a3bb16dbf19f7f9349a8c911f
[android-x86/external-stagefright-plugins.git] / libstagefright / codecs / ffmpegdec / vdec / SoftFFmpegVideo.cpp
1 /*
2  * Copyright 2012 Michael Chen <omxcodec@gmail.com>
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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "SoftFFmpegVideo"
19 #include <utils/Log.h>
20
21 #include "SoftFFmpegVideo.h"
22
23 #include <media/stagefright/foundation/ADebug.h>
24 #include <media/stagefright/foundation/hexdump.h>
25 #include <media/stagefright/MediaDefs.h>
26
27 #define DEBUG_PKT 0
28 #define DEBUG_FRM 0
29
30 static int decoder_reorder_pts = -1;
31
32 namespace android {
33
34 template<class T>
35 static void InitOMXParams(T *params) {
36     params->nSize = sizeof(T);
37     params->nVersion.s.nVersionMajor = 1;
38     params->nVersion.s.nVersionMinor = 0;
39     params->nVersion.s.nRevision = 0;
40     params->nVersion.s.nStep = 0;
41 }
42
43 void SoftFFmpegVideo::setMode(const char *name) {
44     if (!strcmp(name, "OMX.ffmpeg.mpeg2.decoder")) {
45         mMode = MODE_MPEG2;
46     } else if (!strcmp(name, "OMX.ffmpeg.h263.decoder")) {
47         mMode = MODE_H263;
48         } else if (!strcmp(name, "OMX.ffmpeg.mpeg4.decoder")) {
49         mMode = MODE_MPEG4;
50     } else if (!strcmp(name, "OMX.ffmpeg.wmv.decoder")) {
51         mMode = MODE_WMV;
52     } else if (!strcmp(name, "OMX.ffmpeg.rv.decoder")) {
53         mMode = MODE_RV;
54         } else if (!strcmp(name, "OMX.ffmpeg.h264.decoder")) {
55         mMode = MODE_H264;
56     } else if (!strcmp(name, "OMX.ffmpeg.vp8.decoder")) {
57         mMode = MODE_VP8;
58     } else if (!strcmp(name, "OMX.ffmpeg.vp9.decoder")) {
59         mMode = MODE_VP9;
60     } else if (!strcmp(name, "OMX.ffmpeg.vc1.decoder")) {
61         mMode = MODE_VC1;
62     } else if (!strcmp(name, "OMX.ffmpeg.flv1.decoder")) {
63         mMode = MODE_FLV1;
64     } else if (!strcmp(name, "OMX.ffmpeg.divx.decoder")) {
65         mMode = MODE_DIVX;
66     } else if (!strcmp(name, "OMX.ffmpeg.hevc.decoder")) {
67         mMode = MODE_HEVC;
68     } else if (!strcmp(name, "OMX.ffmpeg.vtrial.decoder")) {
69         mMode = MODE_TRIAL;
70     } else {
71         TRESPASS();
72     }
73 }
74
75 SoftFFmpegVideo::SoftFFmpegVideo(
76         const char *name,
77         const OMX_CALLBACKTYPE *callbacks,
78         OMX_PTR appData,
79         OMX_COMPONENTTYPE **component)
80     : SimpleSoftOMXComponent(name, callbacks, appData, component),
81       mMode(MODE_NONE),
82       mFFmpegAlreadyInited(false),
83       mCodecAlreadyOpened(false),
84       mPendingSettingChangeEvent(false),
85       mPendingFrameAsSettingChanged(false),
86       mCtx(NULL),
87       mImgConvertCtx(NULL),
88       mFrame(NULL),
89       mEOSStatus(INPUT_DATA_AVAILABLE),
90       mExtradataReady(false),
91       mIgnoreExtradata(false),
92       mSignalledError(false),
93       mDoDeinterlace(true),
94       mWidth(320),
95       mHeight(240),
96       mStride(320),
97       mOutputPortSettingsChange(NONE) {
98
99     ALOGD("SoftFFmpegVideo component: %s mMode: %d appData: %p", name, mMode, appData);
100
101     setMode(name);
102
103     initPorts();
104     CHECK_EQ(initDecoder(), (status_t)OK);
105 }
106
107 SoftFFmpegVideo::~SoftFFmpegVideo() {
108     ALOGV("~SoftFFmpegVideo");
109     deInitDecoder();
110     if (mFFmpegAlreadyInited) {
111         deInitFFmpeg();
112     }
113 }
114
115 void SoftFFmpegVideo::initInputFormat(uint32_t mode,
116         OMX_PARAM_PORTDEFINITIONTYPE &def) {
117     switch (mode) {
118     case MODE_MPEG2:
119         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_MPEG2);
120         def.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG2;
121         break;
122     case MODE_H263:
123         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_H263);
124         def.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
125         break;
126     case MODE_MPEG4:
127         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_MPEG4);
128         def.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
129         break;
130     case MODE_WMV:
131         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_WMV);
132         def.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV;
133         break;
134     case MODE_RV:
135         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_RV);
136         def.format.video.eCompressionFormat = OMX_VIDEO_CodingRV;
137         break;
138     case MODE_H264:
139         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_AVC);
140         def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
141         break;
142     case MODE_VP8:
143         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_VP8);
144         def.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8;
145         break;
146     case MODE_VP9:
147         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_VP9);
148         def.format.video.eCompressionFormat = OMX_VIDEO_CodingVP9;
149         break;
150     case MODE_VC1:
151         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_VC1);
152         def.format.video.eCompressionFormat = OMX_VIDEO_CodingVC1;
153         break;
154     case MODE_FLV1:
155         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_FLV1);
156         def.format.video.eCompressionFormat = OMX_VIDEO_CodingFLV1;
157         break;
158     case MODE_DIVX:
159         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_DIVX);
160         def.format.video.eCompressionFormat = OMX_VIDEO_CodingDIVX;
161         break;
162     case MODE_HEVC:
163         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_HEVC);
164         def.format.video.eCompressionFormat = OMX_VIDEO_CodingHEVC;
165         break;
166     case MODE_TRIAL:
167         def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_FFMPEG);
168         def.format.video.eCompressionFormat = OMX_VIDEO_CodingAutoDetect;
169         break;
170     default:
171         CHECK(!"Should not be here. Unsupported mime type and compression format");
172         break;
173     }
174
175     def.format.video.pNativeRender = NULL;
176     def.format.video.nFrameWidth = mWidth;
177     def.format.video.nFrameHeight = mHeight;
178     def.format.video.nStride = def.format.video.nFrameWidth;
179     def.format.video.nSliceHeight = def.format.video.nFrameHeight;
180     def.format.video.nBitrate = 0;
181     def.format.video.xFramerate = 0;
182     def.format.video.bFlagErrorConcealment = OMX_FALSE;
183     def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
184     def.format.video.pNativeWindow = NULL;
185 }
186
187 void SoftFFmpegVideo::initPorts() {
188     OMX_PARAM_PORTDEFINITIONTYPE def;
189     InitOMXParams(&def);
190
191     def.nPortIndex = 0;
192     def.eDir = OMX_DirInput;
193     def.nBufferCountMin = kNumInputBuffers;
194     def.nBufferCountActual = def.nBufferCountMin;
195     def.nBufferSize = 1280 * 720 * 3 / 2; // 256 * 1024?
196     def.bEnabled = OMX_TRUE;
197     def.bPopulated = OMX_FALSE;
198     def.eDomain = OMX_PortDomainVideo;
199     def.bBuffersContiguous = OMX_FALSE;
200     def.nBufferAlignment = 1;
201
202     initInputFormat(mMode, def);
203
204     addPort(def);
205
206     def.nPortIndex = 1;
207     def.eDir = OMX_DirOutput;
208     def.nBufferCountMin = kNumOutputBuffers;
209     def.nBufferCountActual = def.nBufferCountMin;
210     def.bEnabled = OMX_TRUE;
211     def.bPopulated = OMX_FALSE;
212     def.eDomain = OMX_PortDomainVideo;
213     def.bBuffersContiguous = OMX_FALSE;
214     def.nBufferAlignment = 2;
215
216     def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_RAW);
217     def.format.video.pNativeRender = NULL;
218     def.format.video.nFrameWidth = mWidth;
219     def.format.video.nFrameHeight = mHeight;
220     def.format.video.nStride = def.format.video.nFrameWidth;
221     def.format.video.nSliceHeight = def.format.video.nFrameHeight;
222     def.format.video.nBitrate = 0;
223     def.format.video.xFramerate = 0;
224     def.format.video.bFlagErrorConcealment = OMX_FALSE;
225     def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
226     def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
227     def.format.video.pNativeWindow = NULL;
228
229     def.nBufferSize =
230         (def.format.video.nFrameWidth * def.format.video.nFrameHeight * 3) / 2;
231
232     addPort(def);
233 }
234
235 void SoftFFmpegVideo::setDefaultCtx(AVCodecContext *avctx, const AVCodec *codec) {
236     int fast = 0;
237
238     avctx->workaround_bugs   = 1;
239     avctx->lowres            = 0;
240     if(avctx->lowres > codec->max_lowres){
241         ALOGW("The maximum value for lowres supported by the decoder is %d",
242                 codec->max_lowres);
243         avctx->lowres= codec->max_lowres;
244     }
245     avctx->idct_algo         = 0;
246     avctx->skip_frame        = AVDISCARD_DEFAULT;
247     avctx->skip_idct         = AVDISCARD_DEFAULT;
248     avctx->skip_loop_filter  = AVDISCARD_DEFAULT;
249     avctx->error_concealment = 3;
250
251     if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
252     if (fast)   avctx->flags2 |= CODEC_FLAG2_FAST;
253     if(codec->capabilities & CODEC_CAP_DR1)
254         avctx->flags |= CODEC_FLAG_EMU_EDGE;
255 }
256
257 status_t SoftFFmpegVideo::initDecoder() {
258     status_t status;
259     
260     status = initFFmpeg();
261     if (status != OK) {
262         return NO_INIT;
263     }
264     mFFmpegAlreadyInited = true;
265
266     mCtx = avcodec_alloc_context3(NULL);
267     if (!mCtx)
268     {
269         ALOGE("avcodec_alloc_context failed.");
270         return NO_MEMORY;
271     }
272
273     mCtx->codec_type = AVMEDIA_TYPE_VIDEO;
274     switch (mMode) {
275     case MODE_MPEG2:
276         mCtx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
277         break;
278     case MODE_H263:
279         mCtx->codec_id = AV_CODEC_ID_H263;
280         //FIXME, which?
281         //mCtx->codec_id = AV_CODEC_ID_H263P;
282         //mCtx->codec_id = AV_CODEC_ID_H263I;
283         break;
284     case MODE_MPEG4:
285         mCtx->codec_id = AV_CODEC_ID_MPEG4;
286         break;
287     case MODE_WMV:
288         mCtx->codec_id = AV_CODEC_ID_WMV2;      // default, adjust in "internalSetParameter" fxn
289         break;
290     case MODE_RV:
291         mCtx->codec_id = AV_CODEC_ID_RV40;      // default, adjust in "internalSetParameter" fxn
292         break;
293     case MODE_H264:
294         mCtx->codec_id = AV_CODEC_ID_H264;
295         break;
296     case MODE_VP8:
297         mCtx->codec_id = AV_CODEC_ID_VP8;
298         break;
299     case MODE_VP9:
300         mCtx->codec_id = AV_CODEC_ID_VP9;
301         break;
302     case MODE_VC1:
303         mCtx->codec_id = AV_CODEC_ID_VC1;
304         break;
305     case MODE_FLV1:
306         mCtx->codec_id = AV_CODEC_ID_FLV1;
307         break;
308     case MODE_DIVX:
309         mCtx->codec_id = AV_CODEC_ID_MPEG4;
310         break;
311     case MODE_HEVC:
312         mCtx->codec_id = AV_CODEC_ID_HEVC;
313         break;
314     case MODE_TRIAL:
315         mCtx->codec_id = AV_CODEC_ID_NONE;
316         break;
317     default:
318         CHECK(!"Should not be here. Unsupported codec");
319         break;
320     }
321
322     mCtx->extradata_size = 0;
323     mCtx->extradata = NULL;
324     mCtx->width = mWidth;
325     mCtx->height = mHeight;
326
327     return OK;
328 }
329
330 void SoftFFmpegVideo::deInitDecoder() {
331     if (mCtx) {
332         if (avcodec_is_open(mCtx)) {
333             avcodec_flush_buffers(mCtx);
334         }
335         if (mCtx->extradata) {
336             av_free(mCtx->extradata);
337             mCtx->extradata = NULL;
338             mCtx->extradata_size = 0;
339         }
340         if (mCodecAlreadyOpened) {
341             avcodec_close(mCtx);
342             av_free(mCtx);
343             mCtx = NULL;
344         }
345     }
346     if (mFrame) {
347         av_freep(&mFrame);
348         mFrame = NULL;
349     }
350     if (mImgConvertCtx) {
351         sws_freeContext(mImgConvertCtx);
352         mImgConvertCtx = NULL;
353     }
354 }
355
356 void SoftFFmpegVideo::getInputFormat(uint32_t mode,
357         OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams) {
358     switch (mode) {
359     case MODE_MPEG2:
360         formatParams->eCompressionFormat = OMX_VIDEO_CodingMPEG2;
361         break;
362     case MODE_H263:
363         formatParams->eCompressionFormat = OMX_VIDEO_CodingH263;
364         break;
365     case MODE_MPEG4:
366         formatParams->eCompressionFormat = OMX_VIDEO_CodingMPEG4;
367         break;
368     case MODE_WMV:
369         formatParams->eCompressionFormat = OMX_VIDEO_CodingWMV;
370         break;
371     case MODE_RV:
372         formatParams->eCompressionFormat = OMX_VIDEO_CodingRV;
373         break;
374     case MODE_H264:
375         formatParams->eCompressionFormat = OMX_VIDEO_CodingAVC;
376         break;
377     case MODE_VP8:
378         formatParams->eCompressionFormat = OMX_VIDEO_CodingVP8;
379         break;
380     case MODE_VP9:
381         formatParams->eCompressionFormat = OMX_VIDEO_CodingVP9;
382         break;
383     case MODE_VC1:
384         formatParams->eCompressionFormat = OMX_VIDEO_CodingVC1;
385         break;
386     case MODE_FLV1:
387         formatParams->eCompressionFormat = OMX_VIDEO_CodingFLV1;
388         break;
389     case MODE_DIVX:
390         formatParams->eCompressionFormat = OMX_VIDEO_CodingDIVX;
391         break;
392     case MODE_HEVC:
393         formatParams->eCompressionFormat = OMX_VIDEO_CodingHEVC;
394         break;
395     case MODE_TRIAL:
396         formatParams->eCompressionFormat = OMX_VIDEO_CodingAutoDetect;
397         break;
398     default:
399        CHECK(!"Should not be here. Unsupported compression format.");
400        break;
401     }
402     formatParams->eColorFormat = OMX_COLOR_FormatUnused;
403     formatParams->xFramerate = 0;
404 }
405
406 OMX_ERRORTYPE SoftFFmpegVideo::internalGetParameter(
407         OMX_INDEXTYPE index, OMX_PTR params) {
408     //ALOGV("internalGetParameter index:0x%x", index);
409     switch (index) {
410         case OMX_IndexParamVideoPortFormat:
411         {
412             OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
413                 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
414
415             if (formatParams->nPortIndex > kOutputPortIndex) {
416                 return OMX_ErrorUndefined;
417             }
418
419             if (formatParams->nIndex != 0) {
420                 return OMX_ErrorNoMore;
421             }
422
423             if (formatParams->nPortIndex == kInputPortIndex) {
424                 getInputFormat(mMode, formatParams);
425             } else {
426                 CHECK_EQ(formatParams->nPortIndex, kOutputPortIndex);
427
428                 formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused;
429                 formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar;
430                 formatParams->xFramerate = 0;
431             }
432
433             return OMX_ErrorNone;
434         }
435
436         case OMX_IndexParamVideoWmv:
437         {
438             OMX_VIDEO_PARAM_WMVTYPE *profile =
439                 (OMX_VIDEO_PARAM_WMVTYPE *)params;
440
441             if (profile->nPortIndex != kInputPortIndex) {
442                 return OMX_ErrorUndefined;
443             }
444
445             profile->eFormat = OMX_VIDEO_WMVFormatUnused;
446
447             return OMX_ErrorNone;
448         }
449
450         case OMX_IndexParamVideoRv:
451         {
452             OMX_VIDEO_PARAM_RVTYPE *profile =
453                 (OMX_VIDEO_PARAM_RVTYPE *)params;
454
455             if (profile->nPortIndex != kInputPortIndex) {
456                 return OMX_ErrorUndefined;
457             }
458
459             profile->eFormat = OMX_VIDEO_RVFormatUnused;
460
461             return OMX_ErrorNone;
462         }
463
464                 case OMX_IndexParamVideoFFmpeg:
465         {
466             OMX_VIDEO_PARAM_FFMPEGTYPE *profile =
467                 (OMX_VIDEO_PARAM_FFMPEGTYPE *)params;
468
469             if (profile->nPortIndex != kInputPortIndex) {
470                 return OMX_ErrorUndefined;
471             }
472
473             profile->eCodecId = AV_CODEC_ID_NONE;
474             profile->nWidth   = 0;
475             profile->nHeight  = 0;
476
477             return OMX_ErrorNone;
478         }
479
480         default:
481
482             return SimpleSoftOMXComponent::internalGetParameter(index, params);
483     }
484 }
485
486 OMX_ERRORTYPE SoftFFmpegVideo::isRoleSupported(
487                         const OMX_PARAM_COMPONENTROLETYPE *roleParams) {
488     bool supported = true;
489
490     switch (mMode) {
491     case MODE_MPEG2:
492         if (strncmp((const char *)roleParams->cRole,
493                 "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE - 1))
494             supported = false;
495             break;
496     case MODE_H263:
497         if (strncmp((const char *)roleParams->cRole,
498                 "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE - 1))
499             supported = false;
500             break;
501     case MODE_MPEG4:
502         if (strncmp((const char *)roleParams->cRole,
503                 "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE - 1))
504             supported = false;
505             break;
506     case MODE_WMV:
507         if (strncmp((const char *)roleParams->cRole,
508                 "video_decoder.wmv", OMX_MAX_STRINGNAME_SIZE - 1))
509             supported = false;
510             break;
511     case MODE_RV:
512         if (strncmp((const char *)roleParams->cRole,
513                 "video_decoder.rv", OMX_MAX_STRINGNAME_SIZE - 1))
514             supported = false;
515             break;
516     case MODE_H264:
517         if (strncmp((const char *)roleParams->cRole,
518                 "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE - 1))
519             supported = false;
520             break;
521     case MODE_VP8:
522         if (strncmp((const char *)roleParams->cRole,
523                 "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE - 1))
524             supported = false;
525             break;
526     case MODE_VP9:
527         if (strncmp((const char *)roleParams->cRole,
528                 "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE - 1))
529             supported = false;
530             break;
531     case MODE_VC1:
532         if (strncmp((const char *)roleParams->cRole,
533                 "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE - 1))
534             supported = false;
535             break;
536     case MODE_FLV1:
537         if (strncmp((const char *)roleParams->cRole,
538                 "video_decoder.flv1", OMX_MAX_STRINGNAME_SIZE - 1))
539             supported = false;
540             break;
541     case MODE_DIVX:
542         if (strncmp((const char *)roleParams->cRole,
543                 "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE - 1))
544             supported = false;
545             break;
546     case MODE_HEVC:
547         if (strncmp((const char *)roleParams->cRole,
548                 "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE - 1))
549             supported = false;
550             break;
551     case MODE_TRIAL:
552         if (strncmp((const char *)roleParams->cRole,
553                 "video_decoder.trial", OMX_MAX_STRINGNAME_SIZE - 1))
554             supported = false;
555             break;
556     default:
557         CHECK(!"Should not be here. Unsupported role.");
558         break;
559     }
560
561     if (!supported) {
562         ALOGE("unsupported role: %s", (const char *)roleParams->cRole);
563         return OMX_ErrorUndefined;
564     }
565     return OMX_ErrorNone;
566 }
567
568 OMX_ERRORTYPE SoftFFmpegVideo::internalSetParameter(
569         OMX_INDEXTYPE index, const OMX_PTR params) {
570     //ALOGV("internalSetParameter index:0x%x", index);
571     switch (index) {
572         case OMX_IndexParamStandardComponentRole:
573         {
574             const OMX_PARAM_COMPONENTROLETYPE *roleParams =
575                 (const OMX_PARAM_COMPONENTROLETYPE *)params;
576             return isRoleSupported(roleParams);
577         }
578
579         case OMX_IndexParamVideoPortFormat:
580         {
581             OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
582                 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
583
584             if (formatParams->nPortIndex > kOutputPortIndex) {
585                 return OMX_ErrorUndefined;
586             }
587
588             if (formatParams->nIndex != 0) {
589                 return OMX_ErrorNoMore;
590             }
591
592             return OMX_ErrorNone;
593         }
594
595         case OMX_IndexParamPortDefinition:
596         {
597             OMX_PARAM_PORTDEFINITIONTYPE *defParams =
598                 (OMX_PARAM_PORTDEFINITIONTYPE *)params;
599
600             if (defParams->nPortIndex > kOutputPortIndex ||
601                     defParams->nSize != sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
602                 return OMX_ErrorUndefined;
603             }
604
605             CHECK_EQ((int)defParams->eDomain, (int)OMX_PortDomainVideo);
606
607             //only care about input port
608             if (defParams->nPortIndex == kOutputPortIndex) {
609                 OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &defParams->format.video;
610                 mCtx->width = video_def->nFrameWidth;
611                 mCtx->height = video_def->nFrameHeight;
612                 ALOGV("got OMX_IndexParamPortDefinition, width: %lu, height: %lu",
613                         video_def->nFrameWidth, video_def->nFrameHeight);
614                 return OMX_ErrorNone;
615             }
616
617             return OMX_ErrorNone;
618         }
619
620         case OMX_IndexParamVideoWmv:
621         {
622             OMX_VIDEO_PARAM_WMVTYPE *profile =
623                 (OMX_VIDEO_PARAM_WMVTYPE *)params;
624
625             if (profile->nPortIndex != kInputPortIndex) {
626                 return OMX_ErrorUndefined;
627             }
628
629             if (profile->eFormat == OMX_VIDEO_WMVFormat7) {
630                 mCtx->codec_id = AV_CODEC_ID_WMV1;
631             } else if (profile->eFormat == OMX_VIDEO_WMVFormat8) {
632                 mCtx->codec_id = AV_CODEC_ID_WMV2;
633             } else if (profile->eFormat == OMX_VIDEO_WMVFormat9) {
634                 mCtx->codec_id = AV_CODEC_ID_WMV3;
635             } else {
636                 ALOGE("unsupported wmv codec: 0x%x", profile->eFormat);
637                 return OMX_ErrorUndefined;
638             }
639
640             return OMX_ErrorNone;
641         }
642
643         case OMX_IndexParamVideoRv:
644         {
645             OMX_VIDEO_PARAM_RVTYPE *profile =
646                 (OMX_VIDEO_PARAM_RVTYPE *)params;
647
648             if (profile->nPortIndex != kInputPortIndex) {
649                 return OMX_ErrorUndefined;
650             }
651
652             if (profile->eFormat == OMX_VIDEO_RVFormatG2) {
653                 mCtx->codec_id = AV_CODEC_ID_RV20;
654             } else if (profile->eFormat == OMX_VIDEO_RVFormat8) {
655                 mCtx->codec_id = AV_CODEC_ID_RV30;
656             } else if (profile->eFormat == OMX_VIDEO_RVFormat9) {
657                 mCtx->codec_id = AV_CODEC_ID_RV40;
658             } else {
659                 ALOGE("unsupported rv codec: 0x%x", profile->eFormat);
660                 return OMX_ErrorUndefined;
661             }
662
663             return OMX_ErrorNone;
664         }
665
666         case OMX_IndexParamVideoFFmpeg:
667         {
668             OMX_VIDEO_PARAM_FFMPEGTYPE *profile =
669                 (OMX_VIDEO_PARAM_FFMPEGTYPE *)params;
670
671             if (profile->nPortIndex != kInputPortIndex) {
672                 return OMX_ErrorUndefined;
673             }
674
675             mCtx->codec_id = (enum AVCodecID)profile->eCodecId;
676             mCtx->width    = profile->nWidth;
677             mCtx->height   = profile->nHeight;
678
679             ALOGD("got OMX_IndexParamVideoFFmpeg, "
680                 "eCodecId:%ld(%s), width:%lu, height:%lu",
681                 profile->eCodecId,
682                 avcodec_get_name(mCtx->codec_id),
683                 profile->nWidth,
684                 profile->nHeight);
685
686             return OMX_ErrorNone;
687         }
688
689         default:
690
691             return SimpleSoftOMXComponent::internalSetParameter(index, params);
692     }
693 }
694
695 bool SoftFFmpegVideo::isPortSettingChanged() {
696     return (mCtx->width != mWidth || mCtx->height != mHeight);
697 }
698
699 bool SoftFFmpegVideo::handlePortSettingChangeEvent() {
700     if (mCtx->width != mWidth || mCtx->height != mHeight) {
701        ALOGI("ffmpeg video port setting change event(%dx%d)->(%dx%d).",
702                mWidth, mHeight, mCtx->width, mCtx->height);
703
704        mWidth = mCtx->width;
705        mHeight = mCtx->height;
706        mStride = mWidth;
707
708        updatePortDefinitions();
709        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
710        mOutputPortSettingsChange = AWAITING_DISABLED;
711        return true;
712     }
713
714     return false;
715 }
716
717 int32_t SoftFFmpegVideo::handleExtradata() {
718     List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
719     BufferInfo *inInfo = *inQueue.begin();
720     OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
721
722     ALOGI("got extradata, ignore: %d, size: %lu",
723             mIgnoreExtradata, inHeader->nFilledLen);
724     hexdump(inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen);
725
726     if (mIgnoreExtradata) {
727         ALOGI("got extradata, size: %lu, but ignore it", inHeader->nFilledLen);
728         } else {
729         if (!mExtradataReady) {
730             //if (mMode == MODE_H264)
731             //it is possible to receive multiple input buffer with OMX_BUFFERFLAG_CODECCONFIG flag.
732             //for example, H264, the first input buffer is SPS, and another is PPS!
733             int orig_extradata_size = mCtx->extradata_size;
734             mCtx->extradata_size += inHeader->nFilledLen;
735             mCtx->extradata = (uint8_t *)realloc(mCtx->extradata,
736                     mCtx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
737             if (!mCtx->extradata) {
738                 ALOGE("ffmpeg video decoder failed to alloc extradata memory.");
739                 return ERR_OOM;
740             }
741
742             memcpy(mCtx->extradata + orig_extradata_size,
743                     inHeader->pBuffer + inHeader->nOffset,
744                     inHeader->nFilledLen);
745             memset(mCtx->extradata + mCtx->extradata_size, 0,
746                     FF_INPUT_BUFFER_PADDING_SIZE);
747         }
748     }
749
750     inQueue.erase(inQueue.begin());
751     inInfo->mOwnedByUs = false;
752     notifyEmptyBufferDone(inHeader);
753
754     return ERR_OK;
755 }
756
757 int32_t SoftFFmpegVideo::openDecoder() {
758     if (mCodecAlreadyOpened) {
759         return ERR_OK;
760     }
761
762     if (!mExtradataReady) {
763         ALOGI("extradata is ready, size: %d", mCtx->extradata_size);
764         hexdump(mCtx->extradata, mCtx->extradata_size);
765         mExtradataReady = true;
766     }
767
768     //find decoder again as codec_id may have changed
769     mCtx->codec = avcodec_find_decoder(mCtx->codec_id);
770     if (!mCtx->codec) {
771         ALOGE("ffmpeg video decoder failed to find codec");
772         return ERR_CODEC_NOT_FOUND;
773     }
774
775     setDefaultCtx(mCtx, mCtx->codec);
776
777     ALOGD("begin to open ffmpeg decoder(%s) now",
778             avcodec_get_name(mCtx->codec_id));
779
780     int err = avcodec_open2(mCtx, mCtx->codec, NULL);
781     if (err < 0) {
782         ALOGE("ffmpeg video decoder failed to initialize. (%s)", av_err2str(err));
783         return ERR_DECODER_OPEN_FAILED;
784     }
785         mCodecAlreadyOpened = true;
786
787     ALOGD("open ffmpeg video decoder(%s) success",
788             avcodec_get_name(mCtx->codec_id));
789
790     mFrame = avcodec_alloc_frame();
791     if (!mFrame) {
792         ALOGE("oom for video frame");
793         return ERR_OOM;
794     }
795
796     return ERR_OK;
797 }
798
799 void SoftFFmpegVideo::initPacket(AVPacket *pkt,
800         OMX_BUFFERHEADERTYPE *inHeader) {
801     memset(pkt, 0, sizeof(AVPacket));
802     av_init_packet(pkt);
803
804     if (inHeader) {
805         pkt->data = (uint8_t *)inHeader->pBuffer + inHeader->nOffset;
806         pkt->size = inHeader->nFilledLen;
807         pkt->pts = inHeader->nTimeStamp;
808     } else {
809         pkt->data = NULL;
810         pkt->size = 0;
811         pkt->pts = AV_NOPTS_VALUE;
812     }
813
814 #if DEBUG_PKT
815     if (pkt->pts != AV_NOPTS_VALUE)
816     {
817         ALOGV("pkt size:%d, pts:%lld", pkt->size, pkt->pts);
818     } else {
819         ALOGV("pkt size:%d, pts:N/A", pkt->size);
820     }
821 #endif
822 }
823
824 int32_t SoftFFmpegVideo::decodeVideo() {
825     int len = 0;
826     int gotPic = false;
827     int32_t ret = ERR_OK;
828     bool is_flush = (mEOSStatus != INPUT_DATA_AVAILABLE);
829     List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
830     BufferInfo *inInfo = NULL;
831     OMX_BUFFERHEADERTYPE *inHeader = NULL;
832
833     if (!is_flush) {
834         inInfo = *inQueue.begin();
835         CHECK(inInfo != NULL);
836         inHeader = inInfo->mHeader;
837     }
838
839     AVPacket pkt;
840     initPacket(&pkt, inHeader);
841     //av_frame_unref(mFrame); //Don't unref mFrame!!!
842     avcodec_get_frame_defaults(mFrame);
843
844     int err = avcodec_decode_video2(mCtx, mFrame, &gotPic, &pkt);
845     if (err < 0) {
846         ALOGE("ffmpeg video decoder failed to decode frame. (%d)", err);
847         //don't send error to OMXCodec, skip!
848         ret = ERR_NO_FRM;
849     } else {
850         mPendingSettingChangeEvent = isPortSettingChanged();
851
852         if (!gotPic) {
853             ALOGI("ffmpeg video decoder failed to get frame.");
854             //stop sending empty packets if the decoder is finished
855             if (is_flush && mCtx->codec->capabilities & CODEC_CAP_DELAY) {
856                 ret = ERR_FLUSHED;
857             } else {
858                 ret = ERR_NO_FRM;
859             }
860         } else {
861             if (mPendingSettingChangeEvent) {
862                 mPendingFrameAsSettingChanged = true;
863             }
864                         ret = ERR_OK;
865         }
866     }
867
868         if (!is_flush) {
869         inQueue.erase(inQueue.begin());
870         inInfo->mOwnedByUs = false;
871         notifyEmptyBufferDone(inHeader);
872         }
873
874         return ret;
875 }
876
877 int32_t SoftFFmpegVideo::preProcessVideoFrame(AVPicture *picture, void **bufp) {
878     AVPicture *picture2;
879     AVPicture picture_tmp;
880     uint8_t *buf = NULL;
881
882     //deinterlace : must be done before any resize
883     if (mDoDeinterlace) {
884         int size = 0;
885
886         //create temporary picture
887         size = avpicture_get_size(mCtx->pix_fmt, mCtx->width, mCtx->height);
888         buf  = (uint8_t *)av_malloc(size);
889         if (!buf) {
890             ALOGE("oom for temporary picture");
891             return ERR_OOM;
892         }
893
894         picture2 = &picture_tmp;
895         avpicture_fill(picture2, buf, mCtx->pix_fmt, mCtx->width, mCtx->height);
896
897         if (avpicture_deinterlace(picture2, picture,
898                 mCtx->pix_fmt, mCtx->width, mCtx->height) < 0) {
899             //if error, do not deinterlace
900             ALOGE("Deinterlacing failed");
901             av_free(buf);
902             buf = NULL;
903             picture2 = picture;
904         }
905     } else {
906         picture2 = picture;
907     }
908
909     if (picture != picture2)
910         *picture = *picture2;
911     *bufp = buf;
912
913     return ERR_OK;
914 }
915
916 int32_t SoftFFmpegVideo::drainOneOutputBuffer() {
917     List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
918     BufferInfo *outInfo = *outQueue.begin();
919         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
920
921     AVPicture pict;
922     void *buffer_to_free = NULL;
923     int64_t pts = AV_NOPTS_VALUE;
924     uint8_t *dst = outHeader->pBuffer;
925
926     //do deinterlace if necessary. for example, your TV is progressive
927     int32_t err = preProcessVideoFrame((AVPicture *)mFrame, &buffer_to_free);
928     if (err != ERR_OK) {
929         ALOGE("preProcessVideoFrame failed");
930         return err;
931     }
932
933     memset(&pict, 0, sizeof(AVPicture));
934     pict.data[0] = dst;
935     pict.data[1] = dst + mStride * mHeight;
936     pict.data[2] = pict.data[1] + (mStride / 2  * mHeight / 2);
937     pict.linesize[0] = mStride;
938     pict.linesize[1] = mStride / 2;
939     pict.linesize[2] = mStride / 2;
940
941     int sws_flags = SWS_BICUBIC;
942     mImgConvertCtx = sws_getCachedContext(mImgConvertCtx,
943            mWidth, mHeight, (AVPixelFormat)mFrame->format, mWidth, mHeight,
944            PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
945     if (mImgConvertCtx == NULL) {
946         ALOGE("Cannot initialize the conversion context");
947         av_free(buffer_to_free);
948         return ERR_SWS_FAILED;
949     }
950     sws_scale(mImgConvertCtx, mFrame->data, mFrame->linesize,
951             0, mHeight, pict.data, pict.linesize);
952
953     outHeader->nOffset = 0;
954     outHeader->nFilledLen = (mStride * mHeight * 3) / 2;
955     outHeader->nFlags = 0;
956     if (mFrame->key_frame) {
957         outHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
958     }
959
960     //process timestamps
961     if (decoder_reorder_pts == -1) {
962         pts = *(int64_t*)av_opt_ptr(avcodec_get_frame_class(),
963                 mFrame, "best_effort_timestamp");
964     } else if (decoder_reorder_pts) {
965         pts = mFrame->pkt_pts;
966     } else {
967         pts = mFrame->pkt_dts;
968     }
969
970     if (pts == AV_NOPTS_VALUE) {
971         pts = 0;
972     }
973     outHeader->nTimeStamp = pts; //FIXME pts is right???
974
975 #if DEBUG_FRM
976     ALOGV("mFrame pts: %lld", pts);
977 #endif
978
979     outQueue.erase(outQueue.begin());
980     outInfo->mOwnedByUs = false;
981     notifyFillBufferDone(outHeader);
982
983     av_free(buffer_to_free);
984
985     return ERR_OK;
986 }
987
988 void SoftFFmpegVideo::drainEOSOutputBuffer() {
989     List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
990     BufferInfo *outInfo = *outQueue.begin();
991     CHECK(outInfo != NULL);
992     OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
993
994     ALOGD("ffmpeg video decoder fill eos outbuf");
995
996     outHeader->nTimeStamp = 0;
997     outHeader->nFilledLen = 0;
998     outHeader->nFlags = OMX_BUFFERFLAG_EOS;
999
1000     outQueue.erase(outQueue.begin());
1001     outInfo->mOwnedByUs = false;
1002     notifyFillBufferDone(outHeader);
1003
1004     mEOSStatus = OUTPUT_FRAMES_FLUSHED;
1005 }
1006
1007 void SoftFFmpegVideo::drainAllOutputBuffers() {
1008     List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
1009    if (!mCodecAlreadyOpened) {
1010         drainEOSOutputBuffer();
1011         mEOSStatus = OUTPUT_FRAMES_FLUSHED;
1012            return;
1013    }
1014
1015     if(!(mCtx->codec->capabilities & CODEC_CAP_DELAY)) {
1016         drainEOSOutputBuffer();
1017         mEOSStatus = OUTPUT_FRAMES_FLUSHED;
1018         return;
1019     }
1020
1021     while (!outQueue.empty()) {
1022         if (!mPendingFrameAsSettingChanged) {
1023             int32_t err = decodeVideo();
1024                     if (err < ERR_OK) {
1025                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
1026                 mSignalledError = true;
1027                 return;
1028             } else if (err == ERR_FLUSHED) {
1029                 drainEOSOutputBuffer();
1030                 return;
1031             } else {
1032                 CHECK_EQ(err, ERR_OK);
1033                 if (mPendingSettingChangeEvent) {
1034                     return;
1035                 }
1036             }
1037                 }
1038
1039         if (drainOneOutputBuffer() != ERR_OK) {
1040             notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
1041             mSignalledError = true;
1042             return;
1043                 }
1044                 
1045         if (mPendingFrameAsSettingChanged) {
1046             mPendingFrameAsSettingChanged = false;
1047         }
1048     }
1049 }
1050
1051 void SoftFFmpegVideo::onQueueFilled(OMX_U32 portIndex) {
1052     BufferInfo *inInfo = NULL;
1053     OMX_BUFFERHEADERTYPE *inHeader = NULL;
1054     List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
1055     List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
1056
1057     if (mSignalledError || mOutputPortSettingsChange != NONE) {
1058         return;
1059     }
1060
1061     if (mEOSStatus == OUTPUT_FRAMES_FLUSHED) {
1062         return;
1063     }
1064
1065     while (((mEOSStatus != INPUT_DATA_AVAILABLE) || !inQueue.empty())
1066             && !outQueue.empty()) {
1067         if (mPendingSettingChangeEvent) {
1068             //fix crash! We don't notify event until wait for all output buffers
1069             if (outQueue.size() == kNumOutputBuffers) {
1070                 CHECK(handlePortSettingChangeEvent() == true);
1071                 mPendingSettingChangeEvent = false;
1072             }
1073             return;
1074         }
1075
1076         if (mEOSStatus == INPUT_EOS_SEEN) {
1077             drainAllOutputBuffers();
1078             continue;
1079         }
1080
1081         inInfo   = *inQueue.begin();
1082         inHeader = inInfo->mHeader;
1083
1084         if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
1085             ALOGD("ffmpeg video decoder empty eos inbuf");
1086             inQueue.erase(inQueue.begin());
1087             inInfo->mOwnedByUs = false;
1088             notifyEmptyBufferDone(inHeader);
1089             mEOSStatus = INPUT_EOS_SEEN;
1090                         continue;
1091         }
1092
1093         if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1094             if (handleExtradata() != ERR_OK) {
1095                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
1096                 mSignalledError = true;
1097             }
1098             continue;
1099         }
1100
1101         if (!mCodecAlreadyOpened) {
1102                     if (openDecoder() != ERR_OK) {
1103                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
1104                 mSignalledError = true;
1105                 return;
1106             }
1107         }
1108
1109         if (!mPendingFrameAsSettingChanged) {
1110             int32_t err = decodeVideo();
1111                     if (err < ERR_OK) {
1112                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
1113                 mSignalledError = true;
1114                 return;
1115             } else if (err == ERR_NO_FRM) {
1116                 continue;
1117             } else {
1118                 CHECK_EQ(err, ERR_OK);
1119                 if (mPendingSettingChangeEvent) {
1120                     continue;
1121                 }
1122             }
1123                 }
1124
1125         if (drainOneOutputBuffer() != ERR_OK) {
1126             notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
1127             mSignalledError = true;
1128             return;
1129                 }
1130                 
1131         if (mPendingFrameAsSettingChanged) {
1132             mPendingFrameAsSettingChanged = false;
1133         }
1134     }
1135 }
1136
1137 void SoftFFmpegVideo::onPortFlushCompleted(OMX_U32 portIndex) {
1138     ALOGV("ffmpeg video decoder flush port(%lu)", portIndex);
1139     if (portIndex == kInputPortIndex && mCtx) {
1140         if (mCtx) {
1141             //Make sure that the next buffer output does not still
1142             //depend on fragments from the last one decoded.
1143             avcodec_flush_buffers(mCtx);
1144         }
1145         mEOSStatus = INPUT_DATA_AVAILABLE;
1146     }
1147 }
1148
1149 void SoftFFmpegVideo::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
1150     if (portIndex != kOutputPortIndex) {
1151         return;
1152     }
1153
1154     switch (mOutputPortSettingsChange) {
1155         case NONE:
1156             break;
1157
1158         case AWAITING_DISABLED:
1159         {
1160             CHECK(!enabled);
1161             mOutputPortSettingsChange = AWAITING_ENABLED;
1162             break;
1163         }
1164
1165         default:
1166         {
1167             CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
1168             CHECK(enabled);
1169             mOutputPortSettingsChange = NONE;
1170             break;
1171         }
1172     }
1173 }
1174
1175 void SoftFFmpegVideo::updatePortDefinitions() {
1176     OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(0)->mDef;
1177     def->format.video.nFrameWidth = mWidth;
1178     def->format.video.nFrameHeight = mHeight;
1179     def->format.video.nStride = def->format.video.nFrameWidth;
1180     def->format.video.nSliceHeight = def->format.video.nFrameHeight;
1181     def->nBufferSize =
1182         (def->format.video.nFrameWidth
1183             * def->format.video.nFrameHeight * 3) / 2;
1184
1185     def = &editPortInfo(1)->mDef;
1186     def->format.video.nFrameWidth = mWidth;
1187     def->format.video.nFrameHeight = mHeight;
1188     def->format.video.nStride = def->format.video.nFrameWidth;
1189     def->format.video.nSliceHeight = def->format.video.nFrameHeight;
1190 #if 0
1191     def->nBufferSize =
1192         (def->format.video.nFrameWidth
1193             * def->format.video.nFrameHeight * 3) / 2;
1194 #else
1195     def->nBufferSize =
1196         (((def->format.video.nFrameWidth + 15) & -16)
1197             * ((def->format.video.nFrameHeight + 15) & -16) * 3) / 2;
1198 #endif
1199 }
1200
1201 }  // namespace android
1202
1203 android::SoftOMXComponent *createSoftOMXComponent(
1204         const char *name, const OMX_CALLBACKTYPE *callbacks,
1205         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
1206     return new android::SoftFFmpegVideo(name, callbacks, appData, component);
1207 }
1208