am ba5fa0ef: Fixes for b/4149416:expired license refresh, b/4126624:heartbeats, b/4171055: inconsistent license modes Also includes b/3500025: A/V resync issues

* commit 'ba5fa0ef570f6ca3524f8158a23371528930f0fc':
  Fixes for b/4149416:expired license refresh, b/4126624:heartbeats, b/4171055: inconsistent license modes Also includes b/3500025: A/V resync issues
This commit is contained in:
Jeffrey Tinker
2011-03-25 10:13:54 -07:00
committed by Android Git Automerger
13 changed files with 332 additions and 83 deletions

View File

@@ -52,11 +52,13 @@ class WVDRMPluginAPI {
virtual bool ProcessDrmInfo(std::string &assetPath, int playbackMode) = 0;
virtual int CheckRightsStatus(std::string &path) = 0;
virtual bool GetConstraints(std::string &path, uint32_t *timeSincePlayback,
uint32_t *timeRemaining,
uint32_t *licenseDuration, std::string &lastError,
bool &allowOffline, bool &allowStreaming,
bool &denyHD) = 0;
virtual bool SetPlaybackStatus(int playbackStatus, off64_t position) = 0;
virtual bool RemoveRights(std::string &path) = 0;
virtual bool RemoveAllRights() = 0;
@@ -67,10 +69,20 @@ class WVDRMPluginAPI {
EventType_AcquireDrmInfoFailed,
EventType_ProcessDrmInfoFailed,
EventType_RightsInstalled,
EventType_RightsRemoved
EventType_RightsRemoved,
EventType_HeartbeatServer,
EventType_HeartbeatPeriod
};
typedef void (*EventHandler)(EventType type, const std::string &path);
enum EventDestination {
EventDestination_JavaAPI,
EventDestination_MediaPlayer
};
// Returns true if event sent, false if no handler
typedef bool (*EventHandler)(EventType type, EventDestination destination,
const std::string &path);
virtual void SetEventHandler(EventHandler handler) = 0;
protected:

View File

@@ -100,10 +100,32 @@ protected:
ssize_t onPread(int uniqueId, DecryptHandle* decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset);
class Listener {
public:
Listener() : mListener(NULL), mUniqueId(-1) {}
Listener(IDrmEngine::OnInfoListener *listener, int uniqueId)
: mListener(listener), mUniqueId(uniqueId) {};
IDrmEngine::OnInfoListener *GetListener() const {return mListener;}
int GetUniqueId() const {return mUniqueId;}
private:
IDrmEngine::OnInfoListener *mListener;
int mUniqueId;
};
enum MessageType {
MessageType_HeartbeatServer = 4000,
MessageType_HeartbeatPeriod = 4001
};
private:
static void SendEvent(WVDRMPluginAPI::EventType code, const std::string &path);
static IDrmEngine::OnInfoListener *sOnInfoListener;
static int sUniqueId;
static bool SendEvent(WVDRMPluginAPI::EventType code, WVDRMPluginAPI::EventDestination dest,
const std::string &path);
static Vector<Listener> *sNativeListeners;
static Vector<Listener> *sJavaAPIListeners;
WVDRMPluginAPI *mDrmPluginImpl;
};

View File

@@ -47,17 +47,21 @@ extern "C" void destroy(IDrmEngine* pPlugIn) {
}
// Needed for event callout from implementation object
IDrmEngine::OnInfoListener *WVMDrmPlugin::sOnInfoListener = NULL;
int WVMDrmPlugin::sUniqueId;
Vector<WVMDrmPlugin::Listener> *WVMDrmPlugin::sNativeListeners = NULL;
Vector<WVMDrmPlugin::Listener> *WVMDrmPlugin::sJavaAPIListeners = NULL;
WVMDrmPlugin::WVMDrmPlugin()
: DrmEngineBase(),
mDrmPluginImpl(WVDRMPluginAPI::create())
{
sNativeListeners = new Vector<WVMDrmPlugin::Listener>();
sJavaAPIListeners = new Vector<WVMDrmPlugin::Listener>();
mDrmPluginImpl->SetEventHandler(&SendEvent);
}
WVMDrmPlugin::~WVMDrmPlugin() {
delete sNativeListeners;
delete sJavaAPIListeners;
WVDRMPluginAPI::destroy(mDrmPluginImpl);
}
@@ -86,6 +90,21 @@ status_t WVMDrmPlugin::onInitialize(int uniqueId) {
*/
status_t WVMDrmPlugin::onTerminate(int uniqueId) {
//LOGD("WVMDrmPlugin::onTerminate : %d", uniqueId);
for (size_t i = 0; i < sNativeListeners->size(); i++) {
if ((*sNativeListeners)[i].GetUniqueId() == uniqueId) {
sNativeListeners->removeAt(i);
break;
}
}
for (size_t i = 0; i < sJavaAPIListeners->size(); i++) {
if ((*sJavaAPIListeners)[i].GetUniqueId() == uniqueId) {
sJavaAPIListeners->removeAt(i);
break;
}
}
return DRM_NO_ERROR;
}
@@ -100,38 +119,90 @@ status_t WVMDrmPlugin::onTerminate(int uniqueId) {
*/
status_t WVMDrmPlugin::onSetOnInfoListener(
int uniqueId, const IDrmEngine::OnInfoListener* infoListener) {
//LOGD("WVMDrmPlugin::onSetOnInfoListener : %d", uniqueId);
sOnInfoListener = const_cast<IDrmEngine::OnInfoListener *>(infoListener);
sUniqueId = uniqueId;
//LOGD("WVMDrmPlugin::onSetOnInfoListener : add %d", uniqueId);
Listener newListener = Listener(const_cast<IDrmEngine::OnInfoListener *>(infoListener), uniqueId);
bool found = false;
const int maxNativeUniqueId = 100;
if (uniqueId <= maxNativeUniqueId) {
// Replace old listener for this id if it exists
for (size_t i = 0; i < sNativeListeners->size(); i++) {
if ((*sNativeListeners)[i].GetUniqueId() == uniqueId) {
sNativeListeners->replaceAt(newListener, i);
found = true;
break;
}
}
if (!found)
sNativeListeners->push(newListener);
} else {
// Replace old listener for this id if it exists
for (size_t i = 0; i < sJavaAPIListeners->size(); i++) {
if ((*sJavaAPIListeners)[i].GetUniqueId() == uniqueId) {
sJavaAPIListeners->replaceAt(newListener, i);
found = true;
break;
}
}
if (!found)
sJavaAPIListeners->push(newListener);
}
return DRM_NO_ERROR;
}
void WVMDrmPlugin::SendEvent(WVDRMPluginAPI::EventType type, const std::string &path)
bool WVMDrmPlugin::SendEvent(WVDRMPluginAPI::EventType type,
WVDRMPluginAPI::EventDestination destination,
const std::string &msg)
{
int code = -1;
bool result = false;
switch(type) {
EventType_AcquireFailed:
case WVDRMPluginAPI::EventType_AcquireDrmInfoFailed:
code = DrmInfoEvent::TYPE_ACQUIRE_DRM_INFO_FAILED;
break;
EventType_ProcessDrmInfoFailed:
case WVDRMPluginAPI::EventType_ProcessDrmInfoFailed:
code = DrmInfoEvent::TYPE_PROCESS_DRM_INFO_FAILED;
break;
EventType_RightsInstalled:
case WVDRMPluginAPI::EventType_RightsInstalled:
code = DrmInfoEvent::TYPE_RIGHTS_INSTALLED;
break;
EventType_RightsRemoved:
case WVDRMPluginAPI::EventType_RightsRemoved:
code = DrmInfoEvent::TYPE_RIGHTS_REMOVED;
break;
case WVDRMPluginAPI::EventType_HeartbeatServer:
code = MessageType_HeartbeatServer;
break;
case WVDRMPluginAPI::EventType_HeartbeatPeriod:
code = MessageType_HeartbeatPeriod;
break;
default:
break;
}
if (sOnInfoListener) {
String8 msg = String8(path.c_str());
DrmInfoEvent event(sUniqueId, code, msg);
sOnInfoListener->onInfo(event);
String8 message = String8(msg.c_str());
if (destination == WVDRMPluginAPI::EventDestination_JavaAPI) {
for (size_t i = 0; i < sJavaAPIListeners->size(); i++) {
DrmInfoEvent event((*sJavaAPIListeners)[i].GetUniqueId(), code, message);
//LOGD("WVMDrmPlugin::SendEvent [Java]: uniqueId=%d type=%d, code=%d, msg=%s",
// (*sJavaAPIListeners)[i].GetUniqueId(), type, code, msg.c_str());
(*sJavaAPIListeners)[i].GetListener()->onInfo(event);
}
result = true;
} else if (destination == WVDRMPluginAPI::EventDestination_MediaPlayer) {
for (size_t i = 0; i < sNativeListeners->size(); i++) {
DrmInfoEvent event((*sNativeListeners)[i].GetUniqueId(), code, message);
//LOGD("WVMDrmPlugin::SendEvent [Native]: uniqueId=%d type=%d, code=%d, msg=%s",
// (*sNativeListeners)[i].GetUniqueId(), type, code, msg.c_str());
(*sNativeListeners)[i].GetListener()->onInfo(event);
}
result = true;
}
return result;
}
/**
@@ -341,7 +412,7 @@ DrmConstraints* WVMDrmPlugin::onGetConstraints(int uniqueId, const String8* path
drmConstraints->put(&key, lastError.c_str());
if (isValid) {
char charValue[16]; // max uint32 = 0xffffffff + terminating char
char charValue[16]; // max uint32 + terminating char
memset(charValue, 0, 16);
sprintf(charValue, "%lu", (unsigned long)timeSincePlayback);
@@ -649,6 +720,7 @@ status_t WVMDrmPlugin::onOpenDecryptSession(
decryptHandle->decryptApiType = DecryptApiType::WV_BASED;
decryptHandle->status = DRM_NO_ERROR;
decryptHandle->decryptInfo = NULL;
mDrmPluginImpl->OpenSession();
result = DRM_NO_ERROR;
} else {
@@ -675,8 +747,6 @@ status_t WVMDrmPlugin::onOpenDecryptSession(
if (!uri)
return result;
size_t len = strlen(uri);
if (mDrmPluginImpl->IsSupportedMediaType(uri)) {
//LOGD("WVMDrmPlugin::onOpenDecryptSession(uri) : %d - match", uniqueId);
decryptHandle->mimeType = String8("video/wvm");
@@ -712,6 +782,7 @@ status_t WVMDrmPlugin::onCloseDecryptSession(int uniqueId, DecryptHandle* decryp
delete decryptHandle; decryptHandle = NULL;
}
mDrmPluginImpl->CloseSession();
return DRM_NO_ERROR;
}

View File

@@ -199,7 +199,7 @@ void WVMDrmPluginTest::TestGetConstraints(IDrmEngine *plugin, String8 &url, int
}
if (constraints->getCount() != 6) {
fprintf(stderr, "getConstraints returned unexpected count!\n");
fprintf(stderr, "getConstraints returned unexpected count: %d!\n", constraints->getCount());
exit(-1);
}

View File

@@ -470,6 +470,26 @@ WV_Setup(WVSession *&session, WVFileSource *source, const std::string &transport
CLIENT_API bool
WV_IsWidevineMedia(const char *buffer, size_t length);
//
// METHOD: WV_ConfigureHeartbeat
//
// Provides a method of configuring the heartbeat after WV_Setup has been
// called.
//
//
// Parameters:
// [in] heartbeatURL - the URL of the heartbeat server
// [in] heartbeatPeriod - the heartbeat interval in seconds
//
//
// Returns:
// WV_Status_OK on success, otherwise one of the WVStatus values
// indicating the specific error.
//
CLIENT_API WVStatus
WV_ConfigureHeartbeat(WVSession *session, std::string &heartbeatURL,
unsigned int heartbeatPeriod);
//
// METHOD: WV_Teardown
//
@@ -685,6 +705,9 @@ WV_GetData(WVSession *session, unsigned char *buffer, size_t request_size,
//
// [out] pts - On return, set to MPEG-2 access unit presentation timestamp (PTS)
//
// [out] sync_frame - On return, indicates whether the data belongs to a sync frame
// (video key frame, or audio frame).
//
// Returns:
// WV_Status_OK on success, otherwise one of the WVStatus values
// indicating the specific error.
@@ -692,7 +715,7 @@ WV_GetData(WVSession *session, unsigned char *buffer, size_t request_size,
CLIENT_API WVStatus
WV_GetEsData(WVSession *session, WVEsSelector es_selector,
unsigned char *buffer, size_t request_size, size_t& return_size,
bool& au_start, unsigned long long& dts, unsigned long long& pts);
bool& au_start, unsigned long long& dts, unsigned long long& pts, bool& sync_frame);
//

View File

@@ -8,7 +8,8 @@ LOCAL_SRC_FILES:= \
WVMLogging.cpp \
WVMExtractorImpl.cpp \
WVMFileSource.cpp \
WVMMediaSource.cpp
WVMMediaSource.cpp \
WVMInfoListener.cpp
LOCAL_C_INCLUDES:= \
bionic \

View File

@@ -20,11 +20,14 @@
#include "WVMExtractorImpl.h"
#include "WVMMediaSource.h"
#include "WVMFileSource.h"
#include "WVMInfoListener.h"
#include "WVMLogging.h"
#include "WVStreamControlAPI.h"
#include "media/stagefright/MediaErrors.h"
#include "media/stagefright/MediaDefs.h"
#include "drm/DrmManagerClient.h"
#include "drm/DrmConstraints.h"
#include "drm/DrmInfoEvent.h"
#include "AndroidHooks.h"
#define AES_BLOCK_SIZE 16
@@ -86,6 +89,8 @@ WVMExtractorImpl::WVMExtractorImpl(sp<DataSource> dataSource)
{
dataSource->getDrmInfo(sDecryptHandle, &sDrmManagerClient);
//LOGD("WVMExtractorImpl::WVMExtractorImpl: uniqueId = %d", sDrmManagerClient->mUniqueId);
_ah006(android_printbuf);
_ah002(_cb1);
_ah004(_cb2);
@@ -99,6 +104,16 @@ WVMExtractorImpl::WVMExtractorImpl(sp<DataSource> dataSource)
WVCredentials credentials;
// Set an info listener to handle messages from the drm plugin
mInfoListener = new WVMInfoListener();
// Change #if 0 to #if 1 to enable heartbeats. Since the heartbeat server
// is not yet returning valid responses, this will cause the player to
// fail with an error, until the heartbeat server is working correctly.
#if 0
sDrmManagerClient->setOnInfoListener(mInfoListener);
#endif
WVStatus result = WV_Initialize(NULL);
if (result != WV_Status_OK) {
LOGE("WV_Initialize returned status %d\n", result);
@@ -107,22 +122,17 @@ WVMExtractorImpl::WVMExtractorImpl(sp<DataSource> dataSource)
// Enable for debugging HTTP messages
// WV_SetLogging(WV_Logging_HTTP);
if (dataSource->getUri().size() == 0) {
// No URI supplied, pull data from the data source
mFileSource = new WVMFileSource(dataSource);
result = WV_Setup(mSession, mFileSource.get(),
"RAW/RAW/RAW;destination=getdata", credentials,
WV_OutputFormat_ES, kStreamCacheSize);
} else {
// Use the URI
result = WV_Setup(mSession, dataSource->getUri().string(),
"RAW/RAW/RAW;destination=getdata", credentials,
WV_OutputFormat_ES, kStreamCacheSize);
}
if (result != WV_Status_OK) {
LOGE("WV_Setup returned status %d in WVMMediaSource::start\n", result);
mSetupStatus = ERROR_IO;
}
mInfoListener->setSession(mSession);
}
WV_SetWarningToErrorMS(5000);
@@ -241,6 +251,8 @@ status_t WVMExtractorImpl::readMetaData()
mHaveMetaData = true;
mInfoListener->configureHeartbeat();
return OK;
}
@@ -253,7 +265,7 @@ status_t WVMExtractorImpl::readAVCCMetaData(sp<MetaData> videoMetaData)
int limit = 50;
do {
size_t bytesRead;
bool auStart;
bool auStart, sync;
unsigned long long dts, pts;
unsigned char buf[1];
size_t bufSize = 0;
@@ -263,7 +275,7 @@ status_t WVMExtractorImpl::readAVCCMetaData(sp<MetaData> videoMetaData)
// pull some video data. But we can't use it yet, so just request 0 bytes.
//
(void)WV_GetEsData(mSession, WV_EsSelector_Video, buf, bufSize,
bytesRead, auStart, dts, pts);
bytesRead, auStart, dts, pts, sync);
result = WV_Info_GetCodecConfig(mSession, WV_CodecConfigType_AVCC, config, size);
if (result != WV_Status_OK)
@@ -286,28 +298,7 @@ status_t WVMExtractorImpl::readAVCCMetaData(sp<MetaData> videoMetaData)
}
#endif
#if 0
unsigned char mp4_force[] =
{ 0x01, 0x42, 0x00, 0x1e, 0xff, 0xe1, 0x00, 0x1b, 0x67, 0x42, 0x80, 0x1e, 0x96, 0x52, 0x01, 0x40,
0x5f, 0xf3, 0x60, 0x2a, 0x10, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0x09, 0xda,
0x14, 0x2a, 0x48, 0x01, 0x00, 0x04, 0x68, 0xcb, 0x8d, 0x48 } ;
unsigned char wvm_force[] =
{ 0x01, 0x42, 0x80, 0x1e, 0xff, 0xe1, 0x00, 0x1c, 0x67, 0x42, 0x80, 0x1e, 0x96, 0x52, 0x01, 0x40,
0x5f, 0xf3, 0x60, 0x2a, 0x10, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0x09, 0xda,
0x14, 0x2a, 0x48, 0x00, 0x01, 0x00, 0x05, 0x68, 0xcb, 0x8d, 0x48, 0x00 } ;
unsigned char wvm_force_no_zero[] =
{ 0x01, 0x42, 0x80, 0x1e, 0xff, 0xe1, 0x00, 0x1b, 0x67, 0x42, 0x80, 0x1e, 0x96, 0x52, 0x01, 0x40,
0x5f, 0xf3, 0x60, 0x2a, 0x10, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0x09, 0xda,
0x14, 0x2a, 0x48, 0x01, 0x00, 0x04, 0x68, 0xcb, 0x8d, 0x48 } ;
unsigned char wvm_force_modprof[] =
{ 0x01, 0x42, 0x00, 0x1e, 0xff, 0xe1, 0x00, 0x1c, 0x67, 0x42, 0x80, 0x1e, 0x96, 0x52, 0x01, 0x40,
0x5f, 0xf3, 0x60, 0x2a, 0x10, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0x09, 0xda,
0x14, 0x2a, 0x48, 0x00, 0x01, 0x00, 0x05, 0x68, 0xcb, 0x8d, 0x48, 0x00 } ;
videoMetaData->setData(kKeyAVCC, kTypeAVCC, wvm_force_no_zero, sizeof(wvm_force_no_zero));
#else
videoMetaData->setData(kKeyAVCC, kTypeAVCC, config, size);
#endif
return OK;
}
@@ -320,7 +311,7 @@ status_t WVMExtractorImpl::readESDSMetaData(sp<MetaData> audioMetaData)
int limit = 50;
do {
size_t bytesRead;
bool auStart;
bool auStart, sync;
unsigned long long dts, pts;
unsigned char buf[1];
size_t bufSize = 0;
@@ -330,7 +321,7 @@ status_t WVMExtractorImpl::readESDSMetaData(sp<MetaData> audioMetaData)
// pull some audio data. But we can't use it yet, so just request 0 bytes.
//
(void)WV_GetEsData(mSession, WV_EsSelector_Audio, buf, bufSize,
bytesRead, auStart, dts, pts);
bytesRead, auStart, dts, pts, sync);
result = WV_Info_GetCodecConfig(mSession, WV_CodecConfigType_ESDS, config, size);
if (result != WV_Status_OK)

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "WVMInfoListener"
#include <utils/Log.h>
#include "WVMExtractorImpl.h"
#include "WVMMediaSource.h"
#include "WVMFileSource.h"
#include "WVMInfoListener.h"
#include "WVMLogging.h"
#include "WVStreamControlAPI.h"
#include "media/stagefright/MediaErrors.h"
#include "media/stagefright/MediaDefs.h"
#include "drm/DrmInfoEvent.h"
namespace android {
void WVMInfoListener::setSession(WVSession *session)
{
mSession = session;
}
void WVMInfoListener::onInfo(const DrmInfoEvent &event)
{
//LOGD("WVMMediaSource::onInfo: type=%d, msg=%s!!!",
// event.getType(), event.getMessage().string());
if (event.getType() == MessageType_HeartbeatServer)
mServerUrl = event.getMessage();
else if (event.getType() == MessageType_HeartbeatPeriod)
mPeriod = atoi(event.getMessage());
}
void WVMInfoListener::configureHeartbeat()
{
// send the first time we have all the info
if (mSession && mServerUrl.size() && mPeriod != -1) {
//LOGD("WVMMediaSource::calling WV_ConfigureHeartbeat()");
WV_ConfigureHeartbeat(mSession, mServerUrl, mPeriod);
mSession = NULL;
}
}
};

View File

@@ -32,8 +32,6 @@ static void _cb(int code)
WVMMediaSource::sLastError = (status_t)code;
}
extern DrmManagerClient *gDrmManagerClient;
status_t WVMMediaSource::sLastError = NO_ERROR;
WVMMediaSource::WVMMediaSource(WVSession *session, WVEsSelector esSelector,
@@ -156,10 +154,19 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options)
CHECK(mStarted);
*buffer = NULL;
bool seekNextSync = false;
int64_t seekTimeUs;
ReadOptions::SeekMode mode;
if (options && options->getSeekTo(&seekTimeUs, &mode)) {
//LOGD("%s seek mode=%d, seek time=%lld lateby=%lld",
// (mESSelector == WV_EsSelector_Video) ? "video" : "audio",
// mode, seekTimeUs, options->getLateBy());
if (mode == ReadOptions::SEEK_NEXT_SYNC) {
// Handle seek next sync by dropping frames on this track that are
// prior to the specified time.
seekNextSync = true;
} else {
// Let video stream control seek
if (mESSelector == WV_EsSelector_Video) {
float scaleUsed;
@@ -171,6 +178,7 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options)
}
}
}
}
MediaBuffer *mediaBuf;
@@ -184,17 +192,20 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options)
size_t bytesRead;
bool auStart;
size_t offset = 0;
int64_t keyTime;
bool syncFrame;
// Pull full access units. Since we aren't sure how big they might be,
// start with initial buffer size, then allocate a larger buffer if we
// get more a number of bytes equal to the full buffer size and go back
// get a number of bytes equal to the full buffer size and go back
// for the rest. Only loop in this case, usually it's one pass through.
while (true) {
size_t size = mediaBuf->size() - offset;
WVStatus result = WV_GetEsData(mSession, mESSelector, (uint8_t *)mediaBuf->data() + offset,
size, bytesRead, auStart, mDts, mPts);
size, bytesRead, auStart, mDts, mPts, syncFrame);
if (result == WV_Status_End_Of_Media) {
mediaBuf->release();
return ERROR_END_OF_STREAM;
@@ -222,8 +233,16 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options)
}
if (bytesRead == 0) {
// Didn't get anything, sleep a bit so we don't hog the CPU then
// try again.
// Didn't get anything, sleep a bit so we don't hog the CPU then try again
usleep(10000);
continue;
}
#define PCR_HZ 90000
keyTime = (int64_t)mPts * 1000000 / PCR_HZ;
if (seekNextSync && ((keyTime < seekTimeUs) || !syncFrame)) {
// drop frames up to next sync if requested
usleep(10000);
continue;
}
@@ -249,9 +268,6 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options)
mediaBuf = newBuffer;
}
#define PCR_HZ 90000
int64_t keyTime = (int64_t)mDts * 1000000 / PCR_HZ;
mediaBuf->meta_data()->clear();
mediaBuf->meta_data()->setInt64(kKeyTime, keyTime);
@@ -277,9 +293,9 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options)
#endif
#if 0
LOGD("[%p] %s set range_length=%d, get range_length=%d kKeyTime=%lld\n", mediaBuf,
LOGD("[%p] %s set range_length=%d, get range_length=%d kKeyTime=%lld sync=%d\n", mediaBuf,
(mESSelector == WV_EsSelector_Video ? "video" : "audio"),
bytesRead + offset, mediaBuf->range_length(), keyTime);
bytesRead + offset, mediaBuf->range_length(), keyTime, syncFrame);
#endif
*buffer = mediaBuf;

View File

@@ -20,6 +20,7 @@
#include "AndroidConfig.h"
#include "WVStreamControlAPI.h"
#include "WVMInfoListener.h"
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/DataSource.h>
#include <utils/RefBase.h>
@@ -59,6 +60,7 @@ private:
sp<MetaData> mFileMetaData;
sp<WVMFileSource> mFileSource;
sp<DataSource> mDataSource;
sp<WVMInfoListener> mInfoListener;
bool mHaveMetaData;

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WVMINFO_LISTENER_H
#define WVMINFO_LISTENER_H
#include "AndroidConfig.h"
#include "WVMMediaSource.h"
#include <media/stagefright/DataSource.h>
#include "WVStreamControlAPI.h"
#include <utils/RefBase.h>
namespace android {
// Handles messages from the DRM plugin
class WVMInfoListener : public DrmManagerClient::OnInfoListener {
enum MessageType {
MessageType_HeartbeatServer = 4000,
MessageType_HeartbeatPeriod = 4001
};
public:
WVMInfoListener() : mPeriod(-1) {};
virtual void onInfo(const DrmInfoEvent &event);
void setSession(WVSession *session);
void configureHeartbeat();
private:
WVSession *mSession;
std::string mServerUrl;
int mPeriod;
};
} // namespace android
#endif // WVMINFO_LISTENER_H