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:
@ -33,7 +33,8 @@ class String8;
|
||||
class DataSource : public RefBase {
|
||||
public:
|
||||
enum Flags {
|
||||
kWantsPrefetching = 1,
|
||||
kWantsPrefetching = 1,
|
||||
kStreamedFromLocalHost = 2,
|
||||
};
|
||||
|
||||
static sp<DataSource> CreateFromURI(
|
||||
|
@ -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();
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -38,6 +38,8 @@ struct VorbisExtractor : public MediaExtractor {
|
||||
|
||||
virtual sp<MetaData> getMetaData();
|
||||
|
||||
uint32_t flags() const;
|
||||
|
||||
protected:
|
||||
virtual ~VorbisExtractor();
|
||||
|
||||
|
Reference in New Issue
Block a user