OSDN Git Service

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