Add getError and setError to propagate error code from WVMMediaExtractor up to player.

Error code from the plugin is not propagated from WVMExtractorImpl.cpp to the MediaPlayer.
The two APIs addresses this issue and provide a path for the player to retrieve the last error.

Change-Id: I60040eaf2d396379eecca46bfe333c44a39c35ec
related-to-bug: 7073630
This commit is contained in:
Edwin Wong
2012-09-06 13:46:34 -07:00
parent d3c2b6f098
commit d72b67cdeb
2 changed files with 79 additions and 18 deletions

View File

@@ -48,15 +48,17 @@ static int _cb2(char *in, char *out, int length, char *iv)
DrmBuffer *decryptedDrmBufferPtr = &decryptedDrmBuffer;
char ivout[AES_BLOCK_SIZE];
if (in && length)
if (in && length) {
memcpy(ivout, in + length - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
}
status = sDrmManagerClient->decrypt(sDecryptHandle, 0,
&encryptedDrmBuffer, &decryptedDrmBufferPtr,
&ivBuffer);
if (iv)
if (iv) {
memcpy(iv, ivout, AES_BLOCK_SIZE);
}
}
return status;
@@ -100,6 +102,7 @@ WVMExtractorImpl::WVMExtractorImpl(sp<DataSource> dataSource)
mIsLiveStream(false),
mSession(NULL),
mDuration(0),
mError(OK),
mSetupStatus(OK)
{
dataSource->getDrmInfo(sDecryptHandle, &sDrmManagerClient);
@@ -114,8 +117,9 @@ WVMExtractorImpl::WVMExtractorImpl(sp<DataSource> dataSource)
if (sDecryptHandle->status != RightsStatus::RIGHTS_VALID) {
mSetupStatus = ERROR_DRM_NO_LICENSE;
}
} else
} else {
mSetupStatus = ERROR_DRM_NO_LICENSE;
}
// Set an info listener to handle messages from the drm plugin
mInfoListener = new WVMInfoListener();
@@ -129,6 +133,11 @@ void WVMExtractorImpl::Initialize()
WVCredentials credentials;
WVStatus result;
if (mSetupStatus != OK) {
setError(mSetupStatus);
return;
}
if (mDataSource->getUri().size() > 0 && getAdaptiveStreamingMode()) {
mIsLiveStream = (mDataSource->getUri().getPathExtension().find(".m3u8") == 0);
}
@@ -179,6 +188,10 @@ void WVMExtractorImpl::Initialize()
}
}
if (mSetupStatus != OK) {
setError(mSetupStatus);
}
WV_SetWarningToErrorMS(10000);
}
@@ -227,13 +240,15 @@ void WVMExtractorImpl::SocketInfoCallback(int fd, int closing, void *context)
//
status_t WVMExtractorImpl::readMetaData()
{
if (mHaveMetaData)
if (mHaveMetaData) {
return OK;
}
Initialize();
if (mSetupStatus != OK)
if (mSetupStatus != OK) {
return mSetupStatus;
}
// Get Video Configuration
WVVideoType videoType;
@@ -247,8 +262,9 @@ status_t WVMExtractorImpl::readMetaData()
WVStatus result = WV_Info_GetVideoConfiguration(mSession, &videoType, &videoStreamID,
&videoProfile, &level, &width, &height,
&aspect, &frameRate, &videoBitRate);
if (result != WV_Status_OK)
if (result != WV_Status_OK) {
return ERROR_MALFORMED;
}
// Get Audio Configuration
WVAudioType audioType;
@@ -260,8 +276,9 @@ status_t WVMExtractorImpl::readMetaData()
result = WV_Info_GetAudioConfiguration(mSession, &audioType, &audioStreamID, &audioProfile,
&numChannels, &sampleRate, &audioBitRate);
if (result != WV_Status_OK)
if (result != WV_Status_OK) {
return ERROR_MALFORMED;
}
if (numChannels == 0) {
ALOGD("numChannels is 0!");
@@ -272,10 +289,11 @@ status_t WVMExtractorImpl::readMetaData()
if (durationString == "") {
// We won't have a duration for live streams, and Stagefright doesn't seem to
// have a way to represent that. Give a default duration of 1 hour for now.
if (mIsLiveStream)
if (mIsLiveStream) {
durationString = "3600";
else
} else {
return ERROR_MALFORMED;
}
}
mDuration = (int64_t)(strtod(durationString.c_str(), NULL) * 1000000);
@@ -328,8 +346,9 @@ status_t WVMExtractorImpl::readMetaData()
status_t status;
status = readESDSMetaData(audioMetaData);
if (status != OK)
if (status != OK) {
return status;
}
if (mIsLiveStream) {
result = WV_Pause(mSession, "");
@@ -347,8 +366,9 @@ status_t WVMExtractorImpl::readMetaData()
// Since the WVExtractor goes away soon after this, we delegate ownership of some resources
// to the constructed media source
if (mFileSource.get())
if (mFileSource.get()) {
mVideoSource->delegateFileSource(mFileSource);
}
mVideoSource->delegateDataSource(mDataSource);
@@ -411,8 +431,9 @@ status_t WVMExtractorImpl::readESDSMetaData(sp<MetaData> audioMetaData)
bytesRead, auStart, dts, pts, sync);
result = WV_Info_GetCodecConfig(mSession, WV_CodecConfigType_ESDS, config, size);
if (result != WV_Status_OK)
if (result != WV_Status_OK) {
usleep(10000);
}
} while (result == WV_Status_Warning_Not_Available && limit-- > 0);
if (result != WV_Status_OK) {
@@ -423,9 +444,9 @@ status_t WVMExtractorImpl::readESDSMetaData(sp<MetaData> audioMetaData)
#if 0
char *filename = "/data/wvm/esds";
FILE *f = fopen(filename, "w");
if (!f)
if (!f) {
ALOGD("Failed to open %s", filename);
else {
} else {
fwrite(config, size, 1, f);
fclose(f);
}
@@ -437,6 +458,7 @@ status_t WVMExtractorImpl::readESDSMetaData(sp<MetaData> audioMetaData)
size_t WVMExtractorImpl::countTracks() {
status_t err;
if ((err = readMetaData()) != OK) {
setError(err);
return 0;
}
@@ -447,6 +469,7 @@ sp<MediaSource> WVMExtractorImpl::getTrack(size_t index)
{
status_t err;
if ((err = readMetaData()) != OK) {
setError(err);
return NULL;
}
@@ -470,18 +493,21 @@ sp<MetaData> WVMExtractorImpl::getTrackMetaData(size_t index, uint32_t flags)
{
status_t err;
if ((err = readMetaData()) != OK) {
setError(err);
return NULL;
}
sp<MetaData> result;
switch(index) {
case 0:
if (mVideoSource != NULL)
if (mVideoSource != NULL) {
result = mVideoSource->getFormat();
}
break;
case 1:
if (mAudioSource != NULL)
if (mAudioSource != NULL) {
result = mAudioSource->getFormat();
}
break;
default:
break;
@@ -553,7 +579,6 @@ int64_t WVMExtractorImpl::getCachedDurationUs(status_t *finalStatus) {
}
}
}
return durationUs;
}
@@ -604,4 +629,33 @@ size_t WVMExtractorImpl::getStreamCacheSize() const
return atol(value);
}
status_t WVMExtractorImpl::getError() {
Mutex::Autolock autoLock(mLock);
status_t err = mError;
mError = OK;
//
// MediaPlayer.java documents these MEDIA_ERROR codes for applications:
// MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_SERVER_DIED, MEDIA_ERROR_IO,
// MEDIA_ERROR_MALFORMED, MEDIA_ERROR_UNSUPPORTED and MEDIA_ERROR_TIMED_OUT.
// In order to not change the behavior of WVMExtractorImpl.cpp,
// we return all ERROR_ codes used by the WVMExtractor in addition to
// those documented in MediaPlayer.java.
//
if (err == ERROR_DRM_NO_LICENSE || err == ERROR_END_OF_STREAM ||
err == ERROR_IO || err == ERROR_MALFORMED || err == OK ||
err == ERROR_UNSUPPORTED) {
return err;
} else {
return UNKNOWN_ERROR;
}
}
void WVMExtractorImpl::setError(status_t err) {
Mutex::Autolock autoLock(mLock);
mError = err;
}
} // namespace android

View File

@@ -13,7 +13,6 @@
#include <media/stagefright/DataSource.h>
#include <utils/RefBase.h>
// DLL entry - given a data source, instantiate a WVMExtractor object
namespace android {
@@ -52,11 +51,17 @@ public:
static void SocketInfoCallback(int fd, int op, void *context);
static void cleanup();
status_t getError() ;
void setError(status_t err);
protected:
virtual ~WVMExtractorImpl();
void Initialize();
private:
Mutex mLock;
status_t readAVCCMetaData(sp<MetaData> videoMetaData);
status_t readESDSMetaData(sp<MetaData> audioMetaData);
@@ -77,6 +82,8 @@ private:
int64_t mDuration; // usec.
status_t mError;
status_t mSetupStatus;
status_t readMetaData();