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:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user