OSDN Git Service

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