OSDN Git Service

disable verbose log
[android-x86/external-stagefright-plugins.git] / libstagefright / FFmpegExtractor / FFmpegExtractor.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_TAG "FFmpegExtractor"
18 #include <utils/Log.h>
19
20 #include <stdint.h>
21 #include <limits.h> /* INT_MAX */
22 #include <inttypes.h>
23
24 #include <utils/misc.h>
25 #include <utils/String8.h>
26 #include <cutils/properties.h>
27 #include <media/stagefright/foundation/ABitReader.h>
28 #include <media/stagefright/foundation/ABuffer.h>
29 #include <media/stagefright/foundation/ADebug.h>
30 #include <media/stagefright/foundation/AMessage.h>
31 #include <media/stagefright/foundation/hexdump.h>
32 #include <media/stagefright/DataSource.h>
33 #include <media/stagefright/MediaBuffer.h>
34 #include <media/stagefright/foundation/ADebug.h>
35 #include <media/stagefright/MediaDefs.h>
36 #include <media/stagefright/MediaErrors.h>
37 #include <media/stagefright/MediaSource.h>
38 #include <media/stagefright/MetaData.h>
39 #include <media/stagefright/Utils.h>
40 #include "include/avc_utils.h"
41
42 #include "utils/codec_utils.h"
43 #include "utils/ffmpeg_cmdutils.h"
44
45 #include "FFmpegExtractor.h"
46
47 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
48 #define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
49 #define MIN_FRAMES 5
50 #define EXTRACTOR_MAX_PROBE_PACKETS 200
51 #define FF_MAX_EXTRADATA_SIZE ((1 << 28) - FF_INPUT_BUFFER_PADDING_SIZE)
52
53 //debug
54 #define DEBUG_READ_ENTRY           0
55 #define DEBUG_DISABLE_VIDEO        0
56 #define DEBUG_DISABLE_AUDIO        0
57 #define WAIT_KEY_PACKET_AFTER_SEEK 1
58 #define DEBUG_PKT                  0
59 #define DEBUG_EXTRADATA            0
60
61 enum {
62     NO_SEEK = 0,
63     SEEK,
64 };
65
66 namespace android {
67
68 struct FFmpegExtractor::Track : public MediaSource {
69     Track(FFmpegExtractor *extractor, sp<MetaData> meta,
70           AVStream *stream, PacketQueue *queue);
71
72     virtual status_t start(MetaData *params);
73     virtual status_t stop();
74     virtual sp<MetaData> getFormat();
75
76     virtual status_t read(
77             MediaBuffer **buffer, const ReadOptions *options);
78
79 protected:
80     virtual ~Track();
81
82 private:
83     friend struct FFmpegExtractor;
84
85     FFmpegExtractor *mExtractor;
86     sp<MetaData> mMeta;
87
88     enum AVMediaType mMediaType;
89
90     mutable Mutex mLock;
91
92     bool mIsAVC;
93     size_t mNALLengthSize;
94     bool mNal2AnnexB;
95
96     AVStream *mStream;
97     PacketQueue *mQueue;
98
99     int64_t mFirstKeyPktTimestamp;
100
101     DISALLOW_EVIL_CONSTRUCTORS(Track);
102 };
103
104 ////////////////////////////////////////////////////////////////////////////////
105
106 FFmpegExtractor::FFmpegExtractor(const sp<DataSource> &source, const sp<AMessage> &meta)
107     : mDataSource(source),
108       mMeta(new MetaData),
109       mInitCheck(NO_INIT),
110       mFFmpegInited(false),
111       mFormatCtx(NULL),
112       mReaderThreadStarted(false) {
113     ALOGV("FFmpegExtractor::FFmpegExtractor");
114
115     fetchStuffsFromSniffedMeta(meta);
116
117     int err = initStreams();
118     if (err < 0) {
119         ALOGE("failed to init ffmpeg");
120         return;
121     }
122
123     // start reader here, as we want to extract extradata from bitstream if no extradata
124     startReaderThread();
125
126     while(mProbePkts <= EXTRACTOR_MAX_PROBE_PACKETS && !mEOF &&
127         (mFormatCtx->pb ? !mFormatCtx->pb->error : 1) &&
128         (mDefersToCreateVideoTrack || mDefersToCreateAudioTrack)) {
129         // FIXME, i am so lazy! Should use pthread_cond_wait to wait conditions
130         usleep(5000);
131     }
132
133     ALOGV("mProbePkts: %d, mEOF: %d, pb->error(if has): %d, mDefersToCreateVideoTrack: %d, mDefersToCreateAudioTrack: %d",
134         mProbePkts, mEOF, mFormatCtx->pb ? mFormatCtx->pb->error : 0, mDefersToCreateVideoTrack, mDefersToCreateAudioTrack);
135
136     mInitCheck = OK;
137 }
138
139 FFmpegExtractor::~FFmpegExtractor() {
140     ALOGV("FFmpegExtractor::~FFmpegExtractor");
141
142     // stop reader here if no track!
143     stopReaderThread();
144
145     deInitStreams();
146 }
147
148 size_t FFmpegExtractor::countTracks() {
149     return mInitCheck == OK ? mTracks.size() : 0;
150 }
151
152 sp<MediaSource> FFmpegExtractor::getTrack(size_t index) {
153     ALOGV("FFmpegExtractor::getTrack[%d]", index);
154
155     if (mInitCheck != OK) {
156         return NULL;
157     }
158
159     if (index >= mTracks.size()) {
160         return NULL;
161     }
162
163     return mTracks.valueAt(index);
164 }
165
166 sp<MetaData> FFmpegExtractor::getTrackMetaData(size_t index, uint32_t flags) {
167     ALOGV("FFmpegExtractor::getTrackMetaData[%d]", index);
168
169     if (mInitCheck != OK) {
170         return NULL;
171     }
172
173     if (index >= mTracks.size()) {
174         return NULL;
175     }
176
177     return mTracks.valueAt(index)->getFormat();
178 }
179
180 sp<MetaData> FFmpegExtractor::getMetaData() {
181     ALOGV("FFmpegExtractor::getMetaData");
182
183     if (mInitCheck != OK) {
184         return NULL;
185     }
186
187     return mMeta;
188 }
189
190 uint32_t FFmpegExtractor::flags() const {
191     ALOGV("FFmpegExtractor::flags");
192
193     if (mInitCheck != OK) {
194         return 0;
195     }
196
197     uint32_t flags = CAN_PAUSE;
198
199     if (mFormatCtx->duration != AV_NOPTS_VALUE) {
200         flags |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK;
201     }
202
203     return flags;
204 }
205
206 int FFmpegExtractor::check_extradata(AVCodecContext *avctx)
207 {
208     enum AVCodecID codec_id = AV_CODEC_ID_NONE;
209     const char *name = NULL;
210     bool *defersToCreateTrack = NULL;
211     AVBitStreamFilterContext **bsfc = NULL;
212
213     // init
214     if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
215         bsfc = &mVideoBsfc;
216         defersToCreateTrack = &mDefersToCreateVideoTrack;
217     } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO){
218         bsfc = &mAudioBsfc;
219         defersToCreateTrack = &mDefersToCreateAudioTrack;
220     }
221
222         codec_id = avctx->codec_id;
223
224     // ignore extradata
225     if (codec_id != AV_CODEC_ID_H264
226             && codec_id != AV_CODEC_ID_MPEG4
227             && codec_id != AV_CODEC_ID_MPEG1VIDEO
228             && codec_id != AV_CODEC_ID_MPEG2VIDEO
229             && codec_id != AV_CODEC_ID_AAC) {
230         return 1;
231     }
232
233     // is extradata compatible with android?
234     if (codec_id != AV_CODEC_ID_AAC) {
235         int is_compatible = is_extradata_compatible_with_android(avctx);
236         if (!is_compatible) {
237             ALOGI("%s extradata is not compatible with android, should to extract it from bitstream",
238                     av_get_media_type_string(avctx->codec_type));
239             *defersToCreateTrack = true;
240             *bsfc = NULL; // H264 don't need bsfc, only AAC?
241             return 0;
242         }
243         return 1;
244     }
245
246     if (codec_id == AV_CODEC_ID_AAC) {
247         name = "aac_adtstoasc";
248     }
249
250     if (avctx->extradata_size <= 0) {
251         ALOGI("No %s extradata found, should to extract it from bitstream",
252                 av_get_media_type_string(avctx->codec_type));
253         *defersToCreateTrack = true;
254          //CHECK(name != NULL);
255         if (!*bsfc && name) {
256             *bsfc = av_bitstream_filter_init(name);
257             if (!*bsfc) {
258                 ALOGE("Cannot open the %s BSF!", name);
259                 *defersToCreateTrack = false;
260                 return -1;
261             } else {
262                 ALOGV("open the %s bsf", name);
263                 return 0;
264             }
265         } else {
266             return 0;
267         }
268     }
269     return 1;
270 }
271
272 void FFmpegExtractor::printTime(int64_t time)
273 {
274     int hours, mins, secs, us;
275
276     if (time == AV_NOPTS_VALUE)
277         return;
278
279     secs = time / AV_TIME_BASE;
280     us = time % AV_TIME_BASE;
281     mins = secs / 60;
282     secs %= 60;
283     hours = mins / 60;
284     mins %= 60;
285     ALOGI("the time is %02d:%02d:%02d.%02d",
286         hours, mins, secs, (100 * us) / AV_TIME_BASE);
287 }
288
289 bool FFmpegExtractor::is_codec_supported(enum AVCodecID codec_id)
290 {
291     bool supported = false;
292
293     switch(codec_id) {
294     case AV_CODEC_ID_H264:
295     case AV_CODEC_ID_MPEG4:
296     case AV_CODEC_ID_H263:
297     case AV_CODEC_ID_H263P:
298     case AV_CODEC_ID_H263I:
299     case AV_CODEC_ID_AAC:
300     case AV_CODEC_ID_AC3:
301     case AV_CODEC_ID_MP2:
302     case AV_CODEC_ID_MP3:
303     case AV_CODEC_ID_MPEG1VIDEO:
304     case AV_CODEC_ID_MPEG2VIDEO:
305     case AV_CODEC_ID_WMV1:
306     case AV_CODEC_ID_WMV2:
307     case AV_CODEC_ID_WMV3:
308     case AV_CODEC_ID_VC1:
309     case AV_CODEC_ID_WMAV1:
310     case AV_CODEC_ID_WMAV2:
311     case AV_CODEC_ID_WMAPRO:
312     case AV_CODEC_ID_WMALOSSLESS:
313     case AV_CODEC_ID_RV20:
314     case AV_CODEC_ID_RV30:
315     case AV_CODEC_ID_RV40:
316     case AV_CODEC_ID_COOK:
317     case AV_CODEC_ID_APE:
318     case AV_CODEC_ID_DTS:
319     case AV_CODEC_ID_FLAC:
320     case AV_CODEC_ID_FLV1:
321     case AV_CODEC_ID_VORBIS:
322     case AV_CODEC_ID_HEVC:
323
324         supported = true;
325         break;
326     default:
327         ALOGD("unsuppoted codec(%s), but give it a chance",
328                 avcodec_get_name(codec_id));
329         //Won't promise that the following codec id can be supported.
330             //Just give these codecs a chance.
331         supported = true;
332         break;
333     }
334
335         return supported;
336 }
337
338 sp<MetaData> FFmpegExtractor::setVideoFormat(AVStream *stream)
339 {
340     AVCodecContext *avctx = NULL;
341     sp<MetaData> meta = NULL;
342
343     avctx = stream->codec;
344     CHECK_EQ(avctx->codec_type, AVMEDIA_TYPE_VIDEO);
345
346     switch(avctx->codec_id) {
347     case AV_CODEC_ID_H264:
348         if (avctx->extradata[0] == 1) {
349             meta = setAVCFormat(avctx);
350         } else {
351             meta = setH264Format(avctx);
352         }
353         break;
354     case AV_CODEC_ID_MPEG4:
355         meta = setMPEG4Format(avctx);
356         break;
357     case AV_CODEC_ID_H263:
358     case AV_CODEC_ID_H263P:
359     case AV_CODEC_ID_H263I:
360         meta = setH263Format(avctx);
361         break;
362     case AV_CODEC_ID_MPEG1VIDEO:
363     case AV_CODEC_ID_MPEG2VIDEO:
364         meta = setMPEG2VIDEOFormat(avctx);
365         break;
366     case AV_CODEC_ID_VC1:
367         meta = setVC1Format(avctx);
368         break;
369     case AV_CODEC_ID_WMV1:
370         meta = setWMV1Format(avctx);
371         break;
372     case AV_CODEC_ID_WMV2:
373         meta = setWMV2Format(avctx);
374         break;
375     case AV_CODEC_ID_WMV3:
376         meta = setWMV3Format(avctx);
377         break;
378     case AV_CODEC_ID_RV20:
379         meta = setRV20Format(avctx);
380         break;
381     case AV_CODEC_ID_RV30:
382         meta = setRV30Format(avctx);
383         break;
384     case AV_CODEC_ID_RV40:
385         meta = setRV40Format(avctx);
386         break;
387     case AV_CODEC_ID_FLV1:
388         meta = setFLV1Format(avctx);
389         break;
390     case AV_CODEC_ID_HEVC:
391         meta = setHEVCFormat(avctx);
392         break;
393     default:
394         ALOGD("unsuppoted video codec(id:%d, name:%s), but give it a chance",
395                 avctx->codec_id, avcodec_get_name(avctx->codec_id));
396         meta = new MetaData;
397         meta->setInt32(kKeyCodecId, avctx->codec_id);
398         meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_FFMPEG);
399         if (avctx->extradata_size > 0) {
400             meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size);
401         }
402         //CHECK(!"Should not be here. Unsupported codec.");
403         break;
404     }
405
406     if (meta != NULL) {
407         ALOGI("width: %d, height: %d, bit_rate: %d",
408                 avctx->width, avctx->height, avctx->bit_rate);
409
410         meta->setInt32(kKeyWidth, avctx->width);
411         meta->setInt32(kKeyHeight, avctx->height);
412         if (avctx->bit_rate > 0) {
413             meta->setInt32(kKeyBitRate, avctx->bit_rate);
414         }
415         setDurationMetaData(stream, meta);
416         }
417
418     return meta;
419 }
420
421 sp<MetaData> FFmpegExtractor::setAudioFormat(AVStream *stream)
422 {
423     AVCodecContext *avctx = NULL;
424     sp<MetaData> meta = NULL;
425
426     avctx = stream->codec;
427     CHECK_EQ(avctx->codec_type, AVMEDIA_TYPE_AUDIO);
428
429     switch(avctx->codec_id) {
430     case AV_CODEC_ID_MP2:
431         meta = setMP2Format(avctx);
432         break;
433     case AV_CODEC_ID_MP3:
434         meta = setMP3Format(avctx);
435         break;
436     case AV_CODEC_ID_VORBIS:
437         meta = setVORBISFormat(avctx);
438         break;
439     case AV_CODEC_ID_AC3:
440         meta = setAC3Format(avctx);
441         break;
442     case AV_CODEC_ID_AAC:
443         meta = setAACFormat(avctx);
444         break;
445     case AV_CODEC_ID_WMAV1:
446         meta = setWMAV1Format(avctx);
447         break;
448     case AV_CODEC_ID_WMAV2:
449         meta = setWMAV2Format(avctx);
450         break;
451     case AV_CODEC_ID_WMAPRO:
452         meta = setWMAProFormat(avctx);
453         break;
454     case AV_CODEC_ID_WMALOSSLESS:
455         meta = setWMALossLessFormat(avctx);
456         break;
457     case AV_CODEC_ID_COOK:
458         meta = setRAFormat(avctx);
459         break;
460     case AV_CODEC_ID_APE:
461         meta = setAPEFormat(avctx);
462         break;
463     case AV_CODEC_ID_DTS:
464         meta = setDTSFormat(avctx);
465         break;
466     case AV_CODEC_ID_FLAC:
467         meta = setFLACFormat(avctx);
468         break;
469     default:
470         ALOGD("unsuppoted audio codec(id:%d, name:%s), but give it a chance",
471                 avctx->codec_id, avcodec_get_name(avctx->codec_id));
472         meta = new MetaData;
473         meta->setInt32(kKeyCodecId, avctx->codec_id);
474         meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FFMPEG);
475         if (avctx->extradata_size > 0) {
476             meta->setData(kKeyRawCodecSpecificData, 0, avctx->extradata, avctx->extradata_size);
477         }
478         //CHECK(!"Should not be here. Unsupported codec.");
479         break;
480     }
481
482     if (meta != NULL) {
483         ALOGI("bit_rate: %d, sample_rate: %d, channels: %d, "
484                 "bits_per_coded_sample: %d, block_align:%d",
485                 avctx->bit_rate, avctx->sample_rate, avctx->channels,
486                 avctx->bits_per_coded_sample, avctx->block_align);
487
488         meta->setInt32(kKeyChannelCount, avctx->channels);
489         meta->setInt32(kKeyBitRate, avctx->bit_rate);
490         meta->setInt32(kKeyBitspersample, avctx->bits_per_coded_sample);
491         meta->setInt32(kKeySampleRate, avctx->sample_rate);
492         meta->setInt32(kKeyBlockAlign, avctx->block_align);
493         meta->setInt32(kKeySampleFormat, avctx->sample_fmt);
494         setDurationMetaData(stream, meta);
495     }
496
497     return meta;
498 }
499
500 void FFmpegExtractor::setDurationMetaData(AVStream *stream, sp<MetaData> &meta)
501 {
502     AVCodecContext *avctx = stream->codec;
503
504     if (stream->duration != AV_NOPTS_VALUE) {
505         int64_t duration = stream->duration * av_q2d(stream->time_base) * 1000000;
506         printTime(duration);
507         const char *s = av_get_media_type_string(avctx->codec_type);
508         if (stream->start_time != AV_NOPTS_VALUE) {
509             ALOGV("%s startTime:%lld", s, stream->start_time);
510         } else {
511             ALOGV("%s startTime:N/A", s);
512         }
513         meta->setInt64(kKeyDuration, duration);
514     } else {
515         // default when no stream duration
516         meta->setInt64(kKeyDuration, mFormatCtx->duration);
517     }
518 }
519
520 int FFmpegExtractor::stream_component_open(int stream_index)
521 {
522     AVCodecContext *avctx = NULL;
523     sp<MetaData> meta = NULL;
524     bool supported = false;
525     uint32_t type = 0;
526     const void *data = NULL;
527     size_t size = 0;
528     int ret = 0;
529
530     ALOGI("stream_index: %d", stream_index);
531     if (stream_index < 0 || stream_index >= (int)mFormatCtx->nb_streams)
532         return -1;
533     avctx = mFormatCtx->streams[stream_index]->codec;
534
535     supported = is_codec_supported(avctx->codec_id);
536
537     if (!supported) {
538         ALOGE("unsupport the codec(%s)", avcodec_get_name(avctx->codec_id));
539         return -1;
540     }
541     ALOGI("support the codec(%s)", avcodec_get_name(avctx->codec_id));
542
543     unsigned streamType;
544     ssize_t index = mTracks.indexOfKey(stream_index);
545
546     if (index >= 0) {
547         ALOGE("this track already exists");
548         return 0;
549     }
550
551     mFormatCtx->streams[stream_index]->discard = AVDISCARD_DEFAULT;
552
553     char tagbuf[32];
554     av_get_codec_tag_string(tagbuf, sizeof(tagbuf), avctx->codec_tag);
555     ALOGV("Tag %s/0x%08x with codec(%s)\n", tagbuf, avctx->codec_tag, avcodec_get_name(avctx->codec_id));
556
557     switch (avctx->codec_type) {
558     case AVMEDIA_TYPE_VIDEO:
559         if (mVideoStreamIdx == -1)
560             mVideoStreamIdx = stream_index;
561         if (mVideoStream == NULL)
562             mVideoStream = mFormatCtx->streams[stream_index];
563
564         ret = check_extradata(avctx);
565         if (ret != 1) {
566             if (ret == -1) {
567                 // disable the stream
568                 mVideoStreamIdx = -1;
569                 mVideoStream = NULL;
570                 packet_queue_end(&mVideoQ);
571                 mFormatCtx->streams[stream_index]->discard = AVDISCARD_ALL;
572             }
573             return ret;
574          }
575 #if DEBUG_EXTRADATA
576         if (avctx->extradata) {
577             ALOGV("video stream extradata:");
578             hexdump(avctx->extradata, avctx->extradata_size);
579         } else {
580             ALOGV("video stream no extradata, but we can ignore it.");
581         }
582 #endif
583         meta = setVideoFormat(mVideoStream);
584         if (meta == NULL) {
585             ALOGE("setVideoFormat failed");
586             return -1;
587         }
588
589         ALOGV("create a video track");
590         index = mTracks.add(
591             stream_index, new Track(this, meta, mVideoStream, &mVideoQ));
592
593         mDefersToCreateVideoTrack = false;
594
595         break;
596     case AVMEDIA_TYPE_AUDIO:
597         if (mAudioStreamIdx == -1)
598             mAudioStreamIdx = stream_index;
599         if (mAudioStream == NULL)
600             mAudioStream = mFormatCtx->streams[stream_index];
601
602         ret = check_extradata(avctx);
603         if (ret != 1) {
604             if (ret == -1) {
605                 // disable the stream
606                 mAudioStreamIdx = -1;
607                 mAudioStream = NULL;
608                 packet_queue_end(&mAudioQ);
609                 mFormatCtx->streams[stream_index]->discard = AVDISCARD_ALL;
610             }
611             return ret;
612         }
613 #if DEBUG_EXTRADATA
614         if (avctx->extradata) {
615             ALOGV("audio stream extradata(%d):", avctx->extradata_size);
616             hexdump(avctx->extradata, avctx->extradata_size);
617         } else {
618             ALOGV("audio stream no extradata, but we can ignore it.");
619         }
620 #endif
621         meta = setAudioFormat(mAudioStream);
622         if (meta == NULL) {
623             ALOGE("setAudioFormat failed");
624             return -1;
625         }
626
627         ALOGV("create a audio track");
628         index = mTracks.add(
629             stream_index, new Track(this, meta, mAudioStream, &mAudioQ));
630
631         mDefersToCreateAudioTrack = false;
632
633         break;
634     case AVMEDIA_TYPE_SUBTITLE:
635         /* Unsupport now */
636         CHECK(!"Should not be here. Unsupported media type.");
637         break;
638     default:
639         CHECK(!"Should not be here. Unsupported media type.");
640         break;
641     }
642     return 0;
643 }
644
645 void FFmpegExtractor::stream_component_close(int stream_index)
646 {
647     AVCodecContext *avctx;
648
649     if (stream_index < 0 || stream_index >= (int)mFormatCtx->nb_streams)
650         return;
651     avctx = mFormatCtx->streams[stream_index]->codec;
652
653     switch (avctx->codec_type) {
654     case AVMEDIA_TYPE_VIDEO:
655         ALOGV("packet_queue_abort videoq");
656         packet_queue_abort(&mVideoQ);
657         /* wait until the end */
658         while (!mAbortRequest && !mVideoEOSReceived) {
659             ALOGV("wait for video received");
660             usleep(10000);
661         }
662         ALOGV("packet_queue_end videoq");
663         packet_queue_end(&mVideoQ);
664         break;
665     case AVMEDIA_TYPE_AUDIO:
666         ALOGV("packet_queue_abort audioq");
667         packet_queue_abort(&mAudioQ);
668         while (!mAbortRequest && !mAudioEOSReceived) {
669             ALOGV("wait for audio received");
670             usleep(10000);
671         }
672         ALOGV("packet_queue_end audioq");
673         packet_queue_end(&mAudioQ);
674         break;
675     case AVMEDIA_TYPE_SUBTITLE:
676         break;
677     default:
678         break;
679     }
680
681     mFormatCtx->streams[stream_index]->discard = AVDISCARD_ALL;
682     switch (avctx->codec_type) {
683     case AVMEDIA_TYPE_VIDEO:
684         mVideoStream    = NULL;
685         mVideoStreamIdx = -1;
686         if (mVideoBsfc) {
687             av_bitstream_filter_close(mVideoBsfc);
688             mVideoBsfc  = NULL;
689         }
690         break;
691     case AVMEDIA_TYPE_AUDIO:
692         mAudioStream    = NULL;
693         mAudioStreamIdx = -1;
694         if (mAudioBsfc) {
695             av_bitstream_filter_close(mAudioBsfc);
696             mAudioBsfc  = NULL;
697         }
698         break;
699     case AVMEDIA_TYPE_SUBTITLE:
700         break;
701     default:
702         break;
703     }
704 }
705
706 void FFmpegExtractor::reachedEOS(enum AVMediaType media_type)
707 {
708     Mutex::Autolock autoLock(mLock);
709
710     if (media_type == AVMEDIA_TYPE_VIDEO) {
711         mVideoEOSReceived = true;
712     } else if (media_type == AVMEDIA_TYPE_AUDIO) {
713         mAudioEOSReceived = true;
714     }
715 }
716
717 /* seek in the stream */
718 int FFmpegExtractor::stream_seek(int64_t pos, enum AVMediaType media_type)
719 {
720     Mutex::Autolock autoLock(mLock);
721
722     if (mVideoStreamIdx >= 0
723             && mAudioStreamIdx >= 0
724             && media_type == AVMEDIA_TYPE_AUDIO
725             && !mVideoEOSReceived) {
726        return NO_SEEK;
727     }
728
729     // flush immediately
730     if (mAudioStreamIdx >= 0)
731         packet_queue_flush(&mAudioQ);
732     if (mVideoStreamIdx >= 0)
733         packet_queue_flush(&mVideoQ);
734
735     mSeekPos = pos;
736     mSeekFlags &= ~AVSEEK_FLAG_BYTE;
737     mSeekReq = 1;
738
739     return SEEK;
740 }
741
742 // staitc
743 int FFmpegExtractor::decode_interrupt_cb(void *ctx)
744 {
745     FFmpegExtractor *extrator = static_cast<FFmpegExtractor *>(ctx);
746     return extrator->mAbortRequest;
747 }
748
749 void FFmpegExtractor::fetchStuffsFromSniffedMeta(const sp<AMessage> &meta)
750 {
751     AString url;
752     AString mime;
753
754     //url
755     CHECK(meta->findString("extended-extractor-url", &url));
756     CHECK(url.c_str() != NULL);
757     CHECK(url.size() < PATH_MAX);
758
759     memcpy(mFilename, url.c_str(), url.size());
760     mFilename[url.size()] = '\0';
761
762     //mime
763     CHECK(meta->findString("extended-extractor-mime", &mime));
764     CHECK(mime.c_str() != NULL);
765     mMeta->setCString(kKeyMIMEType, mime.c_str());
766 }
767
768 void FFmpegExtractor::setFFmpegDefaultOpts()
769 {
770     mGenPTS       = 0;
771 #if DEBUG_DISABLE_VIDEO
772     mVideoDisable = 1;
773 #else
774     mVideoDisable = 0;
775 #endif
776 #if DEBUG_DISABLE_AUDIO
777     mAudioDisable = 1;
778 #else
779     mAudioDisable = 0;
780 #endif
781     mShowStatus   = 0;
782     mSeekByBytes  = 0; /* seek by bytes 0=off 1=on -1=auto" */
783     mDuration     = AV_NOPTS_VALUE;
784     mSeekPos      = AV_NOPTS_VALUE;
785     mAutoExit     = 1;
786     mLoop         = 1;
787
788     mVideoStreamIdx = -1;
789     mAudioStreamIdx = -1;
790     mVideoStream  = NULL;
791     mAudioStream  = NULL;
792     mDefersToCreateVideoTrack = false;
793     mDefersToCreateAudioTrack = false;
794     mVideoBsfc = NULL;
795     mAudioBsfc = NULL;
796
797     mAbortRequest = 0;
798     mPaused       = 0;
799     mLastPaused   = 0;
800     mSeekReq      = 0;
801
802     mProbePkts    = 0;
803     mEOF          = false;
804 }
805
806 int FFmpegExtractor::initStreams()
807 {
808     int err = 0;
809         int i = 0;
810     status_t status = UNKNOWN_ERROR;
811     int eof = 0;
812     int ret = 0, audio_ret = -1, video_ret = -1;
813     int pkt_in_play_range = 0;
814     AVDictionaryEntry *t = NULL;
815     AVDictionary **opts = NULL;
816     int orig_nb_streams = 0;
817     int st_index[AVMEDIA_TYPE_NB] = {0};
818     int wanted_stream[AVMEDIA_TYPE_NB] = {0};
819     st_index[AVMEDIA_TYPE_AUDIO]  = -1;
820     st_index[AVMEDIA_TYPE_VIDEO]  = -1;
821     wanted_stream[AVMEDIA_TYPE_AUDIO]  = -1;
822     wanted_stream[AVMEDIA_TYPE_VIDEO]  = -1;
823     const char *mime = NULL;
824
825     setFFmpegDefaultOpts();
826
827     status = initFFmpeg();
828     if (status != OK) {
829         ret = -1;
830         goto fail;
831     }
832     mFFmpegInited = true;
833
834     mFormatCtx = avformat_alloc_context();
835         if (!mFormatCtx)
836         {
837         ALOGE("oom for alloc avformat context");
838         ret = -1;
839         goto fail;
840         }
841     mFormatCtx->interrupt_callback.callback = decode_interrupt_cb;
842     mFormatCtx->interrupt_callback.opaque = this;
843     ALOGV("mFilename: %s", mFilename);
844     err = avformat_open_input(&mFormatCtx, mFilename, NULL, &format_opts);
845     if (err < 0) {
846         ALOGE("%s: avformat_open_input failed, err:%s", mFilename, av_err2str(err));
847         ret = -1;
848         goto fail;
849     }
850
851     if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
852         ALOGE("Option %s not found.\n", t->key);
853         //ret = AVERROR_OPTION_NOT_FOUND;
854         ret = -1;
855         goto fail;
856     }
857
858     if (mGenPTS)
859         mFormatCtx->flags |= AVFMT_FLAG_GENPTS;
860
861     opts = setup_find_stream_info_opts(mFormatCtx, codec_opts);
862     orig_nb_streams = mFormatCtx->nb_streams;
863
864     err = avformat_find_stream_info(mFormatCtx, opts);
865     if (err < 0) {
866         ALOGE("%s: could not find stream info, err:%s", mFilename, av_err2str(err));
867         ret = -1;
868         goto fail;
869     }
870     for (i = 0; i < orig_nb_streams; i++)
871         av_dict_free(&opts[i]);
872     av_freep(&opts);
873
874     if (mFormatCtx->pb)
875         mFormatCtx->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use url_feof() to test for the end
876
877     if (mSeekByBytes < 0)
878         mSeekByBytes = !!(mFormatCtx->iformat->flags & AVFMT_TS_DISCONT);
879
880     for (i = 0; i < (int)mFormatCtx->nb_streams; i++)
881         mFormatCtx->streams[i]->discard = AVDISCARD_ALL;
882     if (!mVideoDisable)
883         st_index[AVMEDIA_TYPE_VIDEO] =
884             av_find_best_stream(mFormatCtx, AVMEDIA_TYPE_VIDEO,
885                                 wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
886     if (!mAudioDisable)
887         st_index[AVMEDIA_TYPE_AUDIO] =
888             av_find_best_stream(mFormatCtx, AVMEDIA_TYPE_AUDIO,
889                                 wanted_stream[AVMEDIA_TYPE_AUDIO],
890                                 st_index[AVMEDIA_TYPE_VIDEO],
891                                 NULL, 0);
892     if (mShowStatus) {
893         av_dump_format(mFormatCtx, 0, mFilename, 0);
894     }
895
896     if (mFormatCtx->duration != AV_NOPTS_VALUE &&
897             mFormatCtx->start_time != AV_NOPTS_VALUE) {
898         int hours, mins, secs, us;
899
900         ALOGV("file startTime: %lld", mFormatCtx->start_time);
901
902         mDuration = mFormatCtx->duration;
903
904         secs = mDuration / AV_TIME_BASE;
905         us = mDuration % AV_TIME_BASE;
906         mins = secs / 60;
907         secs %= 60;
908         hours = mins / 60;
909         mins %= 60;
910         ALOGI("the duration is %02d:%02d:%02d.%02d",
911             hours, mins, secs, (100 * us) / AV_TIME_BASE);
912     }
913
914     packet_queue_init(&mVideoQ);
915     packet_queue_init(&mAudioQ);
916
917     if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
918         audio_ret = stream_component_open(st_index[AVMEDIA_TYPE_AUDIO]);
919     }
920
921     if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
922         video_ret = stream_component_open(st_index[AVMEDIA_TYPE_VIDEO]);
923     }
924
925     if ( audio_ret < 0 && video_ret < 0) {
926         ALOGE("%s: could not open codecs\n", mFilename);
927         ret = -1;
928         goto fail;
929     }
930
931     ret = 0;
932
933 fail:
934     return ret;
935 }
936
937 void FFmpegExtractor::deInitStreams()
938 {
939     packet_queue_destroy(&mVideoQ);
940     packet_queue_destroy(&mAudioQ);
941
942     if (mFormatCtx) {
943         avformat_close_input(&mFormatCtx);
944     }
945
946     if (mFFmpegInited) {
947         deInitFFmpeg();
948     }
949 }
950
951 status_t FFmpegExtractor::startReaderThread() {
952     ALOGV("Starting reader thread");
953     Mutex::Autolock autoLock(mLock);
954
955     if (mReaderThreadStarted)
956         return OK;
957
958     pthread_attr_t attr;
959     pthread_attr_init(&attr);
960     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
961     pthread_create(&mReaderThread, &attr, ReaderWrapper, this);
962     pthread_attr_destroy(&attr);
963     mReaderThreadStarted = true;
964     ALOGD("Reader thread started");
965
966     return OK;
967 }
968
969 void FFmpegExtractor::stopReaderThread() {
970     ALOGV("Stopping reader thread");
971     Mutex::Autolock autoLock(mLock);
972
973     if (!mReaderThreadStarted) {
974         ALOGD("Reader thread have been stopped");
975         return;
976     }
977
978     mAbortRequest = 1;
979
980     void *dummy;
981     pthread_join(mReaderThread, &dummy);
982     mReaderThreadStarted = false;
983     ALOGD("Reader thread stopped");
984 }
985
986 // static
987 void *FFmpegExtractor::ReaderWrapper(void *me) {
988     ((FFmpegExtractor *)me)->readerEntry();
989
990     return NULL;
991 }
992
993 void FFmpegExtractor::readerEntry() {
994     int err, i, ret;
995     AVPacket pkt1, *pkt = &pkt1;
996     int eof = 0;
997     int pkt_in_play_range = 0;
998
999     ALOGV("FFmpegExtractor enter thread(readerEntry)");
1000
1001     mVideoEOSReceived = false;
1002     mAudioEOSReceived = false;
1003
1004     for (;;) {
1005         if (mAbortRequest)
1006             break;
1007
1008         if (mPaused != mLastPaused) {
1009             mLastPaused = mPaused;
1010             if (mPaused)
1011                 mReadPauseReturn = av_read_pause(mFormatCtx);
1012             else
1013                 av_read_play(mFormatCtx);
1014         }
1015 #if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
1016         if (mPaused &&
1017                 (!strcmp(mFormatCtx->iformat->name, "rtsp") ||
1018                  (mFormatCtx->pb && !strncmp(mFilename, "mmsh:", 5)))) {
1019             /* wait 10 ms to avoid trying to get another packet */
1020             /* XXX: horrible */
1021             usleep(10000);
1022             continue;
1023         }
1024 #endif
1025
1026         if (mSeekReq) {
1027             ALOGV("readerEntry, mSeekReq: %d", mSeekReq);
1028             ret = avformat_seek_file(mFormatCtx, -1, INT64_MIN, mSeekPos, INT64_MAX, mSeekFlags);
1029             if (ret < 0) {
1030                 ALOGE("%s: error while seeking", mFormatCtx->filename);
1031             } else {
1032                 if (mAudioStreamIdx >= 0) {
1033                     packet_queue_flush(&mAudioQ);
1034                     packet_queue_put(&mAudioQ, &mAudioQ.flush_pkt);
1035                 }
1036                 if (mVideoStreamIdx >= 0) {
1037                     packet_queue_flush(&mVideoQ);
1038                     packet_queue_put(&mVideoQ, &mVideoQ.flush_pkt);
1039                 }
1040             }
1041             mSeekReq = 0;
1042             eof = 0;
1043         }
1044
1045         /* if the queue are full, no need to read more */
1046         if (   mAudioQ.size + mVideoQ.size > MAX_QUEUE_SIZE
1047             || (   (mAudioQ   .size  > MIN_AUDIOQ_SIZE || mAudioStreamIdx < 0)
1048                 && (mVideoQ   .nb_packets > MIN_FRAMES || mVideoStreamIdx < 0))) {
1049 #if DEBUG_READ_ENTRY
1050             ALOGV("readerEntry, full(wtf!!!), mVideoQ.size: %d, mVideoQ.nb_packets: %d, mAudioQ.size: %d, mAudioQ.nb_packets: %d",
1051                     mVideoQ.size, mVideoQ.nb_packets, mAudioQ.size, mAudioQ.nb_packets);
1052 #endif
1053             /* wait 10 ms */
1054             usleep(10000);
1055             continue;
1056         }
1057
1058         if (eof) {
1059             if (mVideoStreamIdx >= 0) {
1060                 packet_queue_put_nullpacket(&mVideoQ, mVideoStreamIdx);
1061             }
1062             if (mAudioStreamIdx >= 0) {
1063                 packet_queue_put_nullpacket(&mAudioQ, mAudioStreamIdx);
1064             }
1065             usleep(10000);
1066 #if DEBUG_READ_ENTRY
1067             ALOGV("readerEntry, eof = 1, mVideoQ.size: %d, mVideoQ.nb_packets: %d, mAudioQ.size: %d, mAudioQ.nb_packets: %d",
1068                     mVideoQ.size, mVideoQ.nb_packets, mAudioQ.size, mAudioQ.nb_packets);
1069 #endif
1070             if (mAudioQ.size + mVideoQ.size  == 0) {
1071                 if (mAutoExit) {
1072                     ret = AVERROR_EOF;
1073                     goto fail;
1074                 }
1075             }
1076             eof=0;
1077             continue;
1078         }
1079
1080         ret = av_read_frame(mFormatCtx, pkt);
1081         mProbePkts++;
1082         if (ret < 0) {
1083             if (ret == AVERROR_EOF || url_feof(mFormatCtx->pb))
1084                 if (ret == AVERROR_EOF) {
1085                     //ALOGV("ret == AVERROR_EOF");
1086                 }
1087                 if (url_feof(mFormatCtx->pb)) {
1088                     //ALOGV("url_feof(mFormatCtx->pb)");
1089                 }
1090
1091                 eof = 1;
1092                 mEOF = true;
1093             if (mFormatCtx->pb && mFormatCtx->pb->error) {
1094                 ALOGE("mFormatCtx->pb->error: %d", mFormatCtx->pb->error);
1095                 break;
1096             }
1097             usleep(100000);
1098             continue;
1099         }
1100
1101         if (pkt->stream_index == mVideoStreamIdx) {
1102              if (mDefersToCreateVideoTrack) {
1103                 AVCodecContext *avctx = mFormatCtx->streams[mVideoStreamIdx]->codec;
1104
1105                 int i = parser_split(avctx, pkt->data, pkt->size);
1106                 if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {
1107                     if (avctx->extradata)
1108                         av_freep(&avctx->extradata);
1109                     avctx->extradata_size= i;
1110                     avctx->extradata = (uint8_t *)av_malloc(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
1111                     if (!avctx->extradata) {
1112                         //return AVERROR(ENOMEM);
1113                         ret = AVERROR(ENOMEM);
1114                         goto fail;
1115                     }
1116                     // sps + pps(there may be sei in it)
1117                     memcpy(avctx->extradata, pkt->data, avctx->extradata_size);
1118                     memset(avctx->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE);
1119                 } else {
1120                     av_free_packet(pkt);
1121                     continue;
1122                 }
1123
1124                 stream_component_open(mVideoStreamIdx);
1125                 if (!mDefersToCreateVideoTrack)
1126                     ALOGI("probe packet counter: %d when create video track ok", mProbePkts);
1127                 if (mProbePkts == EXTRACTOR_MAX_PROBE_PACKETS)
1128                     ALOGI("probe packet counter to max: %d, create video track: %d",
1129                         mProbePkts, !mDefersToCreateVideoTrack);
1130             }
1131         } else if (pkt->stream_index == mAudioStreamIdx) {
1132             int ret;
1133             uint8_t *outbuf;
1134             int   outbuf_size;
1135             AVCodecContext *avctx = mFormatCtx->streams[mAudioStreamIdx]->codec;
1136             if (mAudioBsfc && pkt && pkt->data) {
1137                 ret = av_bitstream_filter_filter(mAudioBsfc, avctx, NULL, &outbuf, &outbuf_size,
1138                                    pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY);
1139
1140                 if (ret < 0 ||!outbuf_size) {
1141                     av_free_packet(pkt);
1142                     continue;
1143                 }
1144                 if (outbuf && outbuf != pkt->data) {
1145                     memmove(pkt->data, outbuf, outbuf_size);
1146                     pkt->size = outbuf_size;
1147                 }
1148             }
1149             if (mDefersToCreateAudioTrack) {
1150                 if (avctx->extradata_size <= 0) {
1151                     av_free_packet(pkt);
1152                     continue;
1153                 }
1154                 stream_component_open(mAudioStreamIdx);
1155                 if (!mDefersToCreateAudioTrack)
1156                     ALOGI("probe packet counter: %d when create audio track ok", mProbePkts);
1157                 if (mProbePkts == EXTRACTOR_MAX_PROBE_PACKETS)
1158                     ALOGI("probe packet counter to max: %d, create audio track: %d",
1159                         mProbePkts, !mDefersToCreateAudioTrack);
1160             }
1161         }
1162
1163         if (pkt->stream_index == mAudioStreamIdx) {
1164             packet_queue_put(&mAudioQ, pkt);
1165         } else if (pkt->stream_index == mVideoStreamIdx) {
1166             packet_queue_put(&mVideoQ, pkt);
1167         } else {
1168             av_free_packet(pkt);
1169         }
1170     }
1171     /* wait until the end */
1172     while (!mAbortRequest) {
1173         usleep(100000);
1174     }
1175
1176     ret = 0;
1177 fail:
1178     ALOGI("reader thread goto end...");
1179
1180     /* close each stream */
1181     if (mAudioStreamIdx >= 0)
1182         stream_component_close(mAudioStreamIdx);
1183     if (mVideoStreamIdx >= 0)
1184         stream_component_close(mVideoStreamIdx);
1185     if (mFormatCtx) {
1186         avformat_close_input(&mFormatCtx);
1187     }
1188
1189     ALOGV("FFmpegExtractor exit thread(readerEntry)");
1190 }
1191
1192 ////////////////////////////////////////////////////////////////////////////////
1193
1194 FFmpegExtractor::Track::Track(
1195         FFmpegExtractor *extractor, sp<MetaData> meta,
1196         AVStream *stream, PacketQueue *queue)
1197     : mExtractor(extractor),
1198       mMeta(meta),
1199       mIsAVC(false),
1200       mNal2AnnexB(false),
1201       mStream(stream),
1202       mQueue(queue) {
1203     const char *mime;
1204
1205     /* H.264 Video Types */
1206     {
1207         AVCodecContext *avctx = stream->codec;
1208
1209         if (avctx->codec_id == AV_CODEC_ID_H264
1210                 && avctx->extradata_size > 0
1211                 && avctx->extradata[0] == 1) {
1212             mIsAVC = true;
1213
1214             uint32_t type;
1215             const void *data;
1216             size_t size;
1217             CHECK(meta->findData(kKeyAVCC, &type, &data, &size));
1218
1219             const uint8_t *ptr = (const uint8_t *)data;
1220
1221             CHECK(size >= 7);
1222             CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
1223
1224             // The number of bytes used to encode the length of a NAL unit.
1225             mNALLengthSize = 1 + (ptr[4] & 3);
1226
1227             ALOGV("the stream is AVC, the length of a NAL unit: %d", mNALLengthSize);
1228
1229             mNal2AnnexB = true;
1230         }
1231     }
1232
1233     mMediaType = mStream->codec->codec_type;
1234     mFirstKeyPktTimestamp = AV_NOPTS_VALUE;
1235 }
1236
1237 FFmpegExtractor::Track::~Track() {
1238     ALOGV("FFmpegExtractor::Track::~Track %s",
1239             av_get_media_type_string(mMediaType));
1240         mExtractor = NULL;
1241         mMeta = NULL;
1242 }
1243
1244 status_t FFmpegExtractor::Track::start(MetaData *params) {
1245     ALOGV("FFmpegExtractor::Track::start %s",
1246             av_get_media_type_string(mMediaType));
1247     Mutex::Autolock autoLock(mLock);
1248     //mExtractor->startReaderThread();
1249     return OK;
1250 }
1251
1252 status_t FFmpegExtractor::Track::stop() {
1253     ALOGV("FFmpegExtractor::Track::stop %s",
1254             av_get_media_type_string(mMediaType));
1255     Mutex::Autolock autoLock(mLock);
1256     //mExtractor->stopReaderThread();
1257     return OK;
1258 }
1259
1260 sp<MetaData> FFmpegExtractor::Track::getFormat() {
1261     Mutex::Autolock autoLock(mLock);
1262
1263     return mMeta;
1264 }
1265
1266 status_t FFmpegExtractor::Track::read(
1267         MediaBuffer **buffer, const ReadOptions *options) {
1268     *buffer = NULL;
1269
1270     Mutex::Autolock autoLock(mLock);
1271
1272     AVPacket pkt;
1273     bool seeking = false;
1274     bool waitKeyPkt = false;
1275     ReadOptions::SeekMode mode;
1276     int64_t pktTS = AV_NOPTS_VALUE;
1277     int64_t seekTimeUs = AV_NOPTS_VALUE;
1278     int64_t timeUs = AV_NOPTS_VALUE;
1279     int key = 0;
1280     status_t status = OK;
1281
1282     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
1283         ALOGV("~~~%s seekTimeUs: %lld, mode: %d", av_get_media_type_string(mMediaType), seekTimeUs, mode);
1284         /* add the stream start time */
1285         if (mStream->start_time != AV_NOPTS_VALUE)
1286             seekTimeUs += mStream->start_time * av_q2d(mStream->time_base) * 1000000;
1287         ALOGV("~~~%s seekTimeUs[+startTime]: %lld, mode: %d", av_get_media_type_string(mMediaType), seekTimeUs, mode);
1288
1289         if (mExtractor->stream_seek(seekTimeUs, mMediaType) == SEEK)
1290             seeking = true;
1291     }
1292
1293 retry:
1294     if (packet_queue_get(mQueue, &pkt, 1) < 0) {
1295         mExtractor->reachedEOS(mMediaType);
1296         return ERROR_END_OF_STREAM;
1297     }
1298
1299     if (seeking) {
1300         if (pkt.data != mQueue->flush_pkt.data) {
1301             av_free_packet(&pkt);
1302             goto retry;
1303         } else {
1304             seeking = false;
1305 #if WAIT_KEY_PACKET_AFTER_SEEK
1306             waitKeyPkt = true;
1307 #endif
1308         }
1309     }
1310
1311     if (pkt.data == mQueue->flush_pkt.data) {
1312         ALOGV("read %s flush pkt", av_get_media_type_string(mMediaType));
1313         av_free_packet(&pkt);
1314         mFirstKeyPktTimestamp = AV_NOPTS_VALUE;
1315         goto retry;
1316     } else if (pkt.data == NULL && pkt.size == 0) {
1317         ALOGD("read %s eos pkt", av_get_media_type_string(mMediaType));
1318         av_free_packet(&pkt);
1319         mExtractor->reachedEOS(mMediaType);
1320             return ERROR_END_OF_STREAM;
1321     }
1322
1323     key = pkt.flags & AV_PKT_FLAG_KEY ? 1 : 0;
1324     pktTS = pkt.pts; //FIXME AV_NOPTS_VALUE??
1325
1326     //use dts when AVI
1327     if (pkt.pts == AV_NOPTS_VALUE)
1328         pktTS = pkt.dts;
1329
1330     //FIXME, drop, omxcodec requires a positive timestamp! e.g. vorbis
1331     if (pktTS != AV_NOPTS_VALUE && pktTS < 0) {
1332         ALOGW("drop the packet with negative timestamp(pts:%lld)", pktTS);
1333         av_free_packet(&pkt);
1334         goto retry;
1335     }
1336
1337     if (waitKeyPkt) {
1338         if (!key) {
1339             ALOGV("drop the non-key packet");
1340             av_free_packet(&pkt);
1341             goto retry;
1342         } else {
1343             ALOGV("~~~~~~ got the key packet");
1344             waitKeyPkt = false;
1345         }
1346     }
1347
1348     if (pktTS != AV_NOPTS_VALUE && mFirstKeyPktTimestamp == AV_NOPTS_VALUE) {
1349         // update the first key timestamp
1350         mFirstKeyPktTimestamp = pktTS;
1351     }
1352      
1353     if (pktTS != AV_NOPTS_VALUE && pktTS < mFirstKeyPktTimestamp) {
1354             ALOGV("drop the packet with the backward timestamp, maybe they are B-frames after I-frame ^_^");
1355             av_free_packet(&pkt);
1356             goto retry;
1357     }
1358
1359     MediaBuffer *mediaBuffer = new MediaBuffer(pkt.size + FF_INPUT_BUFFER_PADDING_SIZE);
1360     mediaBuffer->meta_data()->clear();
1361     mediaBuffer->set_range(0, pkt.size);
1362
1363     //copy data
1364     if (mIsAVC && mNal2AnnexB) {
1365         /* This only works for NAL sizes 3-4 */
1366         CHECK(mNALLengthSize == 3 || mNALLengthSize == 4);
1367
1368         uint8_t *dst = (uint8_t *)mediaBuffer->data();
1369         /* Convert H.264 NAL format to annex b */
1370         status = convertNal2AnnexB(dst, pkt.size, pkt.data, pkt.size, mNALLengthSize);
1371         if (status != OK) {
1372             ALOGE("convertNal2AnnexB failed");
1373             mediaBuffer->release();
1374             mediaBuffer = NULL;
1375             av_free_packet(&pkt);
1376             return ERROR_MALFORMED;
1377         }
1378     } else {
1379         memcpy(mediaBuffer->data(), pkt.data, pkt.size);
1380     }
1381
1382     int64_t start_time = mStream->start_time != AV_NOPTS_VALUE ? mStream->start_time : 0;
1383     if (pktTS != AV_NOPTS_VALUE)
1384         timeUs = (int64_t)((pktTS - start_time) * av_q2d(mStream->time_base) * 1000000);
1385     else
1386         timeUs = SF_NOPTS_VALUE; //FIXME AV_NOPTS_VALUE is negative, but stagefright need positive
1387
1388 #if DEBUG_PKT
1389     if (pktTS != AV_NOPTS_VALUE)
1390         ALOGV("read %s pkt, size:%d, key:%d, pts:%lld, dts:%lld, timeUs[-startTime]:%lld us (%.2f secs)",
1391             av_get_media_type_string(mMediaType), pkt.size, key, pkt.pts, pkt.dts, timeUs, timeUs/1E6);
1392     else
1393         ALOGV("read %s pkt, size:%d, key:%d, pts:N/A, dts:N/A, timeUs[-startTime]:N/A",
1394             av_get_media_type_string(mMediaType), pkt.size, key);
1395 #endif
1396
1397     mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
1398     mediaBuffer->meta_data()->setInt32(kKeyIsSyncFrame, key);
1399
1400     *buffer = mediaBuffer;
1401
1402     av_free_packet(&pkt);
1403
1404     return OK;
1405 }
1406
1407 ////////////////////////////////////////////////////////////////////////////////
1408
1409 typedef struct {
1410     const char *format;
1411     const char *container;
1412 } formatmap;
1413
1414 static formatmap FILE_FORMATS[] = {
1415         {"mpeg",                    MEDIA_MIMETYPE_CONTAINER_MPEG2PS  },
1416         {"mpegts",                  MEDIA_MIMETYPE_CONTAINER_TS       },
1417         {"mov,mp4,m4a,3gp,3g2,mj2", MEDIA_MIMETYPE_CONTAINER_MPEG4    },
1418         {"matroska,webm",           MEDIA_MIMETYPE_CONTAINER_MATROSKA },
1419         {"asf",                     MEDIA_MIMETYPE_CONTAINER_ASF      },
1420         {"rm",                      MEDIA_MIMETYPE_CONTAINER_RM       },
1421         {"flv",                     MEDIA_MIMETYPE_CONTAINER_FLV      },
1422         {"swf",                     MEDIA_MIMETYPE_CONTAINER_FLV      },
1423         {"avi",                     MEDIA_MIMETYPE_CONTAINER_AVI      },
1424         {"ape",                     MEDIA_MIMETYPE_CONTAINER_APE      },
1425         {"dts",                     MEDIA_MIMETYPE_CONTAINER_DTS      },
1426         {"flac",                    MEDIA_MIMETYPE_CONTAINER_FLAC     },
1427         {"ac3",                     MEDIA_MIMETYPE_AUDIO_AC3          },
1428         {"wav",                     MEDIA_MIMETYPE_CONTAINER_WAV      },
1429         {"ogg",                     MEDIA_MIMETYPE_CONTAINER_OGG      },
1430         {"vc1",                     MEDIA_MIMETYPE_CONTAINER_VC1      },
1431         {"hevc",                    MEDIA_MIMETYPE_CONTAINER_HEVC     },
1432 };
1433
1434 static enum AVCodecID getCodecId(AVFormatContext *ic, AVMediaType codec_type)
1435 {
1436         unsigned int idx = 0;
1437         AVCodecContext *avctx = NULL;
1438
1439         for (idx = 0; idx < ic->nb_streams; idx++) {
1440                 avctx = ic->streams[idx]->codec;
1441                 if (avctx->codec_type == codec_type) {
1442                         return avctx->codec_id;
1443                 }
1444         }
1445
1446         return AV_CODEC_ID_NONE;
1447 }
1448
1449 static bool hasAudioCodecOnly(AVFormatContext *ic)
1450 {
1451         enum AVCodecID codec_id = AV_CODEC_ID_NONE;
1452         bool haveVideo = false;
1453         bool haveAudio = false;
1454
1455         if (getCodecId(ic, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) {
1456                 haveVideo = true;
1457         }
1458         if (getCodecId(ic, AVMEDIA_TYPE_AUDIO) != AV_CODEC_ID_NONE) {
1459                 haveAudio = true;
1460         }
1461
1462         if (!haveVideo && haveAudio) {
1463                 return true;
1464         }
1465
1466         return false;
1467 }
1468
1469 //FIXME all codecs: frameworks/av/media/libstagefright/codecs/*
1470 static bool isCodecSupportedByStagefright(enum AVCodecID codec_id)
1471 {
1472     bool supported = false;
1473
1474     switch(codec_id) {
1475     //video
1476     case AV_CODEC_ID_H264:
1477     case AV_CODEC_ID_MPEG4:
1478     case AV_CODEC_ID_H263:
1479     case AV_CODEC_ID_H263P:
1480     case AV_CODEC_ID_H263I:
1481     case AV_CODEC_ID_VP6:
1482     case AV_CODEC_ID_VP8:
1483         //audio
1484     case AV_CODEC_ID_AAC:
1485     case AV_CODEC_ID_MP3:
1486     case AV_CODEC_ID_AMR_NB:
1487     case AV_CODEC_ID_AMR_WB:
1488     case AV_CODEC_ID_FLAC:
1489     case AV_CODEC_ID_VORBIS:
1490     case AV_CODEC_ID_PCM_MULAW: //g711
1491     case AV_CODEC_ID_PCM_ALAW:  //g711
1492     //case AV_CODEC_ID_PCM_XXX: //FIXME more PCM?
1493         supported = true;
1494         break;
1495
1496     default:
1497         break;
1498     }
1499
1500     ALOGD("%ssuppoted codec(%s) by official Stagefright",
1501             (supported ? "" : "un"),
1502             avcodec_get_name(codec_id));
1503
1504         return supported;
1505 }
1506
1507 static void adjustMPEG4Confidence(AVFormatContext *ic, float *confidence)
1508 {
1509         AVDictionary *tags = NULL;
1510         AVDictionaryEntry *tag = NULL;
1511         enum AVCodecID codec_id = AV_CODEC_ID_NONE;
1512
1513         //1. check codec id
1514         codec_id = getCodecId(ic, AVMEDIA_TYPE_VIDEO);
1515         if (codec_id != AV_CODEC_ID_NONE
1516                         && codec_id != AV_CODEC_ID_H264
1517                         && codec_id != AV_CODEC_ID_MPEG4
1518                         && codec_id != AV_CODEC_ID_H263
1519                         && codec_id != AV_CODEC_ID_H263P
1520                         && codec_id != AV_CODEC_ID_H263I) {
1521                 //the MEDIA_MIMETYPE_CONTAINER_MPEG4 of confidence is 0.4f
1522                 ALOGI("[mp4]video codec(%s), confidence should be larger than MPEG4Extractor",
1523                                 avcodec_get_name(codec_id));
1524                 *confidence = 0.41f;
1525         }
1526
1527         codec_id = getCodecId(ic, AVMEDIA_TYPE_AUDIO);
1528         if (codec_id != AV_CODEC_ID_NONE
1529                         && codec_id != AV_CODEC_ID_MP3
1530                         && codec_id != AV_CODEC_ID_AAC
1531                         && codec_id != AV_CODEC_ID_AMR_NB
1532                         && codec_id != AV_CODEC_ID_AMR_WB) {
1533                 ALOGI("[mp4]audio codec(%s), confidence should be larger than MPEG4Extractor",
1534                                 avcodec_get_name(codec_id));
1535                 *confidence = 0.41f;
1536         }
1537
1538         //2. check tag
1539         tags = ic->metadata;
1540         //NOTE: You can use command to show these tags,
1541         //e.g. "ffprobe -show_format 2012.mov"
1542         tag = av_dict_get(tags, "major_brand", NULL, 0);
1543         if (!tag) {
1544                 return;
1545         }
1546
1547         ALOGV("major_brand tag is:%s", tag->value);
1548
1549         //when MEDIA_MIMETYPE_CONTAINER_MPEG4
1550         //WTF, MPEG4Extractor.cpp can not extractor mov format
1551         //NOTE: isCompatibleBrand(MPEG4Extractor.cpp)
1552         //  Won't promise that the following file types can be played.
1553         //  Just give these file types a chance.
1554         //  FOURCC('q', 't', ' ', ' '),  // Apple's QuickTime
1555         //So......
1556         if (!strcmp(tag->value, "qt  ")) {
1557                 ALOGI("[mp4]format is mov, confidence should be larger than mpeg4");
1558                 *confidence = 0.41f;
1559         }
1560 }
1561
1562 static void adjustMPEG2TSConfidence(AVFormatContext *ic, float *confidence)
1563 {
1564         enum AVCodecID codec_id = AV_CODEC_ID_NONE;
1565
1566         codec_id = getCodecId(ic, AVMEDIA_TYPE_VIDEO);
1567         if (codec_id != AV_CODEC_ID_NONE
1568                         && codec_id != AV_CODEC_ID_H264
1569                         && codec_id != AV_CODEC_ID_MPEG4
1570                         && codec_id != AV_CODEC_ID_MPEG1VIDEO
1571                         && codec_id != AV_CODEC_ID_MPEG2VIDEO) {
1572                 //the MEDIA_MIMETYPE_CONTAINER_MPEG2TS of confidence is 0.1f
1573                 ALOGI("[mpeg2ts]video codec(%s), confidence should be larger than MPEG2TSExtractor",
1574                                 avcodec_get_name(codec_id));
1575                 *confidence = 0.11f;
1576         }
1577
1578         codec_id = getCodecId(ic, AVMEDIA_TYPE_AUDIO);
1579         if (codec_id != AV_CODEC_ID_NONE
1580                         && codec_id != AV_CODEC_ID_AAC
1581                         && codec_id != AV_CODEC_ID_PCM_S16LE //FIXME, AV_CODEC_ID_PCM_S24LE, AV_CODEC_ID_PCM_S32LE?
1582                         && codec_id != AV_CODEC_ID_MP1
1583                         && codec_id != AV_CODEC_ID_MP2
1584                         && codec_id != AV_CODEC_ID_MP3) {
1585                 ALOGI("[mpeg2ts]audio codec(%s), confidence should be larger than MPEG2TSExtractor",
1586                                 avcodec_get_name(codec_id));
1587                 *confidence = 0.11f;
1588         }
1589 }
1590
1591 static void adjustMKVConfidence(AVFormatContext *ic, float *confidence)
1592 {
1593         enum AVCodecID codec_id = AV_CODEC_ID_NONE;
1594
1595         codec_id = getCodecId(ic, AVMEDIA_TYPE_VIDEO);
1596         if (codec_id != AV_CODEC_ID_NONE
1597                         && codec_id != AV_CODEC_ID_H264
1598                         && codec_id != AV_CODEC_ID_MPEG4
1599                         && codec_id != AV_CODEC_ID_VP6
1600                         && codec_id != AV_CODEC_ID_VP8) {
1601                 //the MEDIA_MIMETYPE_CONTAINER_MATROSKA of confidence is 0.6f
1602                 ALOGI("[mkv]video codec(%s), confidence should be larger than MatroskaExtractor",
1603                                 avcodec_get_name(codec_id));
1604                 *confidence = 0.61f;
1605         }
1606
1607         codec_id = getCodecId(ic, AVMEDIA_TYPE_AUDIO);
1608         if (codec_id != AV_CODEC_ID_NONE
1609                         && codec_id != AV_CODEC_ID_AAC
1610                         && codec_id != AV_CODEC_ID_MP3
1611                         && codec_id != AV_CODEC_ID_VORBIS) {
1612                 ALOGI("[mkv]audio codec(%s), confidence should be larger than MatroskaExtractor",
1613                                 avcodec_get_name(codec_id));
1614                 *confidence = 0.61f;
1615         }
1616 }
1617
1618 static void adjustCodecConfidence(AVFormatContext *ic, float *confidence)
1619 {
1620         enum AVCodecID codec_id = AV_CODEC_ID_NONE;
1621
1622         codec_id = getCodecId(ic, AVMEDIA_TYPE_VIDEO);
1623         if (codec_id != AV_CODEC_ID_NONE) {
1624                 if (!isCodecSupportedByStagefright(codec_id)) {
1625                         *confidence = 0.88f;
1626                 }
1627         }
1628
1629         codec_id = getCodecId(ic, AVMEDIA_TYPE_AUDIO);
1630         if (codec_id != AV_CODEC_ID_NONE) {
1631                 if (!isCodecSupportedByStagefright(codec_id)) {
1632                         *confidence = 0.88f;
1633                 }
1634         }
1635
1636         if (getCodecId(ic, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE
1637                         && getCodecId(ic, AVMEDIA_TYPE_AUDIO) == AV_CODEC_ID_MP3) {
1638                 *confidence = 0.22f; //larger than MP3Extractor
1639         }
1640 }
1641
1642 //TODO need more checks
1643 static void adjustConfidenceIfNeeded(const char *mime,
1644                 AVFormatContext *ic, float *confidence)
1645 {
1646         //1. check mime
1647         if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)) {
1648                 adjustMPEG4Confidence(ic, confidence);
1649         } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
1650                 adjustMPEG2TSConfidence(ic, confidence);
1651         } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) {
1652                 adjustMKVConfidence(ic, confidence);
1653         } else {
1654                 //todo here
1655         }
1656
1657         if (*confidence > 0.08) {
1658                 return;
1659         }
1660
1661         //2. check codec
1662         adjustCodecConfidence(ic, confidence);
1663 }
1664
1665 static void adjustContainerIfNeeded(const char **mime, AVFormatContext *ic)
1666 {
1667         const char *newMime = *mime;
1668         enum AVCodecID codec_id = AV_CODEC_ID_NONE;
1669
1670         if (!hasAudioCodecOnly(ic)) {
1671                 return;
1672         }
1673
1674         codec_id = getCodecId(ic, AVMEDIA_TYPE_AUDIO);
1675         CHECK(codec_id != AV_CODEC_ID_NONE);
1676         switch (codec_id) {
1677         case AV_CODEC_ID_MP3:
1678                 newMime = MEDIA_MIMETYPE_AUDIO_MPEG;
1679                 break;
1680         case AV_CODEC_ID_AAC:
1681                 newMime = MEDIA_MIMETYPE_AUDIO_AAC;
1682                 break;
1683         case AV_CODEC_ID_VORBIS:
1684                 newMime = MEDIA_MIMETYPE_AUDIO_VORBIS;
1685                 break;
1686         case AV_CODEC_ID_FLAC:
1687                 newMime = MEDIA_MIMETYPE_AUDIO_FLAC;
1688                 break;
1689         case AV_CODEC_ID_AC3:
1690                 newMime = MEDIA_MIMETYPE_AUDIO_AC3;
1691                 break;
1692         case AV_CODEC_ID_APE:
1693                 newMime = MEDIA_MIMETYPE_AUDIO_APE;
1694                 break;
1695         case AV_CODEC_ID_DTS:
1696                 newMime = MEDIA_MIMETYPE_AUDIO_DTS;
1697                 break;
1698         case AV_CODEC_ID_MP2:
1699                 newMime = MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II;
1700                 break;
1701         case AV_CODEC_ID_COOK:
1702                 newMime = MEDIA_MIMETYPE_AUDIO_RA;
1703                 break;
1704         case AV_CODEC_ID_WMAV1:
1705         case AV_CODEC_ID_WMAV2:
1706         case AV_CODEC_ID_WMAPRO:
1707         case AV_CODEC_ID_WMALOSSLESS:
1708                 newMime = MEDIA_MIMETYPE_AUDIO_WMA;
1709                 break;
1710         default:
1711                 break;
1712         }
1713
1714         if (!strcmp(*mime, MEDIA_MIMETYPE_CONTAINER_FFMPEG)) {
1715                 newMime = MEDIA_MIMETYPE_AUDIO_FFMPEG;
1716         }
1717
1718         if (strcmp(*mime, newMime)) {
1719                 ALOGI("adjust mime(%s -> %s)", *mime, newMime);
1720                 *mime = newMime;
1721         }
1722 }
1723
1724 static const char *findMatchingContainer(const char *name)
1725 {
1726         size_t i = 0;
1727         const char *container = NULL;
1728
1729         ALOGI("list the formats suppoted by ffmpeg: ");
1730         ALOGI("========================================");
1731         for (i = 0; i < NELEM(FILE_FORMATS); ++i) {
1732                 ALOGV("format_names[%02d]: %s", i, FILE_FORMATS[i].format);
1733         }
1734         ALOGI("========================================");
1735
1736         for (i = 0; i < NELEM(FILE_FORMATS); ++i) {
1737                 int len = strlen(FILE_FORMATS[i].format);
1738                 if (!strncasecmp(name, FILE_FORMATS[i].format, len)) {
1739                         container = FILE_FORMATS[i].container;
1740                         break;
1741                 }
1742         }
1743
1744         return container;
1745 }
1746
1747 static const char *SniffFFMPEGCommon(const char *url, float *confidence)
1748 {
1749         int err = 0;
1750         size_t i = 0;
1751         size_t nb_streams = 0;
1752         const char *container = NULL;
1753         AVFormatContext *ic = NULL;
1754         AVDictionary **opts = NULL;
1755
1756         status_t status = initFFmpeg();
1757         if (status != OK) {
1758                 ALOGE("could not init ffmpeg");
1759                 return NULL;
1760         }
1761
1762         ic = avformat_alloc_context();
1763         if (!ic)
1764         {
1765                 ALOGE("oom for alloc avformat context");
1766                 goto fail;
1767         }
1768
1769         err = avformat_open_input(&ic, url, NULL, NULL);
1770         if (err < 0) {
1771         ALOGE("%s: avformat_open_input failed, err:%s", url, av_err2str(err));
1772                 goto fail;
1773         }
1774
1775         opts = setup_find_stream_info_opts(ic, codec_opts);
1776         nb_streams = ic->nb_streams;
1777         err = avformat_find_stream_info(ic, opts);
1778         if (err < 0) {
1779         ALOGE("%s: could not find stream info, err:%s", url, av_err2str(err));
1780                 goto fail;
1781         }
1782         for (i = 0; i < nb_streams; i++) {
1783                 av_dict_free(&opts[i]);
1784         }
1785         av_freep(&opts);
1786
1787         av_dump_format(ic, 0, url, 0);
1788
1789         ALOGI("FFmpegExtrator, url: %s, format_name: %s, format_long_name: %s",
1790                         url, ic->iformat->name, ic->iformat->long_name);
1791
1792         container = findMatchingContainer(ic->iformat->name);
1793
1794         if (container) {
1795                 adjustContainerIfNeeded(&container, ic);
1796                 adjustConfidenceIfNeeded(container, ic, confidence);
1797         }
1798
1799 fail:
1800         if (ic) {
1801                 avformat_close_input(&ic);
1802         }
1803         if (status == OK) {
1804                 deInitFFmpeg();
1805         }
1806
1807         return container;
1808 }
1809
1810 static const char *BetterSniffFFMPEG(const sp<DataSource> &source,
1811         float *confidence, sp<AMessage> meta)
1812 {
1813         const char *ret = NULL;
1814         char url[PATH_MAX] = {0};
1815
1816         ALOGI("android-source:%p", source.get());
1817
1818         // pass the addr of smart pointer("source")
1819         snprintf(url, sizeof(url), "android-source:%p", source.get());
1820
1821         ret = SniffFFMPEGCommon(url, confidence);
1822         if (ret) {
1823                 meta->setString("extended-extractor-url", url);
1824         }
1825
1826         return ret;
1827 }
1828
1829 static const char *LegacySniffFFMPEG(const sp<DataSource> &source,
1830          float *confidence, sp<AMessage> meta)
1831 {
1832         const char *ret = NULL;
1833         char url[PATH_MAX] = {0};
1834
1835         String8 uri = source->getUri();
1836         if (!uri.string()) {
1837                 return NULL;
1838         }
1839
1840         ALOGI("source url:%s", uri.string());
1841
1842         // pass the addr of smart pointer("source") + file name
1843         snprintf(url, sizeof(url), "android-source:%p|file:%s", source.get(), uri.string());
1844
1845         ret = SniffFFMPEGCommon(url, confidence);
1846         if (ret) {
1847                 meta->setString("extended-extractor-url", url);
1848         }
1849
1850         return ret;
1851 }
1852
1853 bool SniffFFMPEG(
1854         const sp<DataSource> &source, String8 *mimeType, float *confidence,
1855         sp<AMessage> *meta) {
1856         ALOGV("SniffFFMPEG");
1857
1858         *meta = new AMessage;
1859         *confidence = 0.08f;  // be the last resort, by default
1860
1861         const char *container = BetterSniffFFMPEG(source, confidence, *meta);
1862         if (!container) {
1863                 ALOGW("sniff through BetterSniffFFMPEG failed, try LegacySniffFFMPEG");
1864                 container = LegacySniffFFMPEG(source, confidence, *meta);
1865                 if (container) {
1866                         ALOGI("sniff through LegacySniffFFMPEG success");
1867                 }
1868         } else {
1869                 ALOGI("sniff through BetterSniffFFMPEG success");
1870         }
1871
1872         if (container == NULL) {
1873                 ALOGD("SniffFFMPEG failed to sniff this source");
1874                 (*meta)->clear();
1875                 *meta = NULL;
1876                 return false;
1877         }
1878
1879         ALOGD("ffmpeg detected media content as '%s' with confidence %.2f",
1880                         container, *confidence);
1881
1882         /* use MPEG4Extractor(not extended extractor) for HTTP source only */
1883         if (!strcasecmp(container, MEDIA_MIMETYPE_CONTAINER_MPEG4)
1884                         && (source->flags() & DataSource::kIsCachingDataSource)) {
1885                 ALOGI("support container: %s, but it is caching data source, "
1886                                 "Don't use ffmpegextractor", container);
1887                 (*meta)->clear();
1888                 *meta = NULL;
1889                 return false;
1890         }
1891
1892         mimeType->setTo(container);
1893
1894         (*meta)->setString("extended-extractor", "extended-extractor");
1895         (*meta)->setString("extended-extractor-subtype", "ffmpegextractor");
1896         (*meta)->setString("extended-extractor-mime", container);
1897
1898         //debug only
1899         char value[PROPERTY_VALUE_MAX];
1900         property_get("sys.media.parser.ffmpeg", value, "0");
1901         if (atoi(value)) {
1902                 ALOGI("[debug] use ffmpeg parser");
1903                 *confidence = 0.88f;
1904         }
1905
1906         if (*confidence > 0.08f) {
1907                 (*meta)->setString("extended-extractor-use", "ffmpegextractor");
1908         }
1909
1910         return true;
1911 }
1912
1913 MediaExtractor *CreateFFmpegExtractor(const sp<DataSource> &source, const char *mime, const sp<AMessage> &meta) {
1914     MediaExtractor *ret = NULL;
1915     AString notuse;
1916     if (meta.get() && meta->findString("extended-extractor", &notuse) && (
1917             !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)          ||
1918             !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)           ||
1919             !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)        ||
1920             !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)          ||
1921             !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)           ||
1922             !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_APE)           ||
1923             !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_DTS)           ||
1924             !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II) ||
1925             !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RA)            ||
1926             !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_WMA)           ||
1927             !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FFMPEG)        ||
1928             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)     ||
1929             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MOV)       ||
1930             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)  ||
1931             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_TS)        ||
1932             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)   ||
1933             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_AVI)       ||
1934             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_ASF)       ||
1935             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WEBM)      ||
1936             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WMV)       ||
1937             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPG)       ||
1938             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_FLV)       ||
1939             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_DIVX)      ||
1940             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_RM)        ||
1941             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)       ||
1942             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_FLAC)      ||
1943             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_APE)       ||
1944             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_DTS)       ||
1945             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MP2)       ||
1946             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_RA)        ||
1947             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)       ||
1948             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_VC1)       ||
1949             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_HEVC)      ||
1950             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WMA)       ||
1951             !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_FFMPEG))) {
1952         ret = new FFmpegExtractor(source, meta);
1953     }
1954
1955     ALOGD("%ssupported mime: %s", (ret ? "" : "un"), mime);
1956     return ret;
1957 }
1958
1959 }  // namespace android
1960
1961 extern "C" void getExtractorPlugin(android::MediaExtractor::Plugin *plugin)
1962 {
1963     plugin->sniff = android::SniffFFMPEG;
1964     plugin->create = android::CreateFFmpegExtractor;
1965 }