summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/StagefrightMetadataRetriever.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/StagefrightMetadataRetriever.cpp')
-rw-r--r--media/libstagefright/StagefrightMetadataRetriever.cpp55
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");
+ }
}
}
}