am 100ef9be: Merge "Disable vorbis seek when streaming from localhost." into froyo

Merge commit '100ef9bee48c9beb83d885d233de6a42c64f55af' into froyo-plus-aosp

* commit '100ef9bee48c9beb83d885d233de6a42c64f55af':
  Disable vorbis seek when streaming from localhost.
This commit is contained in:
Andreas Huber
2010-05-06 12:36:13 -07:00
committed by Android Git Automerger
11 changed files with 119 additions and 9 deletions

View File

@ -33,7 +33,8 @@ class String8;
class DataSource : public RefBase {
public:
enum Flags {
kWantsPrefetching = 1,
kWantsPrefetching = 1,
kStreamedFromLocalHost = 2,
};
static sp<DataSource> CreateFromURI(

View File

@ -45,9 +45,7 @@ public:
virtual status_t getSize(off_t *size);
virtual uint32_t flags() {
return kWantsPrefetching;
}
virtual uint32_t flags();
protected:
virtual ~HTTPDataSource();

View File

@ -44,6 +44,16 @@ public:
// returns an empty metadata object.
virtual sp<MetaData> getMetaData();
enum Flags {
CAN_SEEK_BACKWARD = 1,
CAN_SEEK_FORWARD = 2,
CAN_PAUSE = 4,
};
// If subclasses do _not_ override this, the default is
// CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE
virtual uint32_t flags() const;
protected:
MediaExtractor() {}
virtual ~MediaExtractor() {}

View File

@ -6,6 +6,9 @@
#include "AwesomePlayer.h"
#include <media/Metadata.h>
#include <media/stagefright/MediaExtractor.h>
namespace android {
StagefrightPlayer::StagefrightPlayer()
@ -109,7 +112,8 @@ status_t StagefrightPlayer::getDuration(int *msec) {
status_t err = mPlayer->getDuration(&durationUs);
if (err != OK) {
return err;
*msec = 0;
return OK;
}
*msec = (durationUs + 500) / 1000;
@ -156,4 +160,27 @@ void StagefrightPlayer::setAudioSink(const sp<AudioSink> &audioSink) {
mPlayer->setAudioSink(audioSink);
}
status_t StagefrightPlayer::getMetadata(
const media::Metadata::Filter& ids, Parcel *records) {
using media::Metadata;
uint32_t flags = mPlayer->flags();
Metadata metadata(records);
metadata.appendBool(
Metadata::kPauseAvailable,
flags & MediaExtractor::CAN_PAUSE);
metadata.appendBool(
Metadata::kSeekBackwardAvailable,
flags & MediaExtractor::CAN_SEEK_BACKWARD);
metadata.appendBool(
Metadata::kSeekForwardAvailable,
flags & MediaExtractor::CAN_SEEK_FORWARD);
return OK;
}
} // namespace android

View File

@ -53,6 +53,9 @@ public:
virtual status_t suspend();
virtual status_t resume();
virtual status_t getMetadata(
const media::Metadata::Filter& ids, Parcel *records);
private:
AwesomePlayer *mPlayer;

View File

@ -184,6 +184,7 @@ AwesomePlayer::AwesomePlayer()
mVideoRendererIsPreview(false),
mAudioPlayer(NULL),
mFlags(0),
mExtractorFlags(0),
mLastVideoBuffer(NULL),
mVideoBuffer(NULL),
mSuspensionState(NULL) {
@ -310,7 +311,13 @@ status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
}
}
return !haveAudio && !haveVideo ? UNKNOWN_ERROR : OK;
if (!haveAudio && !haveVideo) {
return UNKNOWN_ERROR;
}
mExtractorFlags = extractor->flags();
return OK;
}
void AwesomePlayer::reset() {
@ -390,6 +397,7 @@ void AwesomePlayer::reset_l() {
mDurationUs = -1;
mFlags = 0;
mExtractorFlags = 0;
mVideoWidth = mVideoHeight = -1;
mTimeSourceDeltaUs = 0;
mVideoTimeUs = 0;
@ -683,8 +691,14 @@ status_t AwesomePlayer::getPosition(int64_t *positionUs) {
}
status_t AwesomePlayer::seekTo(int64_t timeUs) {
Mutex::Autolock autoLock(mLock);
return seekTo_l(timeUs);
if (mExtractorFlags
& (MediaExtractor::CAN_SEEK_FORWARD
| MediaExtractor::CAN_SEEK_BACKWARD)) {
Mutex::Autolock autoLock(mLock);
return seekTo_l(timeUs);
}
return OK;
}
status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
@ -1362,5 +1376,9 @@ status_t AwesomePlayer::resume() {
return OK;
}
uint32_t AwesomePlayer::flags() const {
return mExtractorFlags;
}
} // namespace android

View File

@ -425,5 +425,16 @@ void HTTPDataSource::initHeaders(
}
}
uint32_t HTTPDataSource::flags() {
uint32_t f = kWantsPrefetching;
if (!strcasecmp(mStartingHost.string(), "localhost")
|| !strcmp(mStartingHost.string(), "127.0.0.1")) {
f |= kStreamedFromLocalHost;
}
return f;
}
} // namespace android

View File

@ -36,6 +36,10 @@ sp<MetaData> MediaExtractor::getMetaData() {
return new MetaData;
}
uint32_t MediaExtractor::flags() const {
return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE;
}
// static
sp<MediaExtractor> MediaExtractor::Create(
const sp<DataSource> &source, const char *mime) {

View File

@ -20,6 +20,7 @@
#include "include/VorbisExtractor.h"
#include <cutils/properties.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaBufferGroup.h>
@ -37,8 +38,23 @@ namespace android {
struct VorbisDataSource {
sp<DataSource> mDataSource;
off_t mOffset;
bool mSeekDisabled;
};
static bool ShouldDisableSeek(const sp<DataSource> &source) {
char value[PROPERTY_VALUE_MAX];
if (property_get("media.vorbis.always-allow-seek", value, NULL)
&& (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
return false;
}
// This is a workaround for an application streaming data through
// a local HTTP proxy that doesn't really conform to the HTTP/1.1
// specs. We have to disable seek functionality in this case.
return source->flags() & DataSource::kStreamedFromLocalHost;
}
static size_t VorbisRead(
void *ptr, size_t size, size_t nmemb, void *datasource) {
VorbisDataSource *vds = (VorbisDataSource *)datasource;
@ -58,6 +74,11 @@ static int VorbisSeek(
void *datasource, ogg_int64_t offset, int whence) {
VorbisDataSource *vds = (VorbisDataSource *)datasource;
if (vds->mSeekDisabled) {
errno = ESPIPE;
return -1;
}
switch (whence) {
case SEEK_SET:
vds->mOffset = offset;
@ -218,6 +239,7 @@ VorbisExtractor::VorbisExtractor(const sp<DataSource> &source)
mInitCheck(NO_INIT) {
mVorbisDataSource->mDataSource = mDataSource;
mVorbisDataSource->mOffset = 0;
mVorbisDataSource->mSeekDisabled = ShouldDisableSeek(mDataSource);
int res = ov_open_callbacks(
mVorbisDataSource, mFile, NULL, 0, gVorbisCallbacks);
@ -291,6 +313,7 @@ bool SniffVorbis(
VorbisDataSource vds;
vds.mDataSource = source;
vds.mOffset = 0;
vds.mSeekDisabled = ShouldDisableSeek(source);
int res = ov_test_callbacks(&vds, &file, NULL, 0, gVorbisCallbacks);
@ -308,4 +331,13 @@ bool SniffVorbis(
return true;
}
uint32_t VorbisExtractor::flags() const {
if (ShouldDisableSeek(mDataSource)) {
LOGI("This is streamed from local host, seek disabled");
return CAN_PAUSE;
} else {
return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE;
}
}
} // namespace android

View File

@ -84,10 +84,13 @@ struct AwesomePlayer {
status_t suspend();
status_t resume();
// This is a mask of MediaExtractor::Flags.
uint32_t flags() const;
private:
friend struct AwesomeEvent;
enum Flags {
enum {
PLAYING = 1,
LOOPING = 2,
FIRST_FRAME = 4,
@ -126,6 +129,7 @@ private:
int64_t mDurationUs;
uint32_t mFlags;
uint32_t mExtractorFlags;
int32_t mVideoWidth, mVideoHeight;
int64_t mTimeSourceDeltaUs;

View File

@ -38,6 +38,8 @@ struct VorbisExtractor : public MediaExtractor {
virtual sp<MetaData> getMetaData();
uint32_t flags() const;
protected:
virtual ~VorbisExtractor();