Files
android/proprietary/wvm/include/WVMMediaSource.h
John "Juce" Bruce 2e0e32f9f7 When Running in MediaCodec Mode, Widevine Freezes If You Rewind
There was a subtle interaction between Widevine's libraries and MediaCodec
mode.  Widevine's code assumed (erroneously) that video seeks would always
happen before audio seeks, and because we can't seek audio and video
independently from each other, we would ignore audio seeks but respect video
seeks.  This led to a problem since MediaCodec mode calls seeks in arbitrary
order.

Fix is to always respect the first request we get to seek and ignore the
second.

Bug: 6793514
Change-Id: Ic9ec60e0e0f606c7a0de6283dd4c30318eebdbad
2012-09-17 15:54:42 -07:00

116 lines
2.9 KiB
C++

/*
* Copyright (C) 2011 Google, Inc. All Rights Reserved
*/
#ifndef WVMMEDIA_SOURCE_H_
#define WVMMEDIA_SOURCE_H_
#include "AndroidConfig.h"
#include "WVStreamControlAPI.h"
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <utils/RefBase.h>
#include "ClientContext.h"
#ifdef REQUIRE_SECURE_BUFFERS
#include "OEMCrypto_L1.h"
#endif
namespace android {
class WVMFileSource;
class WVMMediaSource : public MediaSource {
public:
WVMMediaSource(WVSession *session, WVEsSelector esSelector,
const sp<MetaData> &metaData, bool isLive, bool cryptoPluginMode);
void delegateFileSource(sp<WVMFileSource> fileSource);
void delegateDataSource(sp<DataSource> dataSource);
void delegateClientContext(sp<ClientContext> context);
virtual status_t start(MetaData *params = NULL);
virtual status_t stop();
virtual sp<MetaData> getFormat();
virtual status_t setBuffers(const Vector<MediaBuffer *> &buffers);
virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL);
void addEncryptedSize(size_t size) { mEncryptedSizes.push_back(size); }
bool isStalled() const { return mIsStalled; }
static int sLastError;
int64_t getTime() { return mKeyTime; }; // usec.
static const int kCryptoBlockSize = 16;
class DecryptContext {
public:
void Initialize(MediaBuffer *mediaBuf) {
mMediaBuf = mediaBuf;
mOffset = 0;
memset(mIV, 0, sizeof(mIV));
}
MediaBuffer *mMediaBuf;
size_t mOffset;
unsigned char mIV[kCryptoBlockSize];
};
static void DecryptCallback(WVEsSelector esType, void* input, void* output, size_t length,
int key, void *context);
DecryptContext& getDecryptContext() { return mDecryptContext; }
void SetCryptoPluginKey(const char key[kCryptoBlockSize]) {
memcpy(mCryptoPluginKey, key, sizeof(mCryptoPluginKey));
}
protected:
virtual ~WVMMediaSource();
private:
static int64_t mLastSeekTimeUs;
Mutex mLock;
WVSession *mSession;
WVEsSelector mESSelector; // indicates audio vs. video
DecryptContext mDecryptContext;
sp<MetaData> mTrackMetaData;
bool mStarted;
bool mLogOnce;
bool mIsLiveStream;
bool mNewSegment;
bool mCryptoInitialized;
bool mIsStalled;
bool mStripADTS;
MediaBufferGroup *mGroup;
int64_t mKeyTime;
unsigned long long mDts;
unsigned long long mPts;
sp<WVMFileSource> mFileSource;
sp<DataSource> mDataSource;
sp<ClientContext> mClientContext;
Vector<size_t> mEncryptedSizes;
char mCryptoPluginKey[kCryptoBlockSize];
void allocBufferGroup();
WVMMediaSource(const WVMMediaSource &);
WVMMediaSource &operator=(const WVMMediaSource &);
};
} // namespace android
#endif // WVMMEDIA_SOURCE_H_