OSDN Git Service

Fix green video when scaling video
[android-x86/external-stagefright-plugins.git] / omx / SoftFFmpegVideo.cpp
1 /*
2  * Copyright 2012 Michael Chen <omxcodec@gmail.com>
3  * Copyright 2015 The CyanogenMod Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #define LOG_TAG "SoftFFmpegVideo"
19 #include <utils/Log.h>
20 #include <cutils/properties.h>
21
22 #include "SoftFFmpegVideo.h"
23 #include "FFmpegComponents.h"
24 #include "ffmpeg_hwaccel.h"
25
26 #include <media/stagefright/foundation/ADebug.h>
27 #include <media/stagefright/foundation/AUtils.h>
28 #include <media/stagefright/foundation/hexdump.h>
29 #include <media/stagefright/MediaDefs.h>
30
31 #define DEBUG_PKT 0
32 #define DEBUG_FRM 0
33 #define DEBUG_EXTRADATA 0
34
35 static int decoder_reorder_pts = -1;
36
37 namespace android {
38
39 static const CodecProfileLevel kM4VProfileLevels[] = {
40     { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5 },
41     { OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5 },
42 };
43
44 static const CodecProfileLevel kAVCProfileLevels[] = {
45     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1  },
46     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b },
47     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11 },
48     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12 },
49     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13 },
50     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2  },
51     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21 },
52     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22 },
53     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3  },
54     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31 },
55     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32 },
56     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4  },
57     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 },
58     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42 },
59     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel5  },
60     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel51 },
61     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel52 },
62
63     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel1  },
64     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel1b },
65     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel11 },
66     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel12 },
67     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel13 },
68     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel2  },
69     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel21 },
70     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel22 },
71     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel3  },
72     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel31 },
73     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel32 },
74     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel4  },
75     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel41 },
76     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel42 },
77     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel5  },
78     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel51 },
79     { OMX_VIDEO_AVCProfileMain,     OMX_VIDEO_AVCLevel52 },
80
81     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel1  },
82     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel1b },
83     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel11 },
84     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel12 },
85     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel13 },
86     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel2  },
87     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel21 },
88     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel22 },
89     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel3  },
90     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel31 },
91     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel32 },
92     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel4  },
93     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel41 },
94     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel42 },
95     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel5  },
96     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel51 },
97     { OMX_VIDEO_AVCProfileHigh,     OMX_VIDEO_AVCLevel52 },
98 };
99
100 SoftFFmpegVideo::SoftFFmpegVideo(
101         const char *name,
102         const char *componentRole,
103         OMX_VIDEO_CODINGTYPE codingType,
104         const CodecProfileLevel *profileLevels,
105         size_t numProfileLevels,
106         const OMX_CALLBACKTYPE *callbacks,
107         OMX_PTR appData,
108         OMX_COMPONENTTYPE **component,
109         enum AVCodecID codecID)
110     : SoftVideoDecoderOMXComponent(name, componentRole, codingType,
111             profileLevels, numProfileLevels, 352, 288, callbacks, appData, component),
112       mCodingType(codingType),
113       mFFmpegAlreadyInited(false),
114       mCodecAlreadyOpened(false),
115       mCtx(NULL),
116       mImgConvertCtx(NULL),
117       mFrame(NULL),
118       mEOSStatus(INPUT_DATA_AVAILABLE),
119       mExtradataReady(false),
120       mIgnoreExtradata(false),
121       mStride(320),
122       mSignalledError(false) {
123
124     ALOGD("SoftFFmpegVideo component: %s codingType=%d appData: %p", name, codingType, appData);
125
126     initPorts(
127             kNumInputBuffers,
128             1024 * 1024 /* inputBufferSize */,
129             kNumOutputBuffers,
130             name);
131
132     CHECK_EQ(initDecoder(codecID), (status_t)OK);
133 }
134
135 SoftFFmpegVideo::~SoftFFmpegVideo() {
136     ALOGV("~SoftFFmpegVideo");
137     deInitDecoder();
138     if (mFFmpegAlreadyInited) {
139         deInitFFmpeg();
140     }
141 }
142
143 void SoftFFmpegVideo::setDefaultCtx(AVCodecContext *avctx, const AVCodec *codec) {
144     int fast = 1;
145
146     avctx->workaround_bugs   = 1;
147     avctx->idct_algo         = 0;
148     avctx->skip_frame        = AVDISCARD_DEFAULT;
149     avctx->skip_idct         = AVDISCARD_DEFAULT;
150     avctx->skip_loop_filter  = AVDISCARD_DEFAULT;
151     avctx->error_concealment = 3;
152
153     if (fast)   avctx->flags2 |= AV_CODEC_FLAG2_FAST;
154 #ifdef CODEC_FLAG_EMU_EDGE
155     if (codec->capabilities & AV_CODEC_CAP_DR1)
156         avctx->flags |= CODEC_FLAG_EMU_EDGE;
157 #endif
158 }
159
160 status_t SoftFFmpegVideo::initDecoder(enum AVCodecID codecID) {
161     status_t status;
162
163     status = initFFmpeg();
164     if (status != OK) {
165         return NO_INIT;
166     }
167     mFFmpegAlreadyInited = true;
168
169     mCtx = avcodec_alloc_context3(NULL);
170     if (!mCtx)
171     {
172         ALOGE("avcodec_alloc_context failed.");
173         return NO_MEMORY;
174     }
175
176     mCtx->codec_type = AVMEDIA_TYPE_VIDEO;
177     mCtx->codec_id = codecID;
178     mCtx->extradata_size = 0;
179     mCtx->extradata = NULL;
180     mCtx->width = mWidth;
181     mCtx->height = mHeight;
182     ffmpeg_hwaccel_init(mCtx);
183     ALOGD("%p initDecoder: %p", this, mCtx);
184     return OK;
185 }
186
187 void SoftFFmpegVideo::deInitDecoder() {
188     ALOGD("%p deInitDecoder: %p", this, mCtx);
189     if (mCtx) {
190         if (avcodec_is_open(mCtx)) {
191             avcodec_flush_buffers(mCtx);
192         }
193         if (mCtx->extradata) {
194             av_free(mCtx->extradata);
195             mCtx->extradata = NULL;
196             mCtx->extradata_size = 0;
197         }
198         if (mCodecAlreadyOpened) {
199             avcodec_close(mCtx);
200             mCodecAlreadyOpened = false;
201         }
202         ffmpeg_hwaccel_deinit(mCtx);
203         av_freep(&mCtx);
204     }
205     if (mFrame) {
206         av_frame_free(&mFrame);
207         mFrame = NULL;
208     }
209     if (mImgConvertCtx) {
210         sws_freeContext(mImgConvertCtx);
211         mImgConvertCtx = NULL;
212     }
213 }
214
215 OMX_ERRORTYPE SoftFFmpegVideo::internalGetParameter(
216         OMX_INDEXTYPE index, OMX_PTR params) {
217     //ALOGV("internalGetParameter index:0x%x", index);
218     switch (index) {
219         case OMX_IndexParamVideoWmv:
220         {
221             OMX_VIDEO_PARAM_WMVTYPE *profile =
222                 (OMX_VIDEO_PARAM_WMVTYPE *)params;
223
224             if (profile->nPortIndex != kInputPortIndex) {
225                 return OMX_ErrorUndefined;
226             }
227
228             profile->eFormat = OMX_VIDEO_WMVFormatUnused;
229
230             return OMX_ErrorNone;
231         }
232
233         case OMX_IndexParamVideoRv:
234         {
235             OMX_VIDEO_PARAM_RVTYPE *profile =
236                 (OMX_VIDEO_PARAM_RVTYPE *)params;
237
238             if (profile->nPortIndex != kInputPortIndex) {
239                 return OMX_ErrorUndefined;
240             }
241
242             profile->eFormat = OMX_VIDEO_RVFormatUnused;
243
244             return OMX_ErrorNone;
245         }
246
247         default:
248         {
249             if (index != (OMX_INDEXTYPE)OMX_IndexParamVideoFFmpeg) {
250                 return SoftVideoDecoderOMXComponent::internalGetParameter(index, params);
251             }
252
253             OMX_VIDEO_PARAM_FFMPEGTYPE *profile =
254                 (OMX_VIDEO_PARAM_FFMPEGTYPE *)params;
255
256             if (profile->nPortIndex != kInputPortIndex) {
257                 return OMX_ErrorUndefined;
258             }
259
260             profile->eCodecId = AV_CODEC_ID_NONE;
261             profile->nWidth   = 0;
262             profile->nHeight  = 0;
263
264             return OMX_ErrorNone;
265         }
266     }
267 }
268
269 OMX_ERRORTYPE SoftFFmpegVideo::isRoleSupported(
270                 const OMX_PARAM_COMPONENTROLETYPE *roleParams) {
271     for (size_t i = 0;
272          i < sizeof(kVideoComponents) / sizeof(kVideoComponents[0]);
273          ++i) {
274         if (strncmp((const char *)roleParams->cRole,
275                 kVideoComponents[i].mRole, OMX_MAX_STRINGNAME_SIZE - 1) == 0) {
276             return OMX_ErrorNone;
277         }
278     }
279     ALOGE("unsupported role: %s", (const char *)roleParams->cRole);
280     return OMX_ErrorUndefined;
281 }
282
283 OMX_ERRORTYPE SoftFFmpegVideo::internalSetParameter(
284         OMX_INDEXTYPE index, const OMX_PTR params) {
285     //ALOGV("internalSetParameter index:0x%x", index);
286     switch (index) {
287         case OMX_IndexParamStandardComponentRole:
288         {
289             const OMX_PARAM_COMPONENTROLETYPE *roleParams =
290                 (const OMX_PARAM_COMPONENTROLETYPE *)params;
291             return isRoleSupported(roleParams);
292         }
293
294         case OMX_IndexParamPortDefinition:
295         {
296             OMX_PARAM_PORTDEFINITIONTYPE *newParams =
297                 (OMX_PARAM_PORTDEFINITIONTYPE *)params;
298             OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &newParams->format.video;
299             OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(newParams->nPortIndex)->mDef;
300
301             uint32_t oldWidth = def->format.video.nFrameWidth;
302             uint32_t oldHeight = def->format.video.nFrameHeight;
303             uint32_t newWidth = video_def->nFrameWidth;
304             uint32_t newHeight = video_def->nFrameHeight;
305             if (newWidth != oldWidth || newHeight != oldHeight) {
306                 bool outputPort = (newParams->nPortIndex == kOutputPortIndex);
307                 if (outputPort) {
308                     ALOGI("OMX_IndexParamPortDefinition (output) width=%d height=%d", newWidth, newHeight);
309
310                     // only update (essentially crop) if size changes
311                     mWidth = newWidth;
312                     mHeight = newHeight;
313
314                     updatePortDefinitions(true, true);
315                     // reset buffer size based on frame size
316                     newParams->nBufferSize = def->nBufferSize;
317                 } else {
318                     // For input port, we only set nFrameWidth and nFrameHeight. Buffer size
319                     // is updated when configuring the output port using the max-frame-size,
320                     // though client can still request a larger size.
321                     ALOGI("OMX_IndexParamPortDefinition (input) width=%d height=%d", newWidth, newHeight);
322                     def->format.video.nFrameWidth = newWidth;
323                     def->format.video.nFrameHeight = newHeight;
324                     mCtx->width = newWidth;
325                     mCtx->height = newHeight;
326                 }
327             }
328             return SoftVideoDecoderOMXComponent::internalSetParameter(index, params);
329         }
330
331         case OMX_IndexParamVideoWmv:
332         {
333             OMX_VIDEO_PARAM_WMVTYPE *profile =
334                 (OMX_VIDEO_PARAM_WMVTYPE *)params;
335
336             if (profile->nPortIndex != kInputPortIndex) {
337                 return OMX_ErrorUndefined;
338             }
339
340             if (profile->eFormat == OMX_VIDEO_WMVFormat7) {
341                 mCtx->codec_id = AV_CODEC_ID_WMV1;
342             } else if (profile->eFormat == OMX_VIDEO_WMVFormat8) {
343                 mCtx->codec_id = AV_CODEC_ID_WMV2;
344             } else if (profile->eFormat == OMX_VIDEO_WMVFormat9) {
345                 mCtx->codec_id = AV_CODEC_ID_WMV3;
346             } else {
347                 mCtx->codec_id = AV_CODEC_ID_VC1;
348             }
349
350             return OMX_ErrorNone;
351         }
352
353         case OMX_IndexParamVideoRv:
354         {
355             OMX_VIDEO_PARAM_RVTYPE *profile =
356                 (OMX_VIDEO_PARAM_RVTYPE *)params;
357
358             if (profile->nPortIndex != kInputPortIndex) {
359                 return OMX_ErrorUndefined;
360             }
361
362             if (profile->eFormat == OMX_VIDEO_RVFormatG2) {
363                 mCtx->codec_id = AV_CODEC_ID_RV20;
364             } else if (profile->eFormat == OMX_VIDEO_RVFormat8) {
365                 mCtx->codec_id = AV_CODEC_ID_RV30;
366             } else if (profile->eFormat == OMX_VIDEO_RVFormat9) {
367                 mCtx->codec_id = AV_CODEC_ID_RV40;
368             } else {
369                 ALOGE("unsupported rv codec: 0x%x", profile->eFormat);
370                 return OMX_ErrorUndefined;
371             }
372
373             return OMX_ErrorNone;
374         }
375
376         default:
377         {
378             if (index != (OMX_INDEXTYPE)OMX_IndexParamVideoFFmpeg) {
379                 return SoftVideoDecoderOMXComponent::internalSetParameter(index, params);
380             }
381
382             OMX_VIDEO_PARAM_FFMPEGTYPE *profile =
383                 (OMX_VIDEO_PARAM_FFMPEGTYPE *)params;
384
385             if (profile->nPortIndex != kInputPortIndex) {
386                 return OMX_ErrorUndefined;
387             }
388
389             mCtx->codec_id = (enum AVCodecID)profile->eCodecId;
390             mCtx->width    = profile->nWidth;
391             mCtx->height   = profile->nHeight;
392
393             ALOGD("got OMX_IndexParamVideoFFmpeg, "
394                 "eCodecId:%d(%s), width:%u, height:%u",
395                 profile->eCodecId,
396                 avcodec_get_name(mCtx->codec_id),
397                 profile->nWidth,
398                 profile->nHeight);
399
400             return OMX_ErrorNone;
401         }
402     }
403 }
404
405 int32_t SoftFFmpegVideo::handleExtradata() {
406     List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
407     BufferInfo *inInfo = *inQueue.begin();
408     OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
409
410 #if DEBUG_EXTRADATA
411     ALOGI("got extradata, ignore: %d, size: %u",
412             mIgnoreExtradata, inHeader->nFilledLen);
413     hexdump(inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen);
414 #endif
415
416     if (mIgnoreExtradata) {
417         ALOGI("got extradata, size: %u, but ignore it", inHeader->nFilledLen);
418     } else {
419         if (!mExtradataReady) {
420             //if (mMode == MODE_H264)
421             //it is possible to receive multiple input buffer with OMX_BUFFERFLAG_CODECCONFIG flag.
422             //for example, H264, the first input buffer is SPS, and another is PPS!
423             int orig_extradata_size = mCtx->extradata_size;
424             mCtx->extradata_size += inHeader->nFilledLen;
425             mCtx->extradata = (uint8_t *)realloc(mCtx->extradata,
426                     mCtx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
427             if (!mCtx->extradata) {
428                 ALOGE("ffmpeg video decoder failed to alloc extradata memory.");
429                 return ERR_OOM;
430             }
431
432             memcpy(mCtx->extradata + orig_extradata_size,
433                     inHeader->pBuffer + inHeader->nOffset,
434                     inHeader->nFilledLen);
435             memset(mCtx->extradata + mCtx->extradata_size, 0,
436                     AV_INPUT_BUFFER_PADDING_SIZE);
437         }
438     }
439
440     inQueue.erase(inQueue.begin());
441     inInfo->mOwnedByUs = false;
442     notifyEmptyBufferDone(inHeader);
443
444     return ERR_OK;
445 }
446
447 int32_t SoftFFmpegVideo::openDecoder() {
448     if (mCodecAlreadyOpened) {
449         return ERR_OK;
450     }
451
452     if (!mExtradataReady) {
453 #if DEBUG_EXTRADATA
454         ALOGI("extradata is ready, size: %d", mCtx->extradata_size);
455         hexdump(mCtx->extradata, mCtx->extradata_size);
456 #endif
457         mExtradataReady = true;
458     }
459
460     //find decoder again as codec_id may have changed
461     mCtx->codec = avcodec_find_decoder(mCtx->codec_id);
462     if (!mCtx->codec) {
463         ALOGE("ffmpeg video decoder failed to find codec");
464         return ERR_CODEC_NOT_FOUND;
465     }
466
467     setDefaultCtx(mCtx, mCtx->codec);
468
469     ALOGD("begin to open ffmpeg decoder(%s) now",
470             avcodec_get_name(mCtx->codec_id));
471
472     int err = avcodec_open2(mCtx, mCtx->codec, NULL);
473     if (err < 0) {
474         ALOGE("ffmpeg video decoder failed to initialize. (%s)", av_err2str(err));
475         return ERR_DECODER_OPEN_FAILED;
476     }
477     mCodecAlreadyOpened = true;
478
479     ALOGD("open ffmpeg video decoder(%s) success",
480             avcodec_get_name(mCtx->codec_id));
481
482     mFrame = av_frame_alloc();
483     if (!mFrame) {
484         ALOGE("oom for video frame");
485         return ERR_OOM;
486     }
487
488     return ERR_OK;
489 }
490
491 void SoftFFmpegVideo::initPacket(AVPacket *pkt,
492         OMX_BUFFERHEADERTYPE *inHeader) {
493     memset(pkt, 0, sizeof(AVPacket));
494     av_init_packet(pkt);
495
496     if (inHeader) {
497         pkt->data = (uint8_t *)inHeader->pBuffer + inHeader->nOffset;
498         pkt->size = inHeader->nFilledLen;
499         pkt->pts = inHeader->nTimeStamp;
500         pkt->dts = inHeader->nTimeStamp;
501     } else {
502         pkt->data = NULL;
503         pkt->size = 0;
504         pkt->pts = AV_NOPTS_VALUE;
505     }
506
507 #if DEBUG_PKT
508     if (pkt->pts != AV_NOPTS_VALUE)
509     {
510         ALOGV("pkt size:%d, pts:%lld", pkt->size, pkt->pts);
511     } else {
512         ALOGV("pkt size:%d, pts:N/A", pkt->size);
513     }
514 #endif
515 }
516
517 int32_t SoftFFmpegVideo::decodeVideo() {
518     int len = 0, err = 0;
519     int gotPic = false;
520     int32_t ret = ERR_OK;
521     List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
522     BufferInfo *inInfo = NULL;
523     OMX_BUFFERHEADERTYPE *inHeader = NULL;
524
525     if (!inQueue.empty()) {
526         inInfo = *inQueue.begin();
527         if (inInfo != NULL)  {
528             inHeader = inInfo->mHeader;
529         }
530     }
531
532     if (mEOSStatus == INPUT_EOS_SEEN && (!inHeader || inHeader->nFilledLen == 0)
533         && !(mCtx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
534         return ERR_FLUSHED;
535     }
536
537     AVPacket pkt;
538     initPacket(&pkt, inHeader);
539
540     err = avcodec_decode_video2(mCtx, mFrame, &gotPic, &pkt);
541     av_packet_unref(&pkt);
542
543     if (err < 0) {
544         ALOGE("ffmpeg video decoder failed to decode frame. (%d)", err);
545         //don't send error to OMXCodec, skip!
546         ret = ERR_NO_FRM;
547     } else {
548         if (!gotPic) {
549             //stop sending empty packets if the decoder is finished
550             if ((mEOSStatus != INPUT_DATA_AVAILABLE && (mCtx->codec->capabilities & AV_CODEC_CAP_DELAY) &&
551                 !inHeader) || inHeader->nFilledLen == 0) {
552                 ALOGD("ffmpeg video decoder flushed.");
553                 ret = ERR_FLUSHED;
554             } else {
555                 ALOGV("ffmpeg video decoder failed to get frame.");
556                 ret = ERR_NO_FRM;
557             }
558         } else {
559             err = ffmpeg_hwaccel_get_frame(mCtx, mFrame);
560             if (err < 0) {
561                 ALOGE("ffmpeg HW video decoder failed to decode frame. (%d)", err);
562                 //don't send error to OMXCodec, skip!
563                 ret = ERR_NO_FRM;
564             } else {
565                 ret = ERR_OK;
566             }
567         }
568     }
569
570     if (!inQueue.empty()) {
571         inQueue.erase(inQueue.begin());
572         if (inInfo) {
573             inInfo->mOwnedByUs = false;
574             notifyEmptyBufferDone(inHeader);
575         }
576     }
577
578     return ret;
579 }
580
581 int32_t SoftFFmpegVideo::drainOneOutputBuffer() {
582     List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
583     BufferInfo *outInfo = *outQueue.begin();
584     OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
585
586     uint8_t *data[4];
587     int linesize[4];
588
589     int64_t pts = AV_NOPTS_VALUE;
590     uint8_t *dst = outHeader->pBuffer;
591
592     uint32_t width = outputBufferWidth();
593     uint32_t height = outputBufferHeight();
594
595     data[0] = dst;
596     data[1] = dst + width * height;
597     data[2] = data[1] + (width / 2  * height / 2);
598     linesize[0] = width;
599     linesize[1] = width / 2;
600     linesize[2] = width / 2;
601
602     ALOGV("drainOneOutputBuffer: frame_width=%d frame_height=%d width=%d height=%d ctx_width=%d ctx_height=%d", mFrame->width, mFrame->height, width, height, mCtx->width, mCtx->height);
603
604     int sws_flags = SWS_BICUBIC;
605     mImgConvertCtx = sws_getCachedContext(mImgConvertCtx,
606            mFrame->width, mFrame->height, (AVPixelFormat)mFrame->format, width, height,
607            AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
608     if (mImgConvertCtx == NULL) {
609         ALOGE("Cannot initialize the conversion context");
610         return ERR_SWS_FAILED;
611     }
612     sws_scale(mImgConvertCtx, mFrame->data, mFrame->linesize,
613             0, mFrame->height, data, linesize);
614
615     outHeader->nOffset = 0;
616     outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * 3) / 2;
617     outHeader->nFlags = 0;
618     if (mFrame->key_frame) {
619         outHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
620     }
621
622     //process timestamps
623 #ifndef LIBAV_CONFIG_H
624     if (decoder_reorder_pts == -1) {
625         pts = av_frame_get_best_effort_timestamp(mFrame);
626     } else
627 #endif
628     if (decoder_reorder_pts) {
629         pts = mFrame->pkt_pts;
630     } else {
631         pts = mFrame->pkt_dts;
632     }
633
634     if (pts == AV_NOPTS_VALUE) {
635         pts = 0;
636     }
637     outHeader->nTimeStamp = pts; //FIXME pts is right???
638
639 #if DEBUG_FRM
640     ALOGV("mFrame pkt_pts: %lld pkt_dts: %lld used %lld", mFrame->pkt_pts, mFrame->pkt_dts, pts);
641 #endif
642
643     outQueue.erase(outQueue.begin());
644     outInfo->mOwnedByUs = false;
645     notifyFillBufferDone(outHeader);
646
647     return ERR_OK;
648 }
649
650 void SoftFFmpegVideo::drainEOSOutputBuffer() {
651     List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
652     BufferInfo *outInfo = *outQueue.begin();
653     CHECK(outInfo != NULL);
654     outQueue.erase(outQueue.begin());
655     OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
656
657     ALOGD("ffmpeg video decoder fill eos outbuf");
658
659     outHeader->nTimeStamp = 0;
660     outHeader->nFilledLen = 0;
661     outHeader->nFlags = OMX_BUFFERFLAG_EOS;
662
663     outInfo->mOwnedByUs = false;
664     notifyFillBufferDone(outHeader);
665
666     mEOSStatus = OUTPUT_FRAMES_FLUSHED;
667 }
668
669 void SoftFFmpegVideo::drainAllOutputBuffers() {
670     List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
671    if (!mCodecAlreadyOpened) {
672         drainEOSOutputBuffer();
673         mEOSStatus = OUTPUT_FRAMES_FLUSHED;
674        return;
675    }
676
677     while (!outQueue.empty()) {
678         int32_t err = decodeVideo();
679         if (err < ERR_OK) {
680             notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
681             mSignalledError = true;
682             return;
683         } else if (err == ERR_FLUSHED) {
684             drainEOSOutputBuffer();
685             return;
686         } else if (err == ERR_NO_FRM) {
687             continue;
688         } else {
689             CHECK_EQ(err, (int32_t)ERR_OK);
690         }
691         if (drainOneOutputBuffer() != ERR_OK) {
692             notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
693             mSignalledError = true;
694             return;
695         }
696     }
697 }
698
699 bool SoftFFmpegVideo::handlePortSettingsChange() {
700     CropSettingsMode crop = kCropUnSet;
701     uint32_t width  = outputBufferWidth();
702     uint32_t height = outputBufferHeight();
703     if (width != (uint32_t)mCtx->width || height != (uint32_t)mCtx->height) {
704         crop = kCropSet;
705         if (mCropWidth != width || mCropHeight != height) {
706             mCropLeft = 0;
707             mCropTop = 0;
708             mCropWidth = width;
709             mCropHeight = height;
710             crop = kCropChanged;
711         }
712     }
713
714     bool portWillReset = false;
715     SoftVideoDecoderOMXComponent::handlePortSettingsChange(
716             &portWillReset, mCtx->width, mCtx->height, crop);
717     return portWillReset;
718 }
719
720 void SoftFFmpegVideo::onQueueFilled(OMX_U32 portIndex __unused) {
721     if (mSignalledError || mOutputPortSettingsChange != NONE) {
722         return;
723     }
724
725     if (mEOSStatus == OUTPUT_FRAMES_FLUSHED) {
726         return;
727     }
728
729     List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
730     List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
731
732     while (((mEOSStatus != INPUT_DATA_AVAILABLE) || !inQueue.empty())
733             && !outQueue.empty()) {
734
735         if (mEOSStatus == INPUT_EOS_SEEN) {
736             drainAllOutputBuffers();
737             return;
738         }
739
740         BufferInfo *inInfo = *inQueue.begin();
741         if (inInfo == NULL) {
742             continue;
743         }
744         OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
745         if (inHeader == NULL) {
746             continue;
747         }
748
749         if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
750             mEOSStatus = INPUT_EOS_SEEN;
751             continue;
752         }
753
754         if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
755             ALOGD("ffmpeg got codecconfig buffer");
756             if (handleExtradata() != ERR_OK) {
757                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
758                 mSignalledError = true;
759             }
760             continue;
761         }
762
763         if (!mCodecAlreadyOpened) {
764             if (openDecoder() != ERR_OK) {
765                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
766                 mSignalledError = true;
767                 return;
768             }
769         }
770
771         int32_t err = decodeVideo();
772         if (err < ERR_OK) {
773             notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
774             mSignalledError = true;
775             return;
776         } else if (err == ERR_FLUSHED) {
777             drainEOSOutputBuffer();
778             return;
779         } else if (err == ERR_NO_FRM) {
780             continue;
781         } else {
782             CHECK_EQ(err, (int32_t)ERR_OK);
783         }
784
785         if (handlePortSettingsChange()) {
786             ALOGV("PORT RESET w=%d h=%d", mCtx->width, mCtx->height);
787             return;
788         }
789
790         if (drainOneOutputBuffer() != ERR_OK) {
791             notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
792             mSignalledError = true;
793             return;
794         }
795     }
796 }
797
798 void SoftFFmpegVideo::onPortFlushCompleted(OMX_U32 portIndex) {
799     ALOGV("ffmpeg video decoder flush port(%u)", portIndex);
800     if (portIndex == kInputPortIndex) {
801         if (mCtx && avcodec_is_open(mCtx)) {
802             //Make sure that the next buffer output does not still
803             //depend on fragments from the last one decoded.
804             avcodec_flush_buffers(mCtx);
805         }
806         mEOSStatus = INPUT_DATA_AVAILABLE;
807     }
808 }
809
810 void SoftFFmpegVideo::onReset() {
811     ALOGV("onReset()");
812     enum AVCodecID codecID = mCtx->codec_id;
813     deInitDecoder();
814     initDecoder(codecID);
815     SoftVideoDecoderOMXComponent::onReset();
816     mSignalledError = false;
817     mExtradataReady = false;
818     mEOSStatus = INPUT_DATA_AVAILABLE;
819 }
820
821 SoftOMXComponent* SoftFFmpegVideo::createSoftOMXComponent(
822         const char *name, const OMX_CALLBACKTYPE *callbacks,
823         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
824
825     if (!property_get_bool("media.sf.hwaccel", 1))
826         return NULL;
827
828     OMX_VIDEO_CODINGTYPE codingType = OMX_VIDEO_CodingAutoDetect;
829     char *componentRole = NULL;
830     enum AVCodecID codecID = AV_CODEC_ID_NONE;
831
832     for (size_t i = 0; i < kNumVideoComponents; ++i) {
833         if (!strcasecmp(name, kVideoComponents[i].mName)) {
834             componentRole = strdup(kVideoComponents[i].mRole);
835             codingType = kVideoComponents[i].mVideoCodingType;
836             codecID = kVideoComponents[i].mCodecID;
837             break;
838         }
839     }
840
841     if (componentRole == NULL) {
842         TRESPASS();
843     }
844
845     const CodecProfileLevel *codec_profile_levels;
846     size_t codec_array_size;
847     if (!strcmp(name, "OMX.ffmpeg.mpeg4.decoder")) {
848         codec_profile_levels = kM4VProfileLevels;
849         codec_array_size = ARRAY_SIZE(kM4VProfileLevels);
850     } else if (!strcmp(name, "OMX.ffmpeg.h264.decoder")) {
851         codec_profile_levels = kAVCProfileLevels;
852         codec_array_size = ARRAY_SIZE(kAVCProfileLevels);
853     } else {
854         codec_profile_levels = NULL;
855         codec_array_size = 0;
856     }
857
858     return new SoftFFmpegVideo(name, componentRole, codingType,
859                 codec_profile_levels, codec_array_size,
860                 callbacks, appData, component, codecID);
861 }
862
863 }  // namespace android