Merge "Using widevine:// to stream adaptive bitrate wvm content no longer" into honeycomb-mr2

This commit is contained in:
James Dong
2011-05-18 16:06:14 -07:00
committed by Android (Google) Code Review
4 changed files with 161 additions and 35 deletions

View File

@@ -24,10 +24,12 @@
#include "include/ARTSPController.h"
#include "include/AwesomePlayer.h"
#include "include/DRMExtractor.h"
#include "include/SoftwareRenderer.h"
#include "include/NuCachedSource2.h"
#include "include/ThrottledSource.h"
#include "include/MPEG2TSExtractor.h"
#include "include/WVMExtractor.h"
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -447,6 +449,7 @@ void AwesomePlayer::reset_l() {
cancelPlayerEvents();
mWVMExtractor.clear();
mCachedSource.clear();
mAudioTrack.clear();
mVideoTrack.clear();
@@ -554,6 +557,11 @@ bool AwesomePlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) {
*durationUs = cachedDataRemaining * 8000000ll / bitrate;
*eos = (finalStatus != OK);
return true;
} else if (mWVMExtractor != NULL) {
status_t finalStatus;
*durationUs = mWVMExtractor->getCachedDurationUs(&finalStatus);
*eos = (finalStatus != OK);
return true;
}
return false;
@@ -646,6 +654,30 @@ void AwesomePlayer::onBufferingUpdate() {
}
}
}
} else if (mWVMExtractor != NULL) {
status_t finalStatus;
int64_t cachedDurationUs
= mWVMExtractor->getCachedDurationUs(&finalStatus);
bool eos = (finalStatus != OK);
if (eos) {
if (finalStatus == ERROR_END_OF_STREAM) {
notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
}
if (mFlags & PREPARING) {
LOGV("cache has reached EOS, prepare is done.");
finishAsyncPrepare_l();
}
} else {
int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
if (percentage > 100) {
percentage = 100;
}
notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
}
}
int64_t cachedDurationUs;
@@ -1320,7 +1352,7 @@ void AwesomePlayer::onVideoEvent() {
mVideoBuffer = NULL;
}
if (mSeeking == SEEK && mCachedSource != NULL && mAudioSource != NULL
if (mSeeking == SEEK && isStreamingHTTP() && mAudioSource != NULL
&& !(mFlags & SEEK_PREVIEW)) {
// We're going to seek the video source first, followed by
// the audio source.
@@ -1654,8 +1686,19 @@ status_t AwesomePlayer::prepareAsync_l() {
status_t AwesomePlayer::finishSetDataSource_l() {
sp<DataSource> dataSource;
bool isWidevineStreaming = false;
if (!strncasecmp("widevine://", mUri.string(), 11)) {
isWidevineStreaming = true;
String8 newURI = String8("http://");
newURI.append(mUri.string() + 11);
mUri = newURI;
}
if (!strncasecmp("http://", mUri.string(), 7)
|| !strncasecmp("https://", mUri.string(), 8)) {
|| !strncasecmp("https://", mUri.string(), 8)
|| isWidevineStreaming) {
mConnectingDataSource = new NuHTTPDataSource(
(mFlags & INCOGNITO) ? NuHTTPDataSource::kFlagIncognito : 0);
@@ -1670,39 +1713,48 @@ status_t AwesomePlayer::finishSetDataSource_l() {
return err;
}
if (!isWidevineStreaming) {
// The widevine extractor does its own caching.
#if 0
mCachedSource = new NuCachedSource2(
new ThrottledSource(
mConnectingDataSource, 50 * 1024 /* bytes/sec */));
mCachedSource = new NuCachedSource2(
new ThrottledSource(
mConnectingDataSource, 50 * 1024 /* bytes/sec */));
#else
mCachedSource = new NuCachedSource2(mConnectingDataSource);
mCachedSource = new NuCachedSource2(mConnectingDataSource);
#endif
mConnectingDataSource.clear();
dataSource = mCachedSource;
// We're going to prefill the cache before trying to instantiate
// the extractor below, as the latter is an operation that otherwise
// could block on the datasource for a significant amount of time.
// During that time we'd be unable to abort the preparation phase
// without this prefill.
mLock.unlock();
for (;;) {
status_t finalStatus;
size_t cachedDataRemaining =
mCachedSource->approxDataRemaining(&finalStatus);
if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
|| (mFlags & PREPARE_CANCELLED)) {
break;
}
usleep(200000);
dataSource = mCachedSource;
} else {
dataSource = mConnectingDataSource;
}
mLock.lock();
mConnectingDataSource.clear();
if (mCachedSource != NULL) {
// We're going to prefill the cache before trying to instantiate
// the extractor below, as the latter is an operation that otherwise
// could block on the datasource for a significant amount of time.
// During that time we'd be unable to abort the preparation phase
// without this prefill.
mLock.unlock();
for (;;) {
status_t finalStatus;
size_t cachedDataRemaining =
mCachedSource->approxDataRemaining(&finalStatus);
if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
|| (mFlags & PREPARE_CANCELLED)) {
break;
}
usleep(200000);
}
mLock.lock();
}
if (mFlags & PREPARE_CANCELLED) {
LOGI("Prepare cancelled while waiting for initial cache fill.");
@@ -1740,10 +1792,29 @@ status_t AwesomePlayer::finishSetDataSource_l() {
return UNKNOWN_ERROR;
}
sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
sp<MediaExtractor> extractor;
if (extractor == NULL) {
return UNKNOWN_ERROR;
if (isWidevineStreaming) {
String8 mimeType;
float confidence;
sp<AMessage> dummy;
bool success = SniffDRM(dataSource, &mimeType, &confidence, &dummy);
if (!success
|| strcasecmp(
mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
return ERROR_UNSUPPORTED;
}
mWVMExtractor = new WVMExtractor(dataSource);
mWVMExtractor->setAdaptiveStreamingMode(true);
extractor = mWVMExtractor;
} else {
extractor = MediaExtractor::Create(dataSource);
if (extractor == NULL) {
return UNKNOWN_ERROR;
}
}
dataSource->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
@@ -1754,7 +1825,15 @@ status_t AwesomePlayer::finishSetDataSource_l() {
}
}
return setDataSource_l(extractor);
status_t err = setDataSource_l(extractor);
if (err != OK) {
mWVMExtractor.clear();
return err;
}
return OK;
}
void AwesomePlayer::abortPrepare(status_t err) {
@@ -1815,7 +1894,7 @@ void AwesomePlayer::onPrepareAsyncEvent() {
mFlags |= PREPARING_CONNECTED;
if (mCachedSource != NULL || mRTSPController != NULL) {
if (isStreamingHTTP() || mRTSPController != NULL) {
postBufferingEvent_l();
} else {
finishAsyncPrepare_l();
@@ -1852,4 +1931,8 @@ void AwesomePlayer::postAudioSeekComplete() {
postCheckAudioStatusEvent_l();
}
bool AwesomePlayer::isStreamingHTTP() const {
return mCachedSource != NULL || mWVMExtractor != NULL;
}
} // namespace android

View File

@@ -45,7 +45,8 @@ namespace android {
static Mutex gWVMutex;
WVMExtractor::WVMExtractor(const sp<DataSource> &source)
: mDataSource(source) {
: mDataSource(source),
mUseAdaptiveStreaming(false) {
{
Mutex::Autolock autoLock(gWVMutex);
if (gVendorLibHandle == NULL) {
@@ -100,5 +101,21 @@ sp<MetaData> WVMExtractor::getMetaData() {
return mImpl->getMetaData();
}
int64_t WVMExtractor::getCachedDurationUs(status_t *finalStatus) {
// TODO: Fill this with life.
*finalStatus = OK;
return 0;
}
void WVMExtractor::setAdaptiveStreamingMode(bool adaptive) {
mUseAdaptiveStreaming = adaptive;
}
bool WVMExtractor::getAdaptiveStreamingMode() const {
return mUseAdaptiveStreaming;
}
} //namespace android

View File

@@ -44,6 +44,8 @@ struct ARTSPController;
class DrmManagerClinet;
class DecryptHandle;
struct WVMExtractor;
struct AwesomeRenderer : public RefBase {
AwesomeRenderer() {}
@@ -219,6 +221,8 @@ private:
DrmManagerClient *mDrmManagerClient;
DecryptHandle *mDecryptHandle;
sp<WVMExtractor> mWVMExtractor;
status_t setDataSource_l(
const char *uri,
const KeyedVector<String8, String8> *headers = NULL);
@@ -268,6 +272,8 @@ private:
status_t startAudioPlayer_l();
bool isStreamingHTTP() const;
AwesomePlayer(const AwesomePlayer &);
AwesomePlayer &operator=(const AwesomePlayer &);
};

View File

@@ -19,6 +19,7 @@
#define WVM_EXTRACTOR_H_
#include <media/stagefright/MediaExtractor.h>
#include <utils/Errors.h>
namespace android {
@@ -33,12 +34,31 @@ public:
virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
virtual sp<MetaData> getMetaData();
// Return the amount of data cached from the current
// playback positiion (in us).
// While more data is still being fetched *finalStatus == OK,
// Once fetching is completed (no more data available), *finalStatus != OK
// If fetching completed normally (i.e. reached EOS instead of IO error)
// *finalStatus == ERROR_END_OF_STREAM
int64_t getCachedDurationUs(status_t *finalStatus);
// Set to use adaptive streaming mode by the WV component.
// If adaptive == true, adaptive streaming mode will be used.
// Default mode is non-adaptive streaming mode.
// Should set to use adaptive streaming mode only if widevine:// protocol
// is used.
void setAdaptiveStreamingMode(bool adaptive);
// Retrieve the adaptive streaming mode used by the WV component.
bool getAdaptiveStreamingMode() const;
protected:
virtual ~WVMExtractor();
private:
sp<DataSource> mDataSource;
sp<MediaExtractor> mImpl;
bool mUseAdaptiveStreaming;
WVMExtractor(const WVMExtractor &);
WVMExtractor &operator=(const WVMExtractor &);