Merge commit '8ea45aad100ee25067b2e83703454c71a968ba4f' into kraken * commit '8ea45aad100ee25067b2e83703454c71a968ba4f': Support for Ogg Vorbis decoding in stagefright.
This commit is contained in:
@@ -36,6 +36,7 @@ extern const char *MEDIA_MIMETYPE_AUDIO_RAW;
|
|||||||
|
|
||||||
extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
|
extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
|
||||||
extern const char *MEDIA_MIMETYPE_CONTAINER_WAV;
|
extern const char *MEDIA_MIMETYPE_CONTAINER_WAV;
|
||||||
|
extern const char *MEDIA_MIMETYPE_CONTAINER_VORBIS;
|
||||||
|
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
|
|||||||
@@ -674,6 +674,26 @@ static player_type getDefaultPlayerType() {
|
|||||||
return PV_PLAYER;
|
return PV_PLAYER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// By default we use the VORBIS_PLAYER for vorbis playback (duh!),
|
||||||
|
// but if the magic property is set we will use our new experimental
|
||||||
|
// stagefright code instead.
|
||||||
|
static player_type OverrideStagefrightForVorbis(player_type player) {
|
||||||
|
if (player != VORBIS_PLAYER) {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BUILD_WITH_FULL_STAGEFRIGHT
|
||||||
|
char value[PROPERTY_VALUE_MAX];
|
||||||
|
if (property_get("media.stagefright.enable-vorbis", value, NULL)
|
||||||
|
&& (!strcmp(value, "1") || !strcmp(value, "true"))) {
|
||||||
|
return STAGEFRIGHT_PLAYER;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return VORBIS_PLAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
player_type getPlayerType(int fd, int64_t offset, int64_t length)
|
player_type getPlayerType(int fd, int64_t offset, int64_t length)
|
||||||
{
|
{
|
||||||
char buf[20];
|
char buf[20];
|
||||||
@@ -685,7 +705,7 @@ player_type getPlayerType(int fd, int64_t offset, int64_t length)
|
|||||||
|
|
||||||
// Ogg vorbis?
|
// Ogg vorbis?
|
||||||
if (ident == 0x5367674f) // 'OggS'
|
if (ident == 0x5367674f) // 'OggS'
|
||||||
return VORBIS_PLAYER;
|
return OverrideStagefrightForVorbis(VORBIS_PLAYER);
|
||||||
|
|
||||||
#ifndef NO_OPENCORE
|
#ifndef NO_OPENCORE
|
||||||
if (ident == 0x75b22630) {
|
if (ident == 0x75b22630) {
|
||||||
@@ -721,6 +741,13 @@ player_type getPlayerType(const char* url)
|
|||||||
return TEST_PLAYER;
|
return TEST_PLAYER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool useStagefrightForHTTP = false;
|
||||||
|
char value[PROPERTY_VALUE_MAX];
|
||||||
|
if (property_get("media.stagefright.enable-http", value, NULL)
|
||||||
|
&& (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
|
||||||
|
useStagefrightForHTTP = true;
|
||||||
|
}
|
||||||
|
|
||||||
// use MidiFile for MIDI extensions
|
// use MidiFile for MIDI extensions
|
||||||
int lenURL = strlen(url);
|
int lenURL = strlen(url);
|
||||||
for (int i = 0; i < NELEM(FILE_EXTS); ++i) {
|
for (int i = 0; i < NELEM(FILE_EXTS); ++i) {
|
||||||
@@ -728,17 +755,18 @@ player_type getPlayerType(const char* url)
|
|||||||
int start = lenURL - len;
|
int start = lenURL - len;
|
||||||
if (start > 0) {
|
if (start > 0) {
|
||||||
if (!strncmp(url + start, FILE_EXTS[i].extension, len)) {
|
if (!strncmp(url + start, FILE_EXTS[i].extension, len)) {
|
||||||
return FILE_EXTS[i].playertype;
|
if (FILE_EXTS[i].playertype == VORBIS_PLAYER
|
||||||
|
&& !strncasecmp(url, "http://", 7)
|
||||||
|
&& useStagefrightForHTTP) {
|
||||||
|
return STAGEFRIGHT_PLAYER;
|
||||||
|
}
|
||||||
|
return OverrideStagefrightForVorbis(FILE_EXTS[i].playertype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strncasecmp(url, "http://", 7)) {
|
if (!strncasecmp(url, "http://", 7)) {
|
||||||
char value[PROPERTY_VALUE_MAX];
|
if (!useStagefrightForHTTP) {
|
||||||
if (!property_get("media.stagefright.enable-http", value, NULL)
|
|
||||||
|| (strcmp(value, "1") && strcasecmp(value, "true"))) {
|
|
||||||
// For now, we're going to use PV for http-based playback
|
|
||||||
// by default until we can clear up a few more issues.
|
|
||||||
return PV_PLAYER;
|
return PV_PLAYER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ LOCAL_SRC_FILES += \
|
|||||||
StagefrightMetadataRetriever.cpp \
|
StagefrightMetadataRetriever.cpp \
|
||||||
TimeSource.cpp \
|
TimeSource.cpp \
|
||||||
TimedEventQueue.cpp \
|
TimedEventQueue.cpp \
|
||||||
|
VorbisExtractor.cpp \
|
||||||
WAVExtractor.cpp \
|
WAVExtractor.cpp \
|
||||||
string.cpp
|
string.cpp
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "include/MP3Extractor.h"
|
#include "include/MP3Extractor.h"
|
||||||
#include "include/MPEG4Extractor.h"
|
#include "include/MPEG4Extractor.h"
|
||||||
#include "include/WAVExtractor.h"
|
#include "include/WAVExtractor.h"
|
||||||
|
#include "include/VorbisExtractor.h"
|
||||||
|
|
||||||
#include <media/stagefright/CachingDataSource.h>
|
#include <media/stagefright/CachingDataSource.h>
|
||||||
#include <media/stagefright/DataSource.h>
|
#include <media/stagefright/DataSource.h>
|
||||||
@@ -92,6 +93,7 @@ void DataSource::RegisterDefaultSniffers() {
|
|||||||
RegisterSniffer(SniffMPEG4);
|
RegisterSniffer(SniffMPEG4);
|
||||||
RegisterSniffer(SniffAMR);
|
RegisterSniffer(SniffAMR);
|
||||||
RegisterSniffer(SniffWAV);
|
RegisterSniffer(SniffWAV);
|
||||||
|
RegisterSniffer(SniffVorbis);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|||||||
@@ -34,5 +34,6 @@ const char *MEDIA_MIMETYPE_AUDIO_RAW = "audio/raw";
|
|||||||
|
|
||||||
const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mpeg4";
|
const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mpeg4";
|
||||||
const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/wav";
|
const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/wav";
|
||||||
|
const char *MEDIA_MIMETYPE_CONTAINER_VORBIS = "application/ogg";
|
||||||
|
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "include/MP3Extractor.h"
|
#include "include/MP3Extractor.h"
|
||||||
#include "include/MPEG4Extractor.h"
|
#include "include/MPEG4Extractor.h"
|
||||||
#include "include/WAVExtractor.h"
|
#include "include/WAVExtractor.h"
|
||||||
|
#include "include/VorbisExtractor.h"
|
||||||
|
|
||||||
#include <media/stagefright/DataSource.h>
|
#include <media/stagefright/DataSource.h>
|
||||||
#include <media/stagefright/MediaDefs.h>
|
#include <media/stagefright/MediaDefs.h>
|
||||||
@@ -62,6 +63,8 @@ sp<MediaExtractor> MediaExtractor::Create(
|
|||||||
return new AMRExtractor(source);
|
return new AMRExtractor(source);
|
||||||
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) {
|
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) {
|
||||||
return new WAVExtractor(source);
|
return new WAVExtractor(source);
|
||||||
|
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_VORBIS)) {
|
||||||
|
return new VorbisExtractor(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
311
media/libstagefright/VorbisExtractor.cpp
Normal file
311
media/libstagefright/VorbisExtractor.cpp
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//#define LOG_NDEBUG 0
|
||||||
|
#define LOG_TAG "VorbisExtractor"
|
||||||
|
#include <utils/Log.h>
|
||||||
|
|
||||||
|
#include "include/VorbisExtractor.h"
|
||||||
|
|
||||||
|
#include <media/stagefright/DataSource.h>
|
||||||
|
#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>
|
||||||
|
#include <utils/String8.h>
|
||||||
|
|
||||||
|
#include <ivorbisfile.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
|
||||||
|
struct VorbisDataSource {
|
||||||
|
sp<DataSource> mDataSource;
|
||||||
|
off_t mOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
static size_t VorbisRead(
|
||||||
|
void *ptr, size_t size, size_t nmemb, void *datasource) {
|
||||||
|
VorbisDataSource *vds = (VorbisDataSource *)datasource;
|
||||||
|
|
||||||
|
ssize_t n = vds->mDataSource->readAt(vds->mOffset, ptr, size * nmemb);
|
||||||
|
|
||||||
|
if (n < 0) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
vds->mOffset += n;
|
||||||
|
|
||||||
|
return n / size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int VorbisSeek(
|
||||||
|
void *datasource, ogg_int64_t offset, int whence) {
|
||||||
|
VorbisDataSource *vds = (VorbisDataSource *)datasource;
|
||||||
|
|
||||||
|
switch (whence) {
|
||||||
|
case SEEK_SET:
|
||||||
|
vds->mOffset = offset;
|
||||||
|
break;
|
||||||
|
case SEEK_END:
|
||||||
|
{
|
||||||
|
off_t size;
|
||||||
|
if (vds->mDataSource->getSize(&size) != OK) {
|
||||||
|
errno = ESPIPE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vds->mOffset = offset + size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SEEK_CUR:
|
||||||
|
{
|
||||||
|
vds->mOffset += offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int VorbisClose(void *datasource) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long VorbisTell(void *datasource) {
|
||||||
|
VorbisDataSource *vds = (VorbisDataSource *)datasource;
|
||||||
|
|
||||||
|
return vds->mOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ov_callbacks gVorbisCallbacks = {
|
||||||
|
&VorbisRead,
|
||||||
|
&VorbisSeek,
|
||||||
|
&VorbisClose,
|
||||||
|
&VorbisTell
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct VorbisSource : public MediaSource {
|
||||||
|
VorbisSource(const sp<VorbisExtractor> &extractor,
|
||||||
|
const sp<MetaData> &meta, OggVorbis_File *file);
|
||||||
|
|
||||||
|
virtual sp<MetaData> getFormat();
|
||||||
|
|
||||||
|
virtual status_t start(MetaData *params = NULL);
|
||||||
|
virtual status_t stop();
|
||||||
|
|
||||||
|
virtual status_t read(
|
||||||
|
MediaBuffer **buffer, const ReadOptions *options = NULL);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~VorbisSource();
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum {
|
||||||
|
kMaxBufferSize = 8192
|
||||||
|
};
|
||||||
|
|
||||||
|
sp<VorbisExtractor> mExtractor;
|
||||||
|
sp<MetaData> mMeta;
|
||||||
|
OggVorbis_File *mFile;
|
||||||
|
MediaBufferGroup *mGroup;
|
||||||
|
|
||||||
|
VorbisSource(const VorbisSource &);
|
||||||
|
VorbisSource &operator=(const VorbisSource &);
|
||||||
|
};
|
||||||
|
|
||||||
|
VorbisSource::VorbisSource(
|
||||||
|
const sp<VorbisExtractor> &extractor,
|
||||||
|
const sp<MetaData> &meta, OggVorbis_File *file)
|
||||||
|
: mExtractor(extractor),
|
||||||
|
mMeta(meta),
|
||||||
|
mFile(file),
|
||||||
|
mGroup(NULL) {
|
||||||
|
}
|
||||||
|
|
||||||
|
VorbisSource::~VorbisSource() {
|
||||||
|
if (mGroup) {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<MetaData> VorbisSource::getFormat() {
|
||||||
|
return mMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t VorbisSource::start(MetaData *params) {
|
||||||
|
if (mGroup != NULL) {
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
mGroup = new MediaBufferGroup;
|
||||||
|
mGroup->add_buffer(new MediaBuffer(kMaxBufferSize));
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t VorbisSource::stop() {
|
||||||
|
delete mGroup;
|
||||||
|
mGroup = NULL;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t VorbisSource::read(
|
||||||
|
MediaBuffer **out, const ReadOptions *options) {
|
||||||
|
*out = NULL;
|
||||||
|
|
||||||
|
int64_t seekTimeUs;
|
||||||
|
if (options && options->getSeekTo(&seekTimeUs)) {
|
||||||
|
ov_time_seek(mFile, seekTimeUs / 1000ll);
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaBuffer *buffer;
|
||||||
|
CHECK_EQ(OK, mGroup->acquire_buffer(&buffer));
|
||||||
|
|
||||||
|
ogg_int64_t positionMs = ov_time_tell(mFile);
|
||||||
|
|
||||||
|
int bitstream;
|
||||||
|
long n = ov_read(mFile, buffer->data(), buffer->size(), &bitstream);
|
||||||
|
|
||||||
|
if (n <= 0) {
|
||||||
|
LOGE("ov_read returned %ld", n);
|
||||||
|
|
||||||
|
buffer->release();
|
||||||
|
buffer = NULL;
|
||||||
|
|
||||||
|
return n < 0 ? ERROR_MALFORMED : ERROR_END_OF_STREAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer->set_range(0, n);
|
||||||
|
buffer->meta_data()->setInt64(kKeyTime, positionMs * 1000ll);
|
||||||
|
|
||||||
|
*out = buffer;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
VorbisExtractor::VorbisExtractor(const sp<DataSource> &source)
|
||||||
|
: mDataSource(source),
|
||||||
|
mFile(new OggVorbis_File),
|
||||||
|
mVorbisDataSource(new VorbisDataSource),
|
||||||
|
mInitCheck(NO_INIT) {
|
||||||
|
mVorbisDataSource->mDataSource = mDataSource;
|
||||||
|
mVorbisDataSource->mOffset = 0;
|
||||||
|
|
||||||
|
int res = ov_open_callbacks(
|
||||||
|
mVorbisDataSource, mFile, NULL, 0, gVorbisCallbacks);
|
||||||
|
|
||||||
|
if (res != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mMeta = new MetaData;
|
||||||
|
mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
|
||||||
|
|
||||||
|
vorbis_info *vi = ov_info(mFile, -1);
|
||||||
|
mMeta->setInt32(kKeySampleRate, vi->rate);
|
||||||
|
mMeta->setInt32(kKeyChannelCount, vi->channels);
|
||||||
|
|
||||||
|
ogg_int64_t durationMs = ov_time_total(mFile, -1);
|
||||||
|
mMeta->setInt64(kKeyDuration, durationMs * 1000ll);
|
||||||
|
|
||||||
|
LOGI("Successfully initialized.");
|
||||||
|
|
||||||
|
mInitCheck = OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
VorbisExtractor::~VorbisExtractor() {
|
||||||
|
CHECK_EQ(0, ov_clear(mFile));
|
||||||
|
|
||||||
|
delete mVorbisDataSource;
|
||||||
|
mVorbisDataSource = NULL;
|
||||||
|
|
||||||
|
delete mFile;
|
||||||
|
mFile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t VorbisExtractor::countTracks() {
|
||||||
|
return mInitCheck != OK ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<MediaSource> VorbisExtractor::getTrack(size_t index) {
|
||||||
|
if (index >= 1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new VorbisSource(this, mMeta, mFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<MetaData> VorbisExtractor::getTrackMetaData(
|
||||||
|
size_t index, uint32_t flags) {
|
||||||
|
if (index >= 1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<MetaData> VorbisExtractor::getMetaData() {
|
||||||
|
sp<MetaData> meta = new MetaData;
|
||||||
|
|
||||||
|
if (mInitCheck != OK) {
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_VORBIS);
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SniffVorbis(
|
||||||
|
const sp<DataSource> &source, String8 *mimeType, float *confidence) {
|
||||||
|
OggVorbis_File file;
|
||||||
|
|
||||||
|
VorbisDataSource vds;
|
||||||
|
vds.mDataSource = source;
|
||||||
|
vds.mOffset = 0;
|
||||||
|
|
||||||
|
int res = ov_test_callbacks(&vds, &file, NULL, 0, gVorbisCallbacks);
|
||||||
|
|
||||||
|
CHECK_EQ(0, ov_clear(&file));
|
||||||
|
|
||||||
|
if (res != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*mimeType = MEDIA_MIMETYPE_CONTAINER_VORBIS;
|
||||||
|
*confidence = 0.4f;
|
||||||
|
|
||||||
|
LOGV("This looks like an Ogg file.");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace android
|
||||||
60
media/libstagefright/include/VorbisExtractor.h
Normal file
60
media/libstagefright/include/VorbisExtractor.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 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 VORBIS_EXTRACTOR_H_
|
||||||
|
|
||||||
|
#define VORBIS_EXTRACTOR_H_
|
||||||
|
|
||||||
|
#include <media/stagefright/MediaExtractor.h>
|
||||||
|
|
||||||
|
struct OggVorbis_File;
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
|
||||||
|
class DataSource;
|
||||||
|
class String8;
|
||||||
|
|
||||||
|
struct VorbisDataSource;
|
||||||
|
|
||||||
|
struct VorbisExtractor : public MediaExtractor {
|
||||||
|
VorbisExtractor(const sp<DataSource> &source);
|
||||||
|
|
||||||
|
virtual size_t countTracks();
|
||||||
|
virtual sp<MediaSource> getTrack(size_t index);
|
||||||
|
virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
|
||||||
|
|
||||||
|
virtual sp<MetaData> getMetaData();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~VorbisExtractor();
|
||||||
|
|
||||||
|
private:
|
||||||
|
sp<DataSource> mDataSource;
|
||||||
|
struct OggVorbis_File *mFile;
|
||||||
|
struct VorbisDataSource *mVorbisDataSource;
|
||||||
|
status_t mInitCheck;
|
||||||
|
sp<MetaData> mMeta;
|
||||||
|
|
||||||
|
VorbisExtractor(const VorbisExtractor &);
|
||||||
|
VorbisExtractor &operator=(const VorbisExtractor &);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool SniffVorbis(
|
||||||
|
const sp<DataSource> &source, String8 *mimeType, float *confidence);
|
||||||
|
|
||||||
|
} // namespace android
|
||||||
|
|
||||||
|
#endif // VORBIS_EXTRACTOR_H_
|
||||||
Reference in New Issue
Block a user