am c06307cc: Merge change 24583 into eclair
Merge commit 'c06307ccde2cc8e92fcb07d29ef5a69803d0c0b3' into eclair-plus-aosp * commit 'c06307ccde2cc8e92fcb07d29ef5a69803d0c0b3': Media MIME types now have corresponding constants in MediaDefs.h, new codec enumeration API.
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include <media/stagefright/DataSource.h>
|
||||
#include <media/stagefright/MediaBufferGroup.h>
|
||||
#include <media/stagefright/MediaDebug.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MediaErrors.h>
|
||||
#include <media/stagefright/MetaData.h>
|
||||
|
||||
@@ -99,7 +100,7 @@ status_t JPEGSource::stop() {
|
||||
|
||||
sp<MetaData> JPEGSource::getFormat() {
|
||||
sp<MetaData> meta = new MetaData;
|
||||
meta->setCString(kKeyMIMEType, "image/jpeg");
|
||||
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_IMAGE_JPEG);
|
||||
meta->setInt32(kKeyWidth, mWidth);
|
||||
meta->setInt32(kKeyHeight, mHeight);
|
||||
meta->setInt32(kKeyMaxInputSize, mSize);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <media/stagefright/MediaBufferGroup.h>
|
||||
#include <media/stagefright/MediaDebug.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MetaData.h>
|
||||
|
||||
namespace android {
|
||||
@@ -48,7 +49,7 @@ status_t SineSource::stop() {
|
||||
|
||||
sp<MetaData> SineSource::getFormat() {
|
||||
sp<MetaData> meta = new MetaData;
|
||||
meta->setCString(kKeyMIMEType, "audio/raw");
|
||||
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
|
||||
meta->setInt32(kKeyChannelCount, mNumChannels);
|
||||
meta->setInt32(kKeySampleRate, mSampleRate);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <media/stagefright/CameraSource.h>
|
||||
#include <media/stagefright/MediaBufferGroup.h>
|
||||
#include <media/stagefright/MediaDebug.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MetaData.h>
|
||||
#include <media/stagefright/MPEG4Extractor.h>
|
||||
#include <media/stagefright/MPEG4Writer.h>
|
||||
@@ -45,7 +46,7 @@ public:
|
||||
sp<MetaData> meta = new MetaData;
|
||||
meta->setInt32(kKeyWidth, mWidth);
|
||||
meta->setInt32(kKeyHeight, mHeight);
|
||||
meta->setCString(kKeyMIMEType, "video/raw");
|
||||
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
|
||||
|
||||
return meta;
|
||||
}
|
||||
@@ -149,8 +150,8 @@ int main(int argc, char **argv) {
|
||||
#endif
|
||||
|
||||
sp<MetaData> enc_meta = new MetaData;
|
||||
// enc_meta->setCString(kKeyMIMEType, "video/3gpp");
|
||||
enc_meta->setCString(kKeyMIMEType, "video/mp4v-es");
|
||||
// enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
|
||||
enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
|
||||
enc_meta->setInt32(kKeyWidth, width);
|
||||
enc_meta->setInt32(kKeyHeight, height);
|
||||
|
||||
@@ -228,7 +229,8 @@ int main(int argc, char **argv) {
|
||||
#endif
|
||||
|
||||
sp<MetaData> encMeta = new MetaData;
|
||||
encMeta->setCString(kKeyMIMEType, 1 ? "audio/amr-wb" : "audio/mp4a-latm");
|
||||
encMeta->setCString(kKeyMIMEType,
|
||||
1 ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AAC);
|
||||
encMeta->setInt32(kKeySampleRate, kSampleRate);
|
||||
encMeta->setInt32(kKeyChannelCount, kNumChannels);
|
||||
encMeta->setInt32(kKeyMaxInputSize, 8192);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <media/stagefright/CachingDataSource.h>
|
||||
#include <media/stagefright/HTTPDataSource.h>
|
||||
#include <media/stagefright/MediaDebug.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MediaPlayerImpl.h>
|
||||
#include <media/stagefright/MediaExtractor.h>
|
||||
#include <media/stagefright/MediaSource.h>
|
||||
@@ -126,6 +127,7 @@ static void usage(const char *me) {
|
||||
fprintf(stderr, " -l(ist) components\n");
|
||||
fprintf(stderr, " -m max-number-of-frames-to-decode in each pass\n");
|
||||
fprintf(stderr, " -b bug to reproduce\n");
|
||||
fprintf(stderr, " -p(rofiles) dump decoder profiles supported\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
@@ -133,12 +135,13 @@ int main(int argc, char **argv) {
|
||||
|
||||
bool audioOnly = false;
|
||||
bool listComponents = false;
|
||||
bool dumpProfiles = false;
|
||||
gNumRepetitions = 1;
|
||||
gMaxNumFrames = 0;
|
||||
gReproduceBug = -1;
|
||||
|
||||
int res;
|
||||
while ((res = getopt(argc, argv, "han:lm:b:")) >= 0) {
|
||||
while ((res = getopt(argc, argv, "han:lm:b:p")) >= 0) {
|
||||
switch (res) {
|
||||
case 'a':
|
||||
{
|
||||
@@ -174,6 +177,12 @@ int main(int argc, char **argv) {
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p':
|
||||
{
|
||||
dumpProfiles = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case '?':
|
||||
case 'h':
|
||||
default:
|
||||
@@ -188,6 +197,53 @@ int main(int argc, char **argv) {
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (dumpProfiles) {
|
||||
sp<IServiceManager> sm = defaultServiceManager();
|
||||
sp<IBinder> binder = sm->getService(String16("media.player"));
|
||||
sp<IMediaPlayerService> service =
|
||||
interface_cast<IMediaPlayerService>(binder);
|
||||
|
||||
CHECK(service.get() != NULL);
|
||||
|
||||
sp<IOMX> omx = service->createOMX();
|
||||
CHECK(omx.get() != NULL);
|
||||
|
||||
const char *kMimeTypes[] = {
|
||||
MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4,
|
||||
MEDIA_MIMETYPE_VIDEO_H263
|
||||
};
|
||||
|
||||
for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]);
|
||||
++k) {
|
||||
printf("type '%s':\n", kMimeTypes[k]);
|
||||
|
||||
Vector<CodecCapabilities> results;
|
||||
CHECK_EQ(QueryCodecs(omx, kMimeTypes[k],
|
||||
true, // queryDecoders
|
||||
&results), OK);
|
||||
|
||||
for (size_t i = 0; i < results.size(); ++i) {
|
||||
printf(" decoder '%s' supports ",
|
||||
results[i].mComponentName.string());
|
||||
|
||||
if (results[i].mProfileLevels.size() == 0) {
|
||||
printf("NOTHING.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) {
|
||||
const CodecProfileLevel &profileLevel =
|
||||
results[i].mProfileLevels[j];
|
||||
|
||||
printf("%s%ld/%ld", j > 0 ? ", " : "",
|
||||
profileLevel.mProfile, profileLevel.mLevel);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (listComponents) {
|
||||
sp<IServiceManager> sm = defaultServiceManager();
|
||||
sp<IBinder> binder = sm->getService(String16("media.player"));
|
||||
|
||||
40
include/media/stagefright/MediaDefs.h
Normal file
40
include/media/stagefright/MediaDefs.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MEDIA_DEFS_H_
|
||||
|
||||
#define MEDIA_DEFS_H_
|
||||
|
||||
namespace android {
|
||||
|
||||
extern const char *MEDIA_MIMETYPE_IMAGE_JPEG;
|
||||
|
||||
extern const char *MEDIA_MIMETYPE_VIDEO_AVC;
|
||||
extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4;
|
||||
extern const char *MEDIA_MIMETYPE_VIDEO_H263;
|
||||
extern const char *MEDIA_MIMETYPE_VIDEO_RAW;
|
||||
|
||||
extern const char *MEDIA_MIMETYPE_AUDIO_AMR_NB;
|
||||
extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB;
|
||||
extern const char *MEDIA_MIMETYPE_AUDIO_MPEG;
|
||||
extern const char *MEDIA_MIMETYPE_AUDIO_AAC;
|
||||
extern const char *MEDIA_MIMETYPE_AUDIO_RAW;
|
||||
|
||||
extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // MEDIA_DEFS_H_
|
||||
@@ -33,7 +33,12 @@ struct OMXCodec : public MediaSource,
|
||||
static sp<OMXCodec> Create(
|
||||
const sp<IOMX> &omx,
|
||||
const sp<MetaData> &meta, bool createEncoder,
|
||||
const sp<MediaSource> &source);
|
||||
const sp<MediaSource> &source,
|
||||
const char *matchComponentName = NULL);
|
||||
|
||||
static void setComponentRole(
|
||||
const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
|
||||
const char *mime);
|
||||
|
||||
virtual status_t start(MetaData *params = NULL);
|
||||
virtual status_t stop();
|
||||
@@ -206,6 +211,32 @@ private:
|
||||
OMXCodec &operator=(const OMXCodec &);
|
||||
};
|
||||
|
||||
struct CodecProfileLevel {
|
||||
OMX_U32 mProfile;
|
||||
OMX_U32 mLevel;
|
||||
};
|
||||
|
||||
struct CodecCapabilities {
|
||||
String8 mComponentName;
|
||||
Vector<CodecProfileLevel> mProfileLevels;
|
||||
};
|
||||
|
||||
// Return a vector of componentNames with supported profile/level pairs
|
||||
// supporting the given mime type, if queryDecoders==true, returns components
|
||||
// that decode content of the given type, otherwise returns components
|
||||
// that encode content of the given type.
|
||||
// profile and level indications only make sense for h.263, mpeg4 and avc
|
||||
// video.
|
||||
// The profile/level values correspond to
|
||||
// OMX_VIDEO_H263PROFILETYPE, OMX_VIDEO_MPEG4PROFILETYPE,
|
||||
// OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263LEVELTYPE, OMX_VIDEO_MPEG4LEVELTYPE
|
||||
// and OMX_VIDEO_AVCLEVELTYPE respectively.
|
||||
|
||||
status_t QueryCodecs(
|
||||
const sp<IOMX> &omx,
|
||||
const char *mimeType, bool queryDecoders,
|
||||
Vector<CodecCapabilities> *results);
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // OMX_CODEC_H_
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <media/stagefright/DataSource.h>
|
||||
#include <media/stagefright/MediaBufferGroup.h>
|
||||
#include <media/stagefright/MediaDebug.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MediaErrors.h>
|
||||
#include <media/stagefright/MediaSource.h>
|
||||
#include <media/stagefright/MetaData.h>
|
||||
@@ -66,7 +67,7 @@ AMRExtractor::AMRExtractor(const sp<DataSource> &source)
|
||||
float confidence;
|
||||
if (SniffAMR(mDataSource, &mimeType, &confidence)) {
|
||||
mInitCheck = OK;
|
||||
mIsWide = (mimeType == "audio/amr-wb");
|
||||
mIsWide = (mimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +97,10 @@ sp<MetaData> AMRExtractor::getTrackMetaData(size_t index) {
|
||||
// static
|
||||
sp<MetaData> AMRExtractor::makeAMRFormat(bool isWide) {
|
||||
sp<MetaData> meta = new MetaData;
|
||||
meta->setCString(kKeyMIMEType, isWide ? "audio/amr-wb" : "audio/3gpp");
|
||||
meta->setCString(
|
||||
kKeyMIMEType, isWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB
|
||||
: MEDIA_MIMETYPE_AUDIO_AMR_NB);
|
||||
|
||||
meta->setInt32(kKeyChannelCount, 1);
|
||||
meta->setInt32(kKeySampleRate, isWide ? 16000 : 8000);
|
||||
|
||||
@@ -221,12 +225,12 @@ bool SniffAMR(
|
||||
}
|
||||
|
||||
if (!memcmp(header, "#!AMR\n", 6)) {
|
||||
*mimeType = "audio/3gpp";
|
||||
*mimeType = MEDIA_MIMETYPE_AUDIO_AMR_NB;
|
||||
*confidence = 0.5;
|
||||
|
||||
return true;
|
||||
} else if (!memcmp(header, "#!AMR-WB\n", 9)) {
|
||||
*mimeType = "audio/amr-wb";
|
||||
*mimeType = MEDIA_MIMETYPE_AUDIO_AMR_WB;
|
||||
*confidence = 0.5;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -13,6 +13,7 @@ LOCAL_SRC_FILES:= \
|
||||
MPEG4Writer.cpp \
|
||||
MediaBuffer.cpp \
|
||||
MediaBufferGroup.cpp \
|
||||
MediaDefs.cpp \
|
||||
MediaExtractor.cpp \
|
||||
MediaPlayerImpl.cpp \
|
||||
MediaSource.cpp \
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <media/AudioTrack.h>
|
||||
#include <media/stagefright/AudioPlayer.h>
|
||||
#include <media/stagefright/MediaDebug.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MediaSource.h>
|
||||
#include <media/stagefright/MetaData.h>
|
||||
|
||||
@@ -61,7 +62,7 @@ void AudioPlayer::start() {
|
||||
const char *mime;
|
||||
bool success = format->findCString(kKeyMIMEType, &mime);
|
||||
CHECK(success);
|
||||
CHECK(!strcasecmp(mime, "audio/raw"));
|
||||
CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
|
||||
|
||||
success = format->findInt32(kKeySampleRate, &mSampleRate);
|
||||
CHECK(success);
|
||||
|
||||
@@ -155,7 +155,7 @@ status_t CameraSource::stop() {
|
||||
|
||||
sp<MetaData> CameraSource::getFormat() {
|
||||
sp<MetaData> meta = new MetaData;
|
||||
meta->setCString(kKeyMIMEType, "video/raw");
|
||||
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
|
||||
meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420SemiPlanar);
|
||||
meta->setInt32(kKeyWidth, 480);
|
||||
meta->setInt32(kKeyHeight, 320);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <media/stagefright/MediaBuffer.h>
|
||||
#include <media/stagefright/MediaBufferGroup.h>
|
||||
#include <media/stagefright/MediaDebug.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MediaErrors.h>
|
||||
#include <media/stagefright/MediaSource.h>
|
||||
#include <media/stagefright/MetaData.h>
|
||||
@@ -330,7 +331,7 @@ MP3Extractor::MP3Extractor(const sp<DataSource> &source)
|
||||
|
||||
mMeta = new MetaData;
|
||||
|
||||
mMeta->setCString(kKeyMIMEType, "audio/mpeg");
|
||||
mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
|
||||
mMeta->setInt32(kKeySampleRate, sample_rate);
|
||||
mMeta->setInt32(kKeyBitRate, bitrate);
|
||||
mMeta->setInt32(kKeyChannelCount, num_channels);
|
||||
@@ -510,7 +511,7 @@ bool SniffMP3(
|
||||
return false;
|
||||
}
|
||||
|
||||
*mimeType = "audio/mpeg";
|
||||
*mimeType = MEDIA_MIMETYPE_AUDIO_MPEG;
|
||||
*confidence = 0.3f;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <media/stagefright/MediaBuffer.h>
|
||||
#include <media/stagefright/MediaBufferGroup.h>
|
||||
#include <media/stagefright/MediaDebug.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MediaSource.h>
|
||||
#include <media/stagefright/MetaData.h>
|
||||
#include <media/stagefright/SampleTable.h>
|
||||
@@ -116,25 +117,25 @@ static void hexdump(const void *_data, size_t size) {
|
||||
}
|
||||
}
|
||||
|
||||
static const char *const FourCC2MIME(uint32_t fourcc) {
|
||||
static const char *FourCC2MIME(uint32_t fourcc) {
|
||||
switch (fourcc) {
|
||||
case FOURCC('m', 'p', '4', 'a'):
|
||||
return "audio/mp4a-latm";
|
||||
return MEDIA_MIMETYPE_AUDIO_AAC;
|
||||
|
||||
case FOURCC('s', 'a', 'm', 'r'):
|
||||
return "audio/3gpp";
|
||||
return MEDIA_MIMETYPE_AUDIO_AMR_NB;
|
||||
|
||||
case FOURCC('s', 'a', 'w', 'b'):
|
||||
return "audio/amr-wb";
|
||||
return MEDIA_MIMETYPE_AUDIO_AMR_WB;
|
||||
|
||||
case FOURCC('m', 'p', '4', 'v'):
|
||||
return "video/mp4v-es";
|
||||
return MEDIA_MIMETYPE_VIDEO_MPEG4;
|
||||
|
||||
case FOURCC('s', '2', '6', '3'):
|
||||
return "video/3gpp";
|
||||
return MEDIA_MIMETYPE_VIDEO_H263;
|
||||
|
||||
case FOURCC('a', 'v', 'c', '1'):
|
||||
return "video/avc";
|
||||
return MEDIA_MIMETYPE_VIDEO_AVC;
|
||||
|
||||
default:
|
||||
CHECK(!"should not be here.");
|
||||
@@ -499,8 +500,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
|
||||
uint16_t data_ref_index = U16_AT(&buffer[6]);
|
||||
uint16_t num_channels = U16_AT(&buffer[16]);
|
||||
|
||||
if (!strcasecmp("audio/3gpp", FourCC2MIME(chunk_type))
|
||||
|| !strcasecmp("audio/amr-wb", FourCC2MIME(chunk_type))) {
|
||||
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
|
||||
FourCC2MIME(chunk_type))
|
||||
|| !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
|
||||
FourCC2MIME(chunk_type))) {
|
||||
// AMR audio is always mono.
|
||||
num_channels = 1;
|
||||
}
|
||||
@@ -746,7 +749,7 @@ MPEG4Source::MPEG4Source(
|
||||
success = mFormat->findInt32(kKeyTimeScale, &mTimescale);
|
||||
CHECK(success);
|
||||
|
||||
mIsAVC = !strcasecmp(mime, "video/avc");
|
||||
mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
|
||||
}
|
||||
|
||||
MPEG4Source::~MPEG4Source() {
|
||||
@@ -978,7 +981,7 @@ bool SniffMPEG4(
|
||||
|
||||
if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
|
||||
|| !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)) {
|
||||
*mimeType = "video/mp4";
|
||||
*mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
|
||||
*confidence = 0.1;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <media/stagefright/MediaBuffer.h>
|
||||
#include <media/stagefright/MetaData.h>
|
||||
#include <media/stagefright/MediaDebug.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MediaSource.h>
|
||||
#include <media/stagefright/Utils.h>
|
||||
|
||||
@@ -351,7 +352,7 @@ void MPEG4Writer::Track::threadEntry() {
|
||||
sp<MetaData> meta = mSource->getFormat();
|
||||
const char *mime;
|
||||
meta->findCString(kKeyMIMEType, &mime);
|
||||
is_mpeg4 = !strcasecmp(mime, "video/mp4v-es");
|
||||
is_mpeg4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4);
|
||||
|
||||
MediaBuffer *buffer;
|
||||
while (!mDone && mSource->read(&buffer) == OK) {
|
||||
@@ -528,9 +529,9 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) {
|
||||
mOwner->writeInt32(1); // entry count
|
||||
if (is_audio) {
|
||||
const char *fourcc = NULL;
|
||||
if (!strcasecmp("audio/3gpp", mime)) {
|
||||
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
|
||||
fourcc = "samr";
|
||||
} else if (!strcasecmp("audio/amr-wb", mime)) {
|
||||
} else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
|
||||
fourcc = "sawb";
|
||||
} else {
|
||||
LOGE("Unknown mime type '%s'.", mime);
|
||||
@@ -555,9 +556,9 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) {
|
||||
mOwner->writeInt32(samplerate << 16);
|
||||
mOwner->endBox();
|
||||
} else {
|
||||
if (!strcasecmp("video/mp4v-es", mime)) {
|
||||
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
|
||||
mOwner->beginBox("mp4v");
|
||||
} else if (!strcasecmp("video/3gpp", mime)) {
|
||||
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
|
||||
mOwner->beginBox("s263");
|
||||
} else {
|
||||
LOGE("Unknown mime type '%s'.", mime);
|
||||
@@ -590,7 +591,7 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) {
|
||||
|
||||
CHECK(23 + mCodecSpecificDataSize < 128);
|
||||
|
||||
if (!strcasecmp("video/mp4v-es", mime)) {
|
||||
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
|
||||
mOwner->beginBox("esds");
|
||||
|
||||
mOwner->writeInt32(0); // version=0, flags=0
|
||||
@@ -625,7 +626,7 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) {
|
||||
mOwner->write(kData2, sizeof(kData2));
|
||||
|
||||
mOwner->endBox(); // esds
|
||||
} else if (!strcasecmp("video/3gpp", mime)) {
|
||||
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
|
||||
mOwner->beginBox("d263");
|
||||
|
||||
mOwner->writeInt32(0); // vendor
|
||||
|
||||
36
media/libstagefright/MediaDefs.cpp
Normal file
36
media/libstagefright/MediaDefs.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
const char *MEDIA_MIMETYPE_IMAGE_JPEG = "image/jpeg";
|
||||
|
||||
const char *MEDIA_MIMETYPE_VIDEO_AVC = "video/avc";
|
||||
const char *MEDIA_MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
|
||||
const char *MEDIA_MIMETYPE_VIDEO_H263 = "video/3gpp";
|
||||
const char *MEDIA_MIMETYPE_VIDEO_RAW = "video/raw";
|
||||
|
||||
const char *MEDIA_MIMETYPE_AUDIO_AMR_NB = "audio/3gpp";
|
||||
const char *MEDIA_MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb";
|
||||
const char *MEDIA_MIMETYPE_AUDIO_MPEG = "audio/mpeg";
|
||||
const char *MEDIA_MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
|
||||
const char *MEDIA_MIMETYPE_AUDIO_RAW = "audio/raw";
|
||||
|
||||
const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mpeg4";
|
||||
|
||||
} // namespace android
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <media/stagefright/AMRExtractor.h>
|
||||
#include <media/stagefright/DataSource.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MP3Extractor.h>
|
||||
#include <media/stagefright/MPEG4Extractor.h>
|
||||
#include <media/stagefright/MediaExtractor.h>
|
||||
@@ -44,12 +45,13 @@ sp<MediaExtractor> MediaExtractor::Create(
|
||||
mime, confidence);
|
||||
}
|
||||
|
||||
if (!strcasecmp(mime, "video/mp4") || !strcasecmp(mime, "audio/mp4")) {
|
||||
if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
|
||||
|| !strcasecmp(mime, "audio/mp4")) {
|
||||
return new MPEG4Extractor(source);
|
||||
} else if (!strcasecmp(mime, "audio/mpeg")) {
|
||||
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
|
||||
return new MP3Extractor(source);
|
||||
} else if (!strcasecmp(mime, "audio/3gpp")
|
||||
|| !strcasecmp(mime, "audio/amr-wb")) {
|
||||
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)
|
||||
|| !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
|
||||
return new AMRExtractor(source);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <media/stagefright/MediaBuffer.h>
|
||||
#include <media/stagefright/MediaBufferGroup.h>
|
||||
#include <media/stagefright/MediaDebug.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MediaExtractor.h>
|
||||
#include <media/stagefright/MetaData.h>
|
||||
#include <media/stagefright/MmapSource.h>
|
||||
@@ -44,40 +45,40 @@ struct CodecInfo {
|
||||
};
|
||||
|
||||
static const CodecInfo kDecoderInfo[] = {
|
||||
{ "image/jpeg", "OMX.TI.JPEG.decode" },
|
||||
{ "audio/mpeg", "OMX.TI.MP3.decode" },
|
||||
{ "audio/mpeg", "OMX.PV.mp3dec" },
|
||||
{ "audio/3gpp", "OMX.TI.AMR.decode" },
|
||||
{ "audio/3gpp", "OMX.PV.amrdec" },
|
||||
{ "audio/amr-wb", "OMX.TI.WBAMR.decode" },
|
||||
{ "audio/amr-wb", "OMX.PV.amrdec" },
|
||||
{ "audio/mp4a-latm", "OMX.TI.AAC.decode" },
|
||||
{ "audio/mp4a-latm", "OMX.PV.aacdec" },
|
||||
{ "video/mp4v-es", "OMX.qcom.video.decoder.mpeg4" },
|
||||
{ "video/mp4v-es", "OMX.TI.Video.Decoder" },
|
||||
{ "video/mp4v-es", "OMX.PV.mpeg4dec" },
|
||||
{ "video/3gpp", "OMX.qcom.video.decoder.h263" },
|
||||
{ "video/3gpp", "OMX.TI.Video.Decoder" },
|
||||
{ "video/3gpp", "OMX.PV.h263dec" },
|
||||
{ "video/avc", "OMX.qcom.video.decoder.avc" },
|
||||
{ "video/avc", "OMX.TI.Video.Decoder" },
|
||||
{ "video/avc", "OMX.PV.avcdec" },
|
||||
{ MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.Decoder" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
|
||||
};
|
||||
|
||||
static const CodecInfo kEncoderInfo[] = {
|
||||
{ "audio/3gpp", "OMX.TI.AMR.encode" },
|
||||
{ "audio/3gpp", "OMX.PV.amrencnb" },
|
||||
{ "audio/amr-wb", "OMX.TI.WBAMR.encode" },
|
||||
{ "audio/mp4a-latm", "OMX.TI.AAC.encode" },
|
||||
{ "audio/mp4a-latm", "OMX.PV.aacenc" },
|
||||
{ "video/mp4v-es", "OMX.qcom.video.encoder.mpeg4" },
|
||||
{ "video/mp4v-es", "OMX.TI.Video.encoder" },
|
||||
{ "video/mp4v-es", "OMX.PV.mpeg4enc" },
|
||||
{ "video/3gpp", "OMX.qcom.video.encoder.h263" },
|
||||
{ "video/3gpp", "OMX.TI.Video.encoder" },
|
||||
{ "video/3gpp", "OMX.PV.h263enc" },
|
||||
{ "video/avc", "OMX.TI.Video.encoder" },
|
||||
{ "video/avc", "OMX.PV.avcenc" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrencnb" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" },
|
||||
};
|
||||
|
||||
#define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
|
||||
@@ -169,7 +170,8 @@ static void InitOMXParams(T *params) {
|
||||
sp<OMXCodec> OMXCodec::Create(
|
||||
const sp<IOMX> &omx,
|
||||
const sp<MetaData> &meta, bool createEncoder,
|
||||
const sp<MediaSource> &source) {
|
||||
const sp<MediaSource> &source,
|
||||
const char *matchComponentName) {
|
||||
const char *mime;
|
||||
bool success = meta->findCString(kKeyMIMEType, &mime);
|
||||
CHECK(success);
|
||||
@@ -191,6 +193,11 @@ sp<OMXCodec> OMXCodec::Create(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// If a specific codec is requested, skip the non-matching ones.
|
||||
if (matchComponentName && strcmp(componentName, matchComponentName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LOGV("Attempting to allocate OMX node '%s'", componentName);
|
||||
|
||||
status_t err = omx->allocate_node(componentName, &node);
|
||||
@@ -318,13 +325,13 @@ sp<OMXCodec> OMXCodec::Create(
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcasecmp("audio/3gpp", mime)) {
|
||||
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
|
||||
codec->setAMRFormat();
|
||||
}
|
||||
if (!strcasecmp("audio/amr-wb", mime)) {
|
||||
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
|
||||
codec->setAMRWBFormat();
|
||||
}
|
||||
if (!strcasecmp("audio/mp4a-latm", mime)) {
|
||||
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
|
||||
int32_t numChannels, sampleRate;
|
||||
CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
|
||||
CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
|
||||
@@ -343,7 +350,7 @@ sp<OMXCodec> OMXCodec::Create(
|
||||
codec->setVideoOutputFormat(mime, width, height);
|
||||
}
|
||||
}
|
||||
if (!strcasecmp(mime, "image/jpeg")
|
||||
if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_JPEG)
|
||||
&& !strcmp(componentName, "OMX.TI.JPEG.decode")) {
|
||||
OMX_COLOR_FORMATTYPE format =
|
||||
OMX_COLOR_Format32bitARGB8888;
|
||||
@@ -471,11 +478,11 @@ void OMXCodec::setVideoInputFormat(
|
||||
CODEC_LOGI("setVideoInputFormat width=%ld, height=%ld", width, height);
|
||||
|
||||
OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
|
||||
if (!strcasecmp("video/avc", mime)) {
|
||||
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
|
||||
compressionFormat = OMX_VIDEO_CodingAVC;
|
||||
} else if (!strcasecmp("video/mp4v-es", mime)) {
|
||||
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
|
||||
compressionFormat = OMX_VIDEO_CodingMPEG4;
|
||||
} else if (!strcasecmp("video/3gpp", mime)) {
|
||||
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
|
||||
compressionFormat = OMX_VIDEO_CodingH263;
|
||||
} else {
|
||||
LOGE("Not a supported video mime type: %s", mime);
|
||||
@@ -547,11 +554,11 @@ void OMXCodec::setVideoOutputFormat(
|
||||
CODEC_LOGI("setVideoOutputFormat width=%ld, height=%ld", width, height);
|
||||
|
||||
OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
|
||||
if (!strcasecmp("video/avc", mime)) {
|
||||
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
|
||||
compressionFormat = OMX_VIDEO_CodingAVC;
|
||||
} else if (!strcasecmp("video/mp4v-es", mime)) {
|
||||
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
|
||||
compressionFormat = OMX_VIDEO_CodingMPEG4;
|
||||
} else if (!strcasecmp("video/3gpp", mime)) {
|
||||
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
|
||||
compressionFormat = OMX_VIDEO_CodingH263;
|
||||
} else {
|
||||
LOGE("Not a supported video mime type: %s", mime);
|
||||
@@ -670,7 +677,10 @@ OMXCodec::OMXCodec(
|
||||
setComponentRole();
|
||||
}
|
||||
|
||||
void OMXCodec::setComponentRole() {
|
||||
// static
|
||||
void OMXCodec::setComponentRole(
|
||||
const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
|
||||
const char *mime) {
|
||||
struct MimeToRole {
|
||||
const char *mime;
|
||||
const char *decoderRole;
|
||||
@@ -678,13 +688,20 @@ void OMXCodec::setComponentRole() {
|
||||
};
|
||||
|
||||
static const MimeToRole kMimeToRole[] = {
|
||||
{ "audio/mpeg", "audio_decoder.mp3", "audio_encoder.mp3" },
|
||||
{ "audio/3gpp", "audio_decoder.amrnb", "audio_encoder.amrnb" },
|
||||
{ "audio/amr-wb", "audio_decoder.amrwb", "audio_encoder.amrwb" },
|
||||
{ "audio/mp4a-latm", "audio_decoder.aac", "audio_encoder.aac" },
|
||||
{ "video/avc", "video_decoder.avc", "video_encoder.avc" },
|
||||
{ "video/mp4v-es", "video_decoder.mpeg4", "video_encoder.mpeg4" },
|
||||
{ "video/3gpp", "video_decoder.h263", "video_encoder.h263" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_MPEG,
|
||||
"audio_decoder.mp3", "audio_encoder.mp3" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AMR_NB,
|
||||
"audio_decoder.amrnb", "audio_encoder.amrnb" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AMR_WB,
|
||||
"audio_decoder.amrwb", "audio_encoder.amrwb" },
|
||||
{ MEDIA_MIMETYPE_AUDIO_AAC,
|
||||
"audio_decoder.aac", "audio_encoder.aac" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_AVC,
|
||||
"video_decoder.avc", "video_encoder.avc" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_MPEG4,
|
||||
"video_decoder.mpeg4", "video_encoder.mpeg4" },
|
||||
{ MEDIA_MIMETYPE_VIDEO_H263,
|
||||
"video_decoder.h263", "video_encoder.h263" },
|
||||
};
|
||||
|
||||
static const size_t kNumMimeToRole =
|
||||
@@ -692,7 +709,7 @@ void OMXCodec::setComponentRole() {
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < kNumMimeToRole; ++i) {
|
||||
if (!strcasecmp(mMIME, kMimeToRole[i].mime)) {
|
||||
if (!strcasecmp(mime, kMimeToRole[i].mime)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -702,12 +719,10 @@ void OMXCodec::setComponentRole() {
|
||||
}
|
||||
|
||||
const char *role =
|
||||
mIsEncoder ? kMimeToRole[i].encoderRole
|
||||
: kMimeToRole[i].decoderRole;
|
||||
isEncoder ? kMimeToRole[i].encoderRole
|
||||
: kMimeToRole[i].decoderRole;
|
||||
|
||||
if (role != NULL) {
|
||||
CODEC_LOGV("Setting component role '%s'.", role);
|
||||
|
||||
OMX_PARAM_COMPONENTROLETYPE roleParams;
|
||||
InitOMXParams(&roleParams);
|
||||
|
||||
@@ -716,8 +731,8 @@ void OMXCodec::setComponentRole() {
|
||||
|
||||
roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
|
||||
|
||||
status_t err = mOMX->set_parameter(
|
||||
mNode, OMX_IndexParamStandardComponentRole,
|
||||
status_t err = omx->set_parameter(
|
||||
node, OMX_IndexParamStandardComponentRole,
|
||||
&roleParams, sizeof(roleParams));
|
||||
|
||||
if (err != OK) {
|
||||
@@ -726,6 +741,10 @@ void OMXCodec::setComponentRole() {
|
||||
}
|
||||
}
|
||||
|
||||
void OMXCodec::setComponentRole() {
|
||||
setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
|
||||
}
|
||||
|
||||
OMXCodec::~OMXCodec() {
|
||||
CHECK(mState == LOADED || mState == ERROR);
|
||||
|
||||
@@ -1359,7 +1378,7 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) {
|
||||
|
||||
size_t size = specific->mSize;
|
||||
|
||||
if (!strcasecmp("video/avc", mMIME)
|
||||
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME)
|
||||
&& !(mQuirks & kWantsNALFragments)) {
|
||||
static const uint8_t kNALStartCode[4] =
|
||||
{ 0x00, 0x00, 0x00, 0x01 };
|
||||
@@ -2250,7 +2269,7 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
|
||||
OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
|
||||
CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
|
||||
|
||||
mOutputFormat->setCString(kKeyMIMEType, "image/raw");
|
||||
mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
|
||||
mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
|
||||
mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
|
||||
mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
|
||||
@@ -2283,7 +2302,8 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
|
||||
"the input stream contains.");
|
||||
}
|
||||
|
||||
mOutputFormat->setCString(kKeyMIMEType, "audio/raw");
|
||||
mOutputFormat->setCString(
|
||||
kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
|
||||
|
||||
// Use the codec-advertised number of channels, as some
|
||||
// codecs appear to output stereo even if the input data is
|
||||
@@ -2306,17 +2326,20 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
|
||||
|
||||
if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
|
||||
&& amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
|
||||
mOutputFormat->setCString(kKeyMIMEType, "audio/3gpp");
|
||||
mOutputFormat->setCString(
|
||||
kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
|
||||
mOutputFormat->setInt32(kKeySampleRate, 8000);
|
||||
} else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
|
||||
&& amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
|
||||
mOutputFormat->setCString(kKeyMIMEType, "audio/amr-wb");
|
||||
mOutputFormat->setCString(
|
||||
kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
|
||||
mOutputFormat->setInt32(kKeySampleRate, 16000);
|
||||
} else {
|
||||
CHECK(!"Unknown AMR band mode.");
|
||||
}
|
||||
} else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
|
||||
mOutputFormat->setCString(kKeyMIMEType, "audio/mp4a-latm");
|
||||
mOutputFormat->setCString(
|
||||
kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
|
||||
} else {
|
||||
CHECK(!"Should not be here. Unknown audio encoding.");
|
||||
}
|
||||
@@ -2328,13 +2351,17 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
|
||||
OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
|
||||
|
||||
if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
|
||||
mOutputFormat->setCString(kKeyMIMEType, "video/raw");
|
||||
mOutputFormat->setCString(
|
||||
kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
|
||||
} else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
|
||||
mOutputFormat->setCString(kKeyMIMEType, "video/mp4v-es");
|
||||
mOutputFormat->setCString(
|
||||
kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
|
||||
} else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
|
||||
mOutputFormat->setCString(kKeyMIMEType, "video/3gpp");
|
||||
mOutputFormat->setCString(
|
||||
kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
|
||||
} else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
|
||||
mOutputFormat->setCString(kKeyMIMEType, "video/avc");
|
||||
mOutputFormat->setCString(
|
||||
kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
|
||||
} else {
|
||||
CHECK(!"Unknown compression format.");
|
||||
}
|
||||
@@ -2362,4 +2389,67 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
status_t QueryCodecs(
|
||||
const sp<IOMX> &omx,
|
||||
const char *mime, bool queryDecoders,
|
||||
Vector<CodecCapabilities> *results) {
|
||||
results->clear();
|
||||
|
||||
for (int index = 0;; ++index) {
|
||||
const char *componentName;
|
||||
|
||||
if (!queryDecoders) {
|
||||
componentName = GetCodec(
|
||||
kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
|
||||
mime, index);
|
||||
} else {
|
||||
componentName = GetCodec(
|
||||
kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
|
||||
mime, index);
|
||||
}
|
||||
|
||||
if (!componentName) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
IOMX::node_id node;
|
||||
status_t err = omx->allocate_node(componentName, &node);
|
||||
|
||||
if (err != OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OMXCodec::setComponentRole(omx, node, queryDecoders, mime);
|
||||
|
||||
results->push();
|
||||
CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
|
||||
caps->mComponentName = componentName;
|
||||
|
||||
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
|
||||
InitOMXParams(¶m);
|
||||
|
||||
param.nPortIndex = queryDecoders ? 0 : 1;
|
||||
|
||||
for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
|
||||
err = omx->get_parameter(
|
||||
node, OMX_IndexParamVideoProfileLevelQuerySupported,
|
||||
¶m, sizeof(param));
|
||||
|
||||
if (err != OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
CodecProfileLevel profileLevel;
|
||||
profileLevel.mProfile = param.eProfile;
|
||||
profileLevel.mLevel = param.eLevel;
|
||||
|
||||
caps->mProfileLevels.push(profileLevel);
|
||||
}
|
||||
|
||||
CHECK_EQ(omx->free_node(node), OK);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <media/stagefright/MediaBuffer.h>
|
||||
#include <media/stagefright/MediaBufferGroup.h>
|
||||
#include <media/stagefright/MediaDebug.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MetaData.h>
|
||||
#include <media/stagefright/ShoutcastSource.h>
|
||||
#include <media/stagefright/string.h>
|
||||
@@ -77,7 +78,7 @@ status_t ShoutcastSource::stop() {
|
||||
|
||||
sp<MetaData> ShoutcastSource::getFormat() {
|
||||
sp<MetaData> meta = new MetaData;
|
||||
meta->setCString(kKeyMIMEType, "audio/mpeg");
|
||||
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
|
||||
meta->setInt32(kKeySampleRate, 44100);
|
||||
meta->setInt32(kKeyChannelCount, 2); // XXX
|
||||
|
||||
|
||||
Reference in New Issue
Block a user