Merge "Remove most stagefright property overrides, remove VorbisPlayer and VorbisMetadataRetriever as this functionality is now provided by stagefright." into gingerbread

This commit is contained in:
Andreas Huber
2010-06-24 09:05:08 -07:00
committed by Android (Google) Code Review
17 changed files with 47 additions and 952 deletions

View File

@@ -1,5 +1,3 @@
ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -72,5 +70,3 @@ LOCAL_MODULE_TAGS := debug
LOCAL_MODULE:= audioloop
include $(BUILD_EXECUTABLE)
endif

View File

@@ -39,7 +39,6 @@ template<typename T> class SortedVector;
enum player_type {
PV_PLAYER = 1,
SONIVOX_PLAYER = 2,
VORBIS_PLAYER = 3,
STAGEFRIGHT_PLAYER = 4,
// Test players are available only in the 'test' and 'eng' builds.
// The shared library with the test player is passed passed as an

View File

@@ -24,6 +24,7 @@ LOCAL_SHARED_LIBRARIES := \
libui \
libcutils \
libsurfaceflinger_client \
libstagefright \
libcamera_client
ifneq ($(BUILD_WITHOUT_PV),true)
@@ -34,15 +35,6 @@ else
LOCAL_CFLAGS += -DNO_OPENCORE
endif
ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
LOCAL_CFLAGS += -DBUILD_WITH_FULL_STAGEFRIGHT=1
LOCAL_SHARED_LIBRARIES += \
libstagefright
endif
LOCAL_STATIC_LIBRARIES :=
LOCAL_C_INCLUDES += \

View File

@@ -31,13 +31,7 @@
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#ifndef NO_OPENCORE
#include "pvmediascanner.h"
#endif
#if BUILD_WITH_FULL_STAGEFRIGHT
#include <media/stagefright/StagefrightMediaScanner.h>
#endif
// ----------------------------------------------------------------------------
@@ -286,25 +280,10 @@ android_media_MediaScanner_native_init(JNIEnv *env)
}
}
static MediaScanner *createMediaScanner() {
#if BUILD_WITH_FULL_STAGEFRIGHT
char value[PROPERTY_VALUE_MAX];
if (property_get("media.stagefright.enable-scan", value, NULL)
&& (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
return new StagefrightMediaScanner;
}
#endif
#ifndef NO_OPENCORE
return new PVMediaScanner();
#endif
return NULL;
}
static void
android_media_MediaScanner_native_setup(JNIEnv *env, jobject thiz)
{
MediaScanner *mp = createMediaScanner();
MediaScanner *mp = new StagefrightMediaScanner;
if (mp == NULL) {
jniThrowException(env, "java/lang/RuntimeException", "Out of memory");

View File

@@ -11,21 +11,11 @@ LOCAL_SRC_FILES:= \
MediaPlayerService.cpp \
MetadataRetrieverClient.cpp \
TestPlayerStub.cpp \
VorbisPlayer.cpp \
VorbisMetadataRetriever.cpp \
MidiMetadataRetriever.cpp \
MidiFile.cpp
ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
LOCAL_SRC_FILES += \
StagefrightPlayer.cpp \
MidiMetadataRetriever.cpp \
MidiFile.cpp \
StagefrightPlayer.cpp \
StagefrightRecorder.cpp
LOCAL_CFLAGS += -DBUILD_WITH_FULL_STAGEFRIGHT=1
endif
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
LOCAL_LDLIBS += -ldl -lpthread
endif

View File

@@ -56,7 +56,6 @@
#include "MetadataRetrieverClient.h"
#include "MidiFile.h"
#include "VorbisPlayer.h"
#include <media/PVPlayer.h>
#include "TestPlayerStub.h"
#include "StagefrightPlayer.h"
@@ -197,8 +196,6 @@ extmap FILE_EXTS [] = {
{".rtttl", SONIVOX_PLAYER},
{".rtx", SONIVOX_PLAYER},
{".ota", SONIVOX_PLAYER},
{".ogg", VORBIS_PLAYER},
{".oga", VORBIS_PLAYER},
#ifndef NO_OPENCORE
{".wma", PV_PLAYER},
{".wmv", PV_PLAYER},
@@ -666,37 +663,9 @@ void MediaPlayerService::Client::disconnect()
}
static player_type getDefaultPlayerType() {
#if BUILD_WITH_FULL_STAGEFRIGHT
char value[PROPERTY_VALUE_MAX];
if (property_get("media.stagefright.enable-player", value, NULL)
&& (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
return STAGEFRIGHT_PLAYER;
}
#endif
return PV_PLAYER;
return STAGEFRIGHT_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)
{
char buf[20];
@@ -708,7 +677,7 @@ player_type getPlayerType(int fd, int64_t offset, int64_t length)
// Ogg vorbis?
if (ident == 0x5367674f) // 'OggS'
return OverrideStagefrightForVorbis(VORBIS_PLAYER);
return STAGEFRIGHT_PLAYER;
#ifndef NO_OPENCORE
if (ident == 0x75b22630) {
@@ -744,13 +713,6 @@ player_type getPlayerType(const char* url)
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
int lenURL = strlen(url);
for (int i = 0; i < NELEM(FILE_EXTS); ++i) {
@@ -758,22 +720,11 @@ player_type getPlayerType(const char* url)
int start = lenURL - len;
if (start > 0) {
if (!strncasecmp(url + start, FILE_EXTS[i].extension, len)) {
if (FILE_EXTS[i].playertype == VORBIS_PLAYER
&& !strncasecmp(url, "http://", 7)
&& useStagefrightForHTTP) {
return STAGEFRIGHT_PLAYER;
}
return OverrideStagefrightForVorbis(FILE_EXTS[i].playertype);
return FILE_EXTS[i].playertype;
}
}
}
if (!strncasecmp(url, "http://", 7)) {
if (!useStagefrightForHTTP) {
return PV_PLAYER;
}
}
if (!strncasecmp(url, "rtsp://", 7)) {
char value[PROPERTY_VALUE_MAX];
if (!property_get("media.stagefright.enable-rtsp", value, NULL)
@@ -802,16 +753,10 @@ static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
LOGV(" create MidiFile");
p = new MidiFile();
break;
case VORBIS_PLAYER:
LOGV(" create VorbisPlayer");
p = new VorbisPlayer();
break;
#if BUILD_WITH_FULL_STAGEFRIGHT
case STAGEFRIGHT_PLAYER:
LOGV(" create StagefrightPlayer");
p = new StagefrightPlayer;
break;
#endif
case TEST_PLAYER:
LOGV("Create Test Player stub");
p = new TestPlayerStub();

View File

@@ -294,13 +294,11 @@ MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service,
LOGV("Client constructor");
mPid = pid;
#if BUILD_WITH_FULL_STAGEFRIGHT
char value[PROPERTY_VALUE_MAX];
if (property_get("media.stagefright.enable-record", value, NULL)
&& (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
mRecorder = new StagefrightRecorder;
} else
#endif
#ifndef NO_OPENCORE
{
mRecorder = new PVMediaRecorder();

View File

@@ -37,7 +37,6 @@
#include <media/MediaPlayerInterface.h>
#include <media/PVMetadataRetriever.h>
#include <private/media/VideoFrame.h>
#include "VorbisMetadataRetriever.h"
#include "MidiMetadataRetriever.h"
#include "MetadataRetrieverClient.h"
#include "StagefrightMetadataRetriever.h"
@@ -103,30 +102,17 @@ static sp<MediaMetadataRetrieverBase> createRetriever(player_type playerType)
{
sp<MediaMetadataRetrieverBase> p;
switch (playerType) {
#if BUILD_WITH_FULL_STAGEFRIGHT
case STAGEFRIGHT_PLAYER:
{
char value[PROPERTY_VALUE_MAX];
if (property_get("media.stagefright.enable-meta", value, NULL)
&& (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
LOGV("create StagefrightMetadataRetriever");
p = new StagefrightMetadataRetriever;
break;
}
// fall through
p = new StagefrightMetadataRetriever;
break;
}
#endif
#ifndef NO_OPENCORE
case PV_PLAYER:
LOGV("create pv metadata retriever");
p = new PVMetadataRetriever();
break;
#endif
case VORBIS_PLAYER:
LOGV("create vorbis metadata retriever");
p = new VorbisMetadataRetriever();
break;
case SONIVOX_PLAYER:
LOGV("create midi metadata retriever");
p = new MidiMetadataRetriever();

View File

@@ -1,87 +0,0 @@
/*
**
** Copyright 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.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "VorbisMetadataRetriever"
#include <utils/Log.h>
#include "VorbisMetadataRetriever.h"
#include <media/mediametadataretriever.h>
#
namespace android {
void VorbisMetadataRetriever::clearMetadataValues()
{
LOGV("cleearMetadataValues");
mMetadataValues[0][0] = '\0';
}
status_t VorbisMetadataRetriever::setDataSource(const char *url)
{
LOGV("setDataSource: url(%s)", url? url: "NULL pointer");
Mutex::Autolock lock(mLock);
clearMetadataValues();
if (mVorbisPlayer == 0) {
mVorbisPlayer = new VorbisPlayer();
}
// TODO: support headers in MetadataRetriever interface!
return mVorbisPlayer->setDataSource(url, NULL /* headers */);
}
status_t VorbisMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)
{
LOGV("setDataSource: fd(%d), offset(%lld), and length(%lld)", fd, offset, length);
Mutex::Autolock lock(mLock);
clearMetadataValues();
if (mVorbisPlayer == 0) {
mVorbisPlayer = new VorbisPlayer();
}
return mVorbisPlayer->setDataSource(fd, offset, length);
}
const char* VorbisMetadataRetriever::extractMetadata(int keyCode)
{
LOGV("extractMetadata: key(%d)", keyCode);
Mutex::Autolock lock(mLock);
if (mVorbisPlayer == 0 || mVorbisPlayer->initCheck() != NO_ERROR) {
LOGE("no vorbis player is initialized yet");
return NULL;
}
switch (keyCode) {
case METADATA_KEY_DURATION:
{
if (mMetadataValues[0][0] == '\0') {
int duration = -1;
if (mVorbisPlayer->getDuration(&duration) != NO_ERROR) {
LOGE("failed to get duration");
return NULL;
}
snprintf(mMetadataValues[0], MAX_METADATA_STRING_LENGTH, "%d", duration);
}
LOGV("duration: %s ms", mMetadataValues[0]);
return mMetadataValues[0];
}
default:
LOGE("Unsupported key code (%d)", keyCode);
return NULL;
}
return NULL;
}
};

View File

@@ -1,49 +0,0 @@
/*
**
** Copyright 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 ANDROID_VORBISMETADATARETRIEVER_H
#define ANDROID_VORBISMETADATARETRIEVER_H
#include <utils/threads.h>
#include <utils/Errors.h>
#include <media/MediaMetadataRetrieverInterface.h>
#include "VorbisPlayer.h"
namespace android {
class VorbisMetadataRetriever : public MediaMetadataRetrieverInterface {
public:
VorbisMetadataRetriever() {}
~VorbisMetadataRetriever() {}
virtual status_t setDataSource(const char *url);
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual const char* extractMetadata(int keyCode);
private:
static const uint32_t MAX_METADATA_STRING_LENGTH = 128;
void clearMetadataValues();
Mutex mLock;
sp<VorbisPlayer> mVorbisPlayer;
char mMetadataValues[1][MAX_METADATA_STRING_LENGTH];
};
}; // namespace android
#endif // ANDROID_VORBISMETADATARETRIEVER_H

View File

@@ -1,529 +0,0 @@
/*
** Copyright 2007, 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 "VorbisPlayer"
#include "utils/Log.h"
#include <stdio.h>
#include <assert.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "VorbisPlayer.h"
#ifdef HAVE_GETTID
static pid_t myTid() { return gettid(); }
#else
static pid_t myTid() { return getpid(); }
#endif
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
// TODO: Determine appropriate return codes
static status_t ERROR_NOT_OPEN = -1;
static status_t ERROR_OPEN_FAILED = -2;
static status_t ERROR_ALLOCATE_FAILED = -4;
static status_t ERROR_NOT_SUPPORTED = -8;
static status_t ERROR_NOT_READY = -16;
static status_t STATE_INIT = 0;
static status_t STATE_ERROR = 1;
static status_t STATE_OPEN = 2;
VorbisPlayer::VorbisPlayer() :
mAudioBuffer(NULL), mPlayTime(-1), mDuration(-1), mState(STATE_ERROR),
mStreamType(AudioSystem::MUSIC), mLoop(false), mAndroidLoop(false),
mExit(false), mPaused(false), mRender(false), mRenderTid(-1)
{
LOGV("constructor\n");
memset(&mVorbisFile, 0, sizeof mVorbisFile);
}
void VorbisPlayer::onFirstRef()
{
LOGV("onFirstRef");
// create playback thread
Mutex::Autolock l(mMutex);
createThreadEtc(renderThread, this, "vorbis decoder", ANDROID_PRIORITY_AUDIO);
mCondition.wait(mMutex);
if (mRenderTid > 0) {
LOGV("render thread(%d) started", mRenderTid);
mState = STATE_INIT;
}
}
status_t VorbisPlayer::initCheck()
{
if (mState != STATE_ERROR) return NO_ERROR;
return ERROR_NOT_READY;
}
VorbisPlayer::~VorbisPlayer() {
LOGV("VorbisPlayer destructor\n");
release();
}
status_t VorbisPlayer::setDataSource(
const char *uri, const KeyedVector<String8, String8> *headers) {
return setdatasource(uri, -1, 0, 0x7ffffffffffffffLL); // intentionally less than LONG_MAX
}
status_t VorbisPlayer::setDataSource(int fd, int64_t offset, int64_t length)
{
return setdatasource(NULL, fd, offset, length);
}
size_t VorbisPlayer::vp_fread(void *buf, size_t size, size_t nmemb, void *me) {
VorbisPlayer *self = (VorbisPlayer*) me;
long curpos = vp_ftell(me);
while (nmemb != 0 && (curpos + size * nmemb) > self->mLength) {
nmemb--;
}
return fread(buf, size, nmemb, self->mFile);
}
int VorbisPlayer::vp_fseek(void *me, ogg_int64_t off, int whence) {
VorbisPlayer *self = (VorbisPlayer*) me;
if (whence == SEEK_SET)
return fseek(self->mFile, off + self->mOffset, whence);
else if (whence == SEEK_CUR)
return fseek(self->mFile, off, whence);
else if (whence == SEEK_END)
return fseek(self->mFile, self->mOffset + self->mLength + off, SEEK_SET);
return -1;
}
int VorbisPlayer::vp_fclose(void *me) {
LOGV("vp_fclose");
VorbisPlayer *self = (VorbisPlayer*) me;
int ret = fclose (self->mFile);
self->mFile = NULL;
return ret;
}
long VorbisPlayer::vp_ftell(void *me) {
VorbisPlayer *self = (VorbisPlayer*) me;
return ftell(self->mFile) - self->mOffset;
}
status_t VorbisPlayer::setdatasource(const char *path, int fd, int64_t offset, int64_t length)
{
LOGV("setDataSource url=%s, fd=%d\n", path, fd);
// file still open?
Mutex::Autolock l(mMutex);
if (mState == STATE_OPEN) {
reset_nosync();
}
// open file and set paused state
if (path) {
mFile = fopen(path, "r");
} else {
mFile = fdopen(dup(fd), "r");
}
if (mFile == NULL) {
return ERROR_OPEN_FAILED;
}
struct stat sb;
int ret;
if (path) {
ret = stat(path, &sb);
} else {
ret = fstat(fd, &sb);
}
if (ret != 0) {
mState = STATE_ERROR;
fclose(mFile);
return ERROR_OPEN_FAILED;
}
if (sb.st_size > (length + offset)) {
mLength = length;
} else {
mLength = sb.st_size - offset;
}
ov_callbacks callbacks = {
(size_t (*)(void *, size_t, size_t, void *)) vp_fread,
(int (*)(void *, ogg_int64_t, int)) vp_fseek,
(int (*)(void *)) vp_fclose,
(long (*)(void *)) vp_ftell
};
mOffset = offset;
fseek(mFile, offset, SEEK_SET);
int result = ov_open_callbacks(this, &mVorbisFile, NULL, 0, callbacks);
if (result < 0) {
LOGE("ov_open() failed: [%d]\n", (int)result);
mState = STATE_ERROR;
fclose(mFile);
return ERROR_OPEN_FAILED;
}
// look for the android loop tag (for ringtones)
char **ptr = ov_comment(&mVorbisFile,-1)->user_comments;
while(*ptr) {
// does the comment start with ANDROID_LOOP_TAG
if(strncmp(*ptr, ANDROID_LOOP_TAG, strlen(ANDROID_LOOP_TAG)) == 0) {
// read the value of the tag
char *val = *ptr + strlen(ANDROID_LOOP_TAG) + 1;
mAndroidLoop = (strncmp(val, "true", 4) == 0);
}
// we keep parsing even after finding one occurence of ANDROID_LOOP_TAG,
// as we could find another one (the tag might have been appended more than once).
++ptr;
}
LOGV_IF(mAndroidLoop, "looped sound");
mState = STATE_OPEN;
return NO_ERROR;
}
status_t VorbisPlayer::prepare()
{
LOGV("prepare\n");
if (mState != STATE_OPEN ) {
return ERROR_NOT_OPEN;
}
return NO_ERROR;
}
status_t VorbisPlayer::prepareAsync() {
LOGV("prepareAsync\n");
// can't hold the lock here because of the callback
// it's safe because we don't change state
if (mState != STATE_OPEN ) {
sendEvent(MEDIA_ERROR);
return NO_ERROR;
}
sendEvent(MEDIA_PREPARED);
return NO_ERROR;
}
status_t VorbisPlayer::start()
{
LOGV("start\n");
Mutex::Autolock l(mMutex);
if (mState != STATE_OPEN) {
return ERROR_NOT_OPEN;
}
mPaused = false;
mRender = true;
// wake up render thread
LOGV(" wakeup render thread\n");
mCondition.signal();
return NO_ERROR;
}
status_t VorbisPlayer::stop()
{
LOGV("stop\n");
Mutex::Autolock l(mMutex);
if (mState != STATE_OPEN) {
return ERROR_NOT_OPEN;
}
mPaused = true;
mRender = false;
return NO_ERROR;
}
status_t VorbisPlayer::seekTo(int position)
{
LOGV("seekTo %d\n", position);
Mutex::Autolock l(mMutex);
if (mState != STATE_OPEN) {
return ERROR_NOT_OPEN;
}
int result = ov_time_seek(&mVorbisFile, position);
if (result != 0) {
LOGE("ov_time_seek() returned %d\n", result);
return result;
}
sendEvent(MEDIA_SEEK_COMPLETE);
return NO_ERROR;
}
status_t VorbisPlayer::pause()
{
LOGV("pause\n");
Mutex::Autolock l(mMutex);
if (mState != STATE_OPEN) {
return ERROR_NOT_OPEN;
}
mPaused = true;
return NO_ERROR;
}
bool VorbisPlayer::isPlaying()
{
LOGV("isPlaying\n");
if (mState == STATE_OPEN) {
return mRender;
}
return false;
}
status_t VorbisPlayer::getCurrentPosition(int* position)
{
LOGV("getCurrentPosition\n");
Mutex::Autolock l(mMutex);
if (mState != STATE_OPEN) {
LOGE("getCurrentPosition(): file not open");
return ERROR_NOT_OPEN;
}
*position = ov_time_tell(&mVorbisFile);
if (*position < 0) {
LOGE("getCurrentPosition(): ov_time_tell returned %d", *position);
return *position;
}
return NO_ERROR;
}
status_t VorbisPlayer::getDuration(int* duration)
{
LOGV("getDuration\n");
Mutex::Autolock l(mMutex);
if (mState != STATE_OPEN) {
return ERROR_NOT_OPEN;
}
int ret = ov_time_total(&mVorbisFile, -1);
if (ret == OV_EINVAL) {
return -1;
}
*duration = ret;
return NO_ERROR;
}
status_t VorbisPlayer::release()
{
LOGV("release\n");
Mutex::Autolock l(mMutex);
reset_nosync();
// TODO: timeout when thread won't exit
// wait for render thread to exit
if (mRenderTid > 0) {
mExit = true;
mCondition.signal();
mCondition.wait(mMutex);
}
return NO_ERROR;
}
status_t VorbisPlayer::reset()
{
LOGV("reset\n");
Mutex::Autolock l(mMutex);
return reset_nosync();
}
// always call with lock held
status_t VorbisPlayer::reset_nosync()
{
// close file
if (mFile != NULL) {
ov_clear(&mVorbisFile); // this also closes the FILE
if (mFile != NULL) {
LOGV("OOPS! Vorbis didn't close the file");
fclose(mFile);
mFile = NULL;
}
}
mState = STATE_ERROR;
mPlayTime = -1;
mDuration = -1;
mLoop = false;
mAndroidLoop = false;
mPaused = false;
mRender = false;
return NO_ERROR;
}
status_t VorbisPlayer::setLooping(int loop)
{
LOGV("setLooping\n");
Mutex::Autolock l(mMutex);
mLoop = (loop != 0);
return NO_ERROR;
}
status_t VorbisPlayer::createOutputTrack() {
// open audio track
vorbis_info *vi = ov_info(&mVorbisFile, -1);
LOGV("Create AudioTrack object: rate=%ld, channels=%d\n",
vi->rate, vi->channels);
if (mAudioSink->open(vi->rate, vi->channels, AudioSystem::PCM_16_BIT, DEFAULT_AUDIOSINK_BUFFERCOUNT) != NO_ERROR) {
LOGE("mAudioSink open failed");
return ERROR_OPEN_FAILED;
}
return NO_ERROR;
}
int VorbisPlayer::renderThread(void* p) {
return ((VorbisPlayer*)p)->render();
}
#define AUDIOBUFFER_SIZE 4096
int VorbisPlayer::render() {
int result = -1;
int temp;
int current_section = 0;
bool audioStarted = false;
LOGV("render\n");
// allocate render buffer
mAudioBuffer = new char[AUDIOBUFFER_SIZE];
if (!mAudioBuffer) {
LOGE("mAudioBuffer allocate failed\n");
goto threadExit;
}
// let main thread know we're ready
{
Mutex::Autolock l(mMutex);
mRenderTid = myTid();
mCondition.signal();
}
while (1) {
long numread = 0;
{
Mutex::Autolock l(mMutex);
// pausing?
if (mPaused) {
if (mAudioSink->ready()) mAudioSink->pause();
mRender = false;
audioStarted = false;
}
// nothing to render, wait for client thread to wake us up
if (!mExit && !mRender) {
LOGV("render - signal wait\n");
mCondition.wait(mMutex);
LOGV("render - signal rx'd\n");
}
if (mExit) break;
// We could end up here if start() is called, and before we get a
// chance to run, the app calls stop() or reset(). Re-check render
// flag so we don't try to render in stop or reset state.
if (!mRender) continue;
// render vorbis data into the input buffer
numread = ov_read(&mVorbisFile, mAudioBuffer, AUDIOBUFFER_SIZE, &current_section);
if (numread == 0) {
// end of file, do we need to loop?
// ...
if (mLoop || mAndroidLoop) {
ov_time_seek(&mVorbisFile, 0);
current_section = 0;
numread = ov_read(&mVorbisFile, mAudioBuffer, AUDIOBUFFER_SIZE, &current_section);
} else {
mAudioSink->stop();
audioStarted = false;
mRender = false;
mPaused = true;
int endpos = ov_time_tell(&mVorbisFile);
LOGV("send MEDIA_PLAYBACK_COMPLETE");
sendEvent(MEDIA_PLAYBACK_COMPLETE);
// wait until we're started again
LOGV("playback complete - wait for signal");
mCondition.wait(mMutex);
LOGV("playback complete - signal rx'd");
if (mExit) break;
// if we're still at the end, restart from the beginning
if (mState == STATE_OPEN) {
int curpos = ov_time_tell(&mVorbisFile);
if (curpos == endpos) {
ov_time_seek(&mVorbisFile, 0);
}
current_section = 0;
numread = ov_read(&mVorbisFile, mAudioBuffer, AUDIOBUFFER_SIZE, &current_section);
}
}
}
}
// codec returns negative number on error
if (numread < 0) {
LOGE("Error in Vorbis decoder");
sendEvent(MEDIA_ERROR);
break;
}
// create audio output track if necessary
if (!mAudioSink->ready()) {
LOGV("render - create output track\n");
if (createOutputTrack() != NO_ERROR)
break;
}
// Write data to the audio hardware
if ((temp = mAudioSink->write(mAudioBuffer, numread)) < 0) {
LOGE("Error in writing:%d",temp);
result = temp;
break;
}
// start audio output if necessary
if (!audioStarted && !mPaused && !mExit) {
LOGV("render - starting audio\n");
mAudioSink->start();
audioStarted = true;
}
}
threadExit:
mAudioSink.clear();
if (mAudioBuffer) {
delete [] mAudioBuffer;
mAudioBuffer = NULL;
}
// tell main thread goodbye
Mutex::Autolock l(mMutex);
mRenderTid = -1;
mCondition.signal();
return result;
}
} // end namespace android

View File

@@ -1,94 +0,0 @@
/*
**
** Copyright 2008, 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 ANDROID_VORBISPLAYER_H
#define ANDROID_VORBISPLAYER_H
#include <utils/threads.h>
#include <media/MediaPlayerInterface.h>
#include <media/AudioTrack.h>
#include "ivorbiscodec.h"
#include "ivorbisfile.h"
#define ANDROID_LOOP_TAG "ANDROID_LOOP"
namespace android {
class VorbisPlayer : public MediaPlayerInterface {
public:
VorbisPlayer();
~VorbisPlayer();
virtual void onFirstRef();
virtual status_t initCheck();
virtual status_t setDataSource(
const char *uri, const KeyedVector<String8, String8> *headers);
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual status_t setVideoSurface(const sp<ISurface>& surface) { return UNKNOWN_ERROR; }
virtual status_t prepare();
virtual status_t prepareAsync();
virtual status_t start();
virtual status_t stop();
virtual status_t seekTo(int msec);
virtual status_t pause();
virtual bool isPlaying();
virtual status_t getCurrentPosition(int* msec);
virtual status_t getDuration(int* msec);
virtual status_t release();
virtual status_t reset();
virtual status_t setLooping(int loop);
virtual player_type playerType() { return VORBIS_PLAYER; }
virtual status_t invoke(const Parcel& request, Parcel *reply) {return INVALID_OPERATION;}
private:
status_t setdatasource(const char *path, int fd, int64_t offset, int64_t length);
status_t reset_nosync();
status_t createOutputTrack();
static int renderThread(void*);
int render();
static size_t vp_fread(void *, size_t, size_t, void *);
static int vp_fseek(void *, ogg_int64_t, int);
static int vp_fclose(void *);
static long vp_ftell(void *);
Mutex mMutex;
Condition mCondition;
FILE* mFile;
int64_t mOffset;
int64_t mLength;
OggVorbis_File mVorbisFile;
char* mAudioBuffer;
int mPlayTime;
int mDuration;
status_t mState;
int mStreamType;
bool mLoop;
bool mAndroidLoop;
volatile bool mExit;
bool mPaused;
volatile bool mRender;
pid_t mRenderTid;
};
}; // namespace android
#endif // ANDROID_VORBISPLAYER_H

View File

@@ -3,51 +3,44 @@ include $(CLEAR_VARS)
include frameworks/base/media/libstagefright/codecs/common/Config.mk
LOCAL_SRC_FILES:= \
ESDS.cpp \
MediaBuffer.cpp \
MediaBufferGroup.cpp \
MediaDefs.cpp \
MediaSource.cpp \
MetaData.cpp \
OMXCodec.cpp \
Utils.cpp \
OMXClient.cpp
ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
LOCAL_SRC_FILES += \
AMRExtractor.cpp \
AMRWriter.cpp \
AudioPlayer.cpp \
AudioSource.cpp \
AwesomePlayer.cpp \
CameraSource.cpp \
DataSource.cpp \
FileSource.cpp \
HTTPStream.cpp \
JPEGSource.cpp \
MP3Extractor.cpp \
MPEG4Extractor.cpp \
MPEG4Writer.cpp \
MediaExtractor.cpp \
NuCachedSource2.cpp \
NuHTTPDataSource.cpp \
OggExtractor.cpp \
SampleIterator.cpp \
SampleTable.cpp \
ShoutcastSource.cpp \
StagefrightMediaScanner.cpp \
StagefrightMetadataRetriever.cpp \
ThrottledSource.cpp \
TimeSource.cpp \
TimedEventQueue.cpp \
WAVExtractor.cpp \
LOCAL_SRC_FILES:= \
AMRExtractor.cpp \
AMRWriter.cpp \
AudioPlayer.cpp \
AudioSource.cpp \
AwesomePlayer.cpp \
CameraSource.cpp \
DataSource.cpp \
ESDS.cpp \
FileSource.cpp \
HTTPStream.cpp \
JPEGSource.cpp \
MP3Extractor.cpp \
MPEG4Extractor.cpp \
MPEG4Writer.cpp \
MediaBuffer.cpp \
MediaBufferGroup.cpp \
MediaDefs.cpp \
MediaExtractor.cpp \
MediaSource.cpp \
MetaData.cpp \
NuCachedSource2.cpp \
NuHTTPDataSource.cpp \
OMXClient.cpp \
OMXCodec.cpp \
OggExtractor.cpp \
SampleIterator.cpp \
SampleTable.cpp \
ShoutcastSource.cpp \
StagefrightMediaScanner.cpp \
StagefrightMetadataRetriever.cpp \
ThrottledSource.cpp \
TimeSource.cpp \
TimedEventQueue.cpp \
Utils.cpp \
WAVExtractor.cpp \
string.cpp
LOCAL_CFLAGS += -DBUILD_WITH_FULL_STAGEFRIGHT
endif
LOCAL_C_INCLUDES:= \
$(JNI_H_INCLUDE) \
$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
@@ -82,20 +75,13 @@ LOCAL_STATIC_LIBRARIES := \
libstagefright_mpeg2ts \
libstagefright_httplive \
libstagefright_rtsp \
libstagefright_id3 \
LOCAL_SHARED_LIBRARIES += \
libstagefright_amrnb_common \
libstagefright_enc_common \
libstagefright_avc_common \
libstagefright_foundation \
ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
LOCAL_STATIC_LIBRARIES += \
libstagefright_id3
LOCAL_SHARED_LIBRARIES += \
libstagefright_color_conversion
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
@@ -108,8 +94,6 @@ ifneq ($(TARGET_SIMULATOR),true)
LOCAL_SHARED_LIBRARIES += libdl
endif
endif
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
LOCAL_LDLIBS += -lpthread
endif

View File

@@ -425,7 +425,6 @@ sp<MediaSource> OMXCodec::Create(
for (size_t i = 0; i < matchingCodecs.size(); ++i) {
componentName = matchingCodecs[i].string();
#if BUILD_WITH_FULL_STAGEFRIGHT
sp<MediaSource> softwareCodec = createEncoder?
InstantiateSoftwareEncoder(componentName, source, meta):
InstantiateSoftwareCodec(componentName, source);
@@ -435,7 +434,6 @@ sp<MediaSource> OMXCodec::Create(
return softwareCodec;
}
#endif
LOGV("Attempting to allocate OMX node '%s'", componentName);

View File

@@ -1,5 +1,3 @@
ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -28,5 +26,3 @@ LOCAL_MODULE_TAGS := debug
LOCAL_MODULE := testid3
include $(BUILD_EXECUTABLE)
endif

View File

@@ -1,5 +1,3 @@
ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -17,7 +15,3 @@ LOCAL_C_INCLUDES:= \
LOCAL_MODULE:= omx_tests
include $(BUILD_EXECUTABLE)
endif

View File

@@ -11,7 +11,6 @@
# 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.
ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
LOCAL_PATH:= $(call my-dir)
@@ -54,5 +53,3 @@ LOCAL_MODULE := jpeg_bench
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
endif