diff options
Diffstat (limited to 'media/libstagefright/StagefrightMetadataRetriever.cpp')
-rw-r--r-- | media/libstagefright/StagefrightMetadataRetriever.cpp | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp index e37e909..d39f34b 100644 --- a/media/libstagefright/StagefrightMetadataRetriever.cpp +++ b/media/libstagefright/StagefrightMetadataRetriever.cpp @@ -23,10 +23,13 @@ #include <gui/Surface.h> #include "include/StagefrightMetadataRetriever.h" +#include "include/HTTPBase.h" #include <media/ICrypto.h> #include <media/IMediaHTTPService.h> +#include <media/stagefright/FFMPEGSoftCodec.h> + #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> @@ -44,6 +47,8 @@ #include <CharacterEncodingDetector.h> +#include <stagefright/AVExtensions.h> + namespace android { static const int64_t kBufferTimeOutUs = 30000ll; // 30 msec @@ -62,6 +67,12 @@ StagefrightMetadataRetriever::~StagefrightMetadataRetriever() { ALOGV("~StagefrightMetadataRetriever()"); clearMetadata(); mClient.disconnect(); + + if (mSource != NULL && + (mSource->flags() & DataSource::kIsHTTPBasedSource)) { + mExtractor.clear(); + static_cast<HTTPBase *>(mSource.get())->disconnect(); + } } status_t StagefrightMetadataRetriever::setDataSource( @@ -97,6 +108,7 @@ status_t StagefrightMetadataRetriever::setDataSource( fd = dup(fd); ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length); + AVUtils::get()->printFileName(fd); clearMetadata(); mSource = new FileSource(fd, offset, length); @@ -154,6 +166,8 @@ static VideoFrame *extractVideoFrame( // TODO: Use Flexible color instead videoFormat->setInt32("color-format", OMX_COLOR_FormatYUV420Planar); + videoFormat->setInt32("thumbnail-mode", 1); + status_t err; sp<ALooper> looper = new ALooper; looper->start(); @@ -214,6 +228,7 @@ static VideoFrame *extractVideoFrame( err = decoder->getInputBuffers(&inputBuffers); if (err != OK) { ALOGW("failed to get input buffers: %d (%s)", err, asString(err)); + source->stop(); decoder->release(); return NULL; } @@ -222,6 +237,7 @@ static VideoFrame *extractVideoFrame( err = decoder->getOutputBuffers(&outputBuffers); if (err != OK) { ALOGW("failed to get output buffers: %d (%s)", err, asString(err)); + source->stop(); decoder->release(); return NULL; } @@ -257,6 +273,9 @@ static VideoFrame *extractVideoFrame( if (err != OK) { ALOGW("Input Error or EOS"); haveMoreInputs = false; + //correct the status to continue to get output from decoder + err = OK; + inputIndex = -1; break; } @@ -346,9 +365,11 @@ static VideoFrame *extractVideoFrame( } } - int32_t width, height; + int32_t width, height, stride, slice_height; CHECK(outputFormat->findInt32("width", &width)); CHECK(outputFormat->findInt32("height", &height)); + CHECK(outputFormat->findInt32("stride", &stride)); + CHECK(outputFormat->findInt32("slice-height", &slice_height)); int32_t crop_left, crop_top, crop_right, crop_bottom; if (!outputFormat->findRect("crop", &crop_left, &crop_top, &crop_right, &crop_bottom)) { @@ -386,7 +407,7 @@ static VideoFrame *extractVideoFrame( if (converter.isValid()) { err = converter.convert( (const uint8_t *)videoFrameBuffer->data(), - width, height, + stride, slice_height, crop_left, crop_top, crop_right, crop_bottom, frame->mData, frame->mWidth, @@ -442,6 +463,10 @@ VideoFrame *StagefrightMetadataRetriever::getFrameAtTime( for (i = 0; i < n; ++i) { sp<MetaData> meta = mExtractor->getTrackMetaData(i); + if (meta == NULL) { + continue; + } + const char *mime; CHECK(meta->findCString(kKeyMIMEType, &mime)); @@ -481,11 +506,19 @@ VideoFrame *StagefrightMetadataRetriever::getFrameAtTime( mime, false, /* encoder */ NULL, /* matchComponentName */ - OMXCodec::kPreferSoftwareCodecs, + 0 /* OMXCodec::kPreferSoftwareCodecs */, &matchingCodecs); for (size_t i = 0; i < matchingCodecs.size(); ++i) { const char *componentName = matchingCodecs[i].mName.string(); + const char *ffmpegComponentName; + /* determine whether ffmpeg should override a broken h/w codec */ + ffmpegComponentName = FFMPEGSoftCodec::overrideComponentName(0, trackMeta, mime, false); + if (ffmpegComponentName) { + ALOGV("override compoent %s to %s for video frame extraction.", componentName, ffmpegComponentName); + componentName = ffmpegComponentName; + } + VideoFrame *frame = extractVideoFrame(componentName, trackMeta, source, timeUs, option); @@ -612,6 +645,10 @@ void StagefrightMetadataRetriever::parseMetaData() { size_t numTracks = mExtractor->countTracks(); + if (numTracks == 0) { //If no tracks available, corrupt or not valid stream + return; + } + char tmp[32]; sprintf(tmp, "%zu", numTracks); @@ -635,6 +672,9 @@ void StagefrightMetadataRetriever::parseMetaData() { String8 timedTextLang; for (size_t i = 0; i < numTracks; ++i) { sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i); + if (trackMeta == NULL) { + continue; + } int64_t durationUs; if (trackMeta->findInt64(kKeyDuration, &durationUs)) { @@ -661,9 +701,12 @@ void StagefrightMetadataRetriever::parseMetaData() { } } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) { const char *lang; - trackMeta->findCString(kKeyMediaLanguage, &lang); - timedTextLang.append(String8(lang)); - timedTextLang.append(String8(":")); + if (trackMeta->findCString(kKeyMediaLanguage, &lang)) { + timedTextLang.append(String8(lang)); + timedTextLang.append(String8(":")); + } else { + ALOGE("No language found for timed text"); + } } } } |