summaryrefslogtreecommitdiffstats
path: root/libvideoeditor/lvpp
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2012-01-13 17:34:42 -0800
committerJames Dong <jdong@google.com>2012-01-19 17:29:53 -0800
commit00f742c087d92e5452d29be1fb668022b5f8a6c7 (patch)
treedc3de13666176b2d17655b8719af93f5b3197252 /libvideoeditor/lvpp
parent7a4097cc526fc25a36e0f451613340a9444ca043 (diff)
downloadframeworks_av-00f742c087d92e5452d29be1fb668022b5f8a6c7.zip
frameworks_av-00f742c087d92e5452d29be1fb668022b5f8a6c7.tar.gz
frameworks_av-00f742c087d92e5452d29be1fb668022b5f8a6c7.tar.bz2
More source code Clean up in video editor engine
o fixed incorrect design and got rid of PreviewPlayerBase class o removed obsolete/unused code as much as possible and reformatted the source code o verified and passed functional tests o More to come ... Change-Id: I7a89162f8b9d9ea6eabcf0457366cd2f6d970d11
Diffstat (limited to 'libvideoeditor/lvpp')
-rwxr-xr-xlibvideoeditor/lvpp/Android.mk1
-rw-r--r--libvideoeditor/lvpp/AudioPlayerBase.cpp4
-rw-r--r--libvideoeditor/lvpp/AudioPlayerBase.h6
-rwxr-xr-xlibvideoeditor/lvpp/DummyAudioSource.cpp154
-rwxr-xr-xlibvideoeditor/lvpp/DummyAudioSource.h35
-rwxr-xr-xlibvideoeditor/lvpp/DummyVideoSource.cpp118
-rwxr-xr-xlibvideoeditor/lvpp/DummyVideoSource.h28
-rwxr-xr-xlibvideoeditor/lvpp/PreviewPlayer.cpp767
-rwxr-xr-xlibvideoeditor/lvpp/PreviewPlayer.h170
-rw-r--r--libvideoeditor/lvpp/PreviewPlayerBase.cpp1456
-rw-r--r--libvideoeditor/lvpp/PreviewPlayerBase.h244
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorAudioPlayer.cpp4
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorAudioPlayer.h6
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorPlayer.cpp2
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorSRC.cpp60
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorSRC.h80
16 files changed, 1026 insertions, 2109 deletions
diff --git a/libvideoeditor/lvpp/Android.mk b/libvideoeditor/lvpp/Android.mk
index e2d8417..db6cb48 100755
--- a/libvideoeditor/lvpp/Android.mk
+++ b/libvideoeditor/lvpp/Android.mk
@@ -35,7 +35,6 @@ LOCAL_SRC_FILES:= \
DummyVideoSource.cpp \
VideoEditorBGAudioProcessing.cpp \
AudioPlayerBase.cpp \
- PreviewPlayerBase.cpp \
PreviewRenderer.cpp \
I420ColorConverter.cpp \
NativeWindowRenderer.cpp
diff --git a/libvideoeditor/lvpp/AudioPlayerBase.cpp b/libvideoeditor/lvpp/AudioPlayerBase.cpp
index b45f9bf..67ea43c 100644
--- a/libvideoeditor/lvpp/AudioPlayerBase.cpp
+++ b/libvideoeditor/lvpp/AudioPlayerBase.cpp
@@ -27,13 +27,13 @@
#include <media/stagefright/MetaData.h>
#include "AudioPlayerBase.h"
-#include "PreviewPlayerBase.h"
+#include "PreviewPlayer.h"
namespace android {
AudioPlayerBase::AudioPlayerBase(
const sp<MediaPlayerBase::AudioSink> &audioSink,
- PreviewPlayerBase *observer)
+ PreviewPlayer *observer)
: mAudioTrack(NULL),
mInputBuffer(NULL),
mSampleRate(0),
diff --git a/libvideoeditor/lvpp/AudioPlayerBase.h b/libvideoeditor/lvpp/AudioPlayerBase.h
index 31b9fa2..b39d4a2 100644
--- a/libvideoeditor/lvpp/AudioPlayerBase.h
+++ b/libvideoeditor/lvpp/AudioPlayerBase.h
@@ -27,7 +27,7 @@ namespace android {
class MediaSource;
class AudioTrack;
-class PreviewPlayerBase;
+class PreviewPlayer;
class AudioPlayerBase : public TimeSource {
public:
@@ -37,7 +37,7 @@ public:
};
AudioPlayerBase(const sp<MediaPlayerBase::AudioSink> &audioSink,
- PreviewPlayerBase *audioObserver = NULL);
+ PreviewPlayer *audioObserver = NULL);
virtual ~AudioPlayerBase();
@@ -93,7 +93,7 @@ private:
MediaBuffer *mFirstBuffer;
sp<MediaPlayerBase::AudioSink> mAudioSink;
- PreviewPlayerBase *mObserver;
+ PreviewPlayer *mObserver;
static void AudioCallback(int event, void *user, void *info);
void AudioCallback(int event, void *info);
diff --git a/libvideoeditor/lvpp/DummyAudioSource.cpp b/libvideoeditor/lvpp/DummyAudioSource.cpp
index bc38a20..1c497f9 100755
--- a/libvideoeditor/lvpp/DummyAudioSource.cpp
+++ b/libvideoeditor/lvpp/DummyAudioSource.cpp
@@ -14,149 +14,112 @@
* limitations under the License.
*/
-#define LOG_NDEBUG 1
+// #define LOG_NDEBUG 0
#define LOG_TAG "DummyAudioSource"
-#include "utils/Log.h"
-
+#include <utils/Log.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MetaData.h>
-
-
#include "DummyAudioSource.h"
-
-/* Android includes*/
-#include <utils/Log.h>
-#include <memory.h>
-
-
-/*---------------------*/
-/* DEBUG LEVEL SETUP */
-/*---------------------*/
-#define LOG1 ALOGE /*ERRORS Logging*/
-#define LOG2 ALOGV /*WARNING Logging*/
-#define LOG3 //ALOGV /*COMMENTS Logging*/
-
-/*---------------------*/
-/* CONSTANTS */
-/*---------------------*/
-
-
namespace android {
-
-/*---------------------*/
-/* SEEK SOURCE */
-/*---------------------*/
-
//static
-sp<DummyAudioSource> DummyAudioSource::Create(int32_t samplingRate,
- int32_t channelCount,
- int64_t frameDurationUs,
- int64_t audioDurationUs) {
- LOG2("DummyAudioSource::Create ");
- sp<DummyAudioSource> aSource = new DummyAudioSource (samplingRate,
- channelCount,
- frameDurationUs,
- audioDurationUs);
- return aSource;
-}
+sp<DummyAudioSource> DummyAudioSource::Create(
+ int32_t samplingRate, int32_t channelCount,
+ int64_t frameDurationUs, int64_t audioDurationUs) {
+ ALOGV("Create ");
+ return new DummyAudioSource(samplingRate,
+ channelCount,
+ frameDurationUs,
+ audioDurationUs);
-DummyAudioSource::DummyAudioSource (int32_t samplingRate,
- int32_t channelCount,
- int64_t frameDurationUs,
- int64_t audioDurationUs):
- mSamplingRate(samplingRate),
- mChannelCount(channelCount),
- mFrameDurationUs(frameDurationUs),
- mNumberOfSamplePerFrame(0),
- mAudioDurationUs(audioDurationUs),
- mTimeStampUs(0) ,
+}
- mBufferGroup(NULL){
- LOG2("DummyAudioSource::DummyAudioSource constructor START");
- /* Do nothing here? */
- LOG2("DummyAudioSource::DummyAudioSource");
- LOG2("DummyAudioSource:: mSamplingRate = %d",samplingRate);
- LOG2("DummyAudioSource:: mChannelCount = %d",channelCount);
- LOG2("DummyAudioSource:: frameDurationUs = %lld",frameDurationUs);
- LOG2("DummyAudioSource:: mAudioDurationUs = %lld",mAudioDurationUs);
+DummyAudioSource::DummyAudioSource(
+ int32_t samplingRate, int32_t channelCount,
+ int64_t frameDurationUs, int64_t audioDurationUs)
+ : mSamplingRate(samplingRate),
+ mChannelCount(channelCount),
+ mFrameDurationUs(frameDurationUs),
+ mNumberOfSamplePerFrame(0),
+ mAudioDurationUs(audioDurationUs),
+ mTimeStampUs(0),
+ mBufferGroup(NULL) {
+
+ mNumberOfSamplePerFrame = (int32_t)
+ ((1L * mSamplingRate * mFrameDurationUs)/1000000);
+ mNumberOfSamplePerFrame = mNumberOfSamplePerFrame * mChannelCount;
- LOG2("DummyAudioSource::DummyAudioSource constructor END");
+ ALOGV("Constructor: E");
+ ALOGV("samplingRate = %d", samplingRate);
+ ALOGV("channelCount = %d", channelCount);
+ ALOGV("frameDurationUs = %lld", frameDurationUs);
+ ALOGV("audioDurationUs = %lld", audioDurationUs);
+ ALOGV("mNumberOfSamplePerFrame = %d", mNumberOfSamplePerFrame);
+ ALOGV("Constructor: X");
}
-
-DummyAudioSource::~DummyAudioSource () {
+DummyAudioSource::~DummyAudioSource() {
/* Do nothing here? */
- LOG2("DummyAudioSource::~DummyAudioSource");
+ ALOGV("~DummyAudioSource");
}
-void DummyAudioSource::setDuration (int64_t audioDurationUs) {
+void DummyAudioSource::setDuration(int64_t audioDurationUs) {
+ ALOGV("setDuration: %lld us added to %lld us",
+ audioDurationUs, mAudioDurationUs);
+
Mutex::Autolock autoLock(mLock);
- LOG2("SetDuration %lld", mAudioDurationUs);
mAudioDurationUs += audioDurationUs;
- LOG2("SetDuration %lld", mAudioDurationUs);
}
status_t DummyAudioSource::start(MetaData *params) {
+ ALOGV("start: E");
status_t err = OK;
- LOG2("DummyAudioSource::start START");
mTimeStampUs = 0;
- mNumberOfSamplePerFrame = (int32_t) ((1L * mSamplingRate * mFrameDurationUs)/1000000);
- mNumberOfSamplePerFrame = mNumberOfSamplePerFrame * mChannelCount;
mBufferGroup = new MediaBufferGroup;
mBufferGroup->add_buffer(
new MediaBuffer(mNumberOfSamplePerFrame * sizeof(int16_t)));
- LOG2("DummyAudioSource:: mNumberOfSamplePerFrame = %d",mNumberOfSamplePerFrame);
- LOG2("DummyAudioSource::start END");
+ ALOGV("start: X");
return err;
}
-
status_t DummyAudioSource::stop() {
- status_t err = OK;
-
- LOG2("DummyAudioSource::stop START");
+ ALOGV("stop");
delete mBufferGroup;
mBufferGroup = NULL;
-
- LOG2("DummyAudioSource::stop END");
-
- return err;
+ return OK;
}
sp<MetaData> DummyAudioSource::getFormat() {
- LOG2("DummyAudioSource::getFormat");
+ ALOGV("getFormat");
sp<MetaData> meta = new MetaData;
-
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
meta->setInt32(kKeyChannelCount, mChannelCount);
meta->setInt32(kKeySampleRate, mSamplingRate);
meta->setInt64(kKeyDuration, mFrameDurationUs);
-
meta->setCString(kKeyDecoderComponent, "DummyAudioSource");
return meta;
}
-status_t DummyAudioSource::read( MediaBuffer **out, const MediaSource::ReadOptions *options) {
- status_t err = OK;
- //LOG2("DummyAudioSource::read START");
- MediaBuffer *buffer;
+status_t DummyAudioSource::read(
+ MediaBuffer **out, const MediaSource::ReadOptions *options) {
+
+ ALOGV("read: E");
+
int64_t seekTimeUs;
ReadOptions::SeekMode mode;
@@ -164,32 +127,37 @@ status_t DummyAudioSource::read( MediaBuffer **out, const MediaSource::ReadOptio
CHECK(seekTimeUs >= 0);
mTimeStampUs = seekTimeUs;
}
+
{
Mutex::Autolock autoLock(mLock);
if (mTimeStampUs >= mAudioDurationUs) {
+ ALOGI("read: EOS reached %lld > %lld",
+ mTimeStampUs, mAudioDurationUs);
+
*out = NULL;
- ALOGI("EOS reached");
return ERROR_END_OF_STREAM;
}
}
- err = mBufferGroup->acquire_buffer(&buffer);
+ MediaBuffer *buffer;
+ status_t err = mBufferGroup->acquire_buffer(&buffer);
if (err != OK) {
+ ALOGE("Failed to acquire buffer from mBufferGroup: %d", err);
return err;
}
memset((uint8_t *) buffer->data() + buffer->range_offset(),
0, mNumberOfSamplePerFrame << 1);
-
buffer->set_range(buffer->range_offset(), (mNumberOfSamplePerFrame << 1));
-
buffer->meta_data()->setInt64(kKeyTime, mTimeStampUs);
- LOG2("DummyAudioSource::read Buffer_offset = %d,"
- "Buffer_Size = %d, mTimeStampUs = %lld",
- buffer->range_offset(),buffer->size(),mTimeStampUs);
+
+ ALOGV("read: offset = %d, size = %d, mTimeStampUs = %lld",
+ buffer->range_offset(), buffer->size(), mTimeStampUs);
+
mTimeStampUs = mTimeStampUs + mFrameDurationUs;
*out = buffer;
- return err;
+
+ return OK;
}
}// namespace android
diff --git a/libvideoeditor/lvpp/DummyAudioSource.h b/libvideoeditor/lvpp/DummyAudioSource.h
index 8715b10..5f25a8c 100755
--- a/libvideoeditor/lvpp/DummyAudioSource.h
+++ b/libvideoeditor/lvpp/DummyAudioSource.h
@@ -15,44 +15,34 @@
*/
#ifndef DUMMY_AUDIOSOURCE_H_
-
#define DUMMY_AUDIOSOURCE_H_
-#include <utils/RefBase.h>
-#include <utils/threads.h>
-#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/DataSource.h>
namespace android {
-
-class MediaBuffer;
class MetaData;
struct MediaBufferGroup;
-
-
struct DummyAudioSource : public MediaSource {
public:
- static sp<DummyAudioSource> Create(int32_t samplingRate,
- int32_t channelCount,
- int64_t frameDurationUs,
- int64_t audioDurationUs);
+ static sp<DummyAudioSource> Create(
+ int32_t samplingRate, int32_t channelCount,
+ int64_t frameDurationUs, int64_t audioDurationUs);
+
virtual status_t start(MetaData *params = NULL);
virtual status_t stop();
virtual sp<MetaData> getFormat();
- virtual status_t read (MediaBuffer **buffer,
- const MediaSource::ReadOptions *options = NULL);
- void setDuration (int64_t audioDurationUs);
+
+ virtual status_t read(
+ MediaBuffer **buffer,
+ const MediaSource::ReadOptions *options = NULL);
+
+ void setDuration(int64_t audioDurationUs);
protected:
- DummyAudioSource (int32_t samplingRate,
- int32_t channelCount,
- int64_t frameDurationUs,
- int64_t audioDurationUs);
virtual ~DummyAudioSource();
private:
@@ -66,6 +56,11 @@ private:
MediaBufferGroup *mBufferGroup;
+ DummyAudioSource(
+ int32_t samplingRate, int32_t channelCount,
+ int64_t frameDurationUs, int64_t audioDurationUs);
+
+ // Don't call me
DummyAudioSource(const DummyAudioSource &);
DummyAudioSource &operator=(const DummyAudioSource &);
diff --git a/libvideoeditor/lvpp/DummyVideoSource.cpp b/libvideoeditor/lvpp/DummyVideoSource.cpp
index 02ebcb8..339d8fe 100755
--- a/libvideoeditor/lvpp/DummyVideoSource.cpp
+++ b/libvideoeditor/lvpp/DummyVideoSource.cpp
@@ -14,101 +14,98 @@
* limitations under the License.
*/
-#define LOG_NDEBUG 1
+//#define LOG_NDEBUG 0
#define LOG_TAG "DummyVideoSource"
-#include "utils/Log.h"
-
+#include <stdlib.h>
+#include <utils/Log.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MetaData.h>
-
+#include "VideoEditorTools.h"
#include "DummyVideoSource.h"
-/* Android includes*/
-#include <utils/Log.h>
-#include <memory.h>
-
-
-#define LOG1 ALOGE /*ERRORS Logging*/
-#define LOG2 ALOGV /*WARNING Logging*/
-#define LOG3 //ALOGV /*COMMENTS Logging*/
-
namespace android {
+sp<DummyVideoSource> DummyVideoSource::Create(
+ uint32_t width, uint32_t height,
+ uint64_t clipDuration, const char *imageUri) {
+
+ ALOGV("Create");
+ return new DummyVideoSource(
+ width, height, clipDuration, imageUri);
-sp<DummyVideoSource> DummyVideoSource::Create (
- uint32_t width, uint32_t height,
- uint64_t clipDuration, const char *imageUri) {
- LOG2("DummyVideoSource::Create ");
- sp<DummyVideoSource> vSource = new DummyVideoSource (
- width, height, clipDuration, imageUri);
- return vSource;
}
-DummyVideoSource::DummyVideoSource (
- uint32_t width, uint32_t height,
- uint64_t clipDuration, const char *imageUri) {
+DummyVideoSource::DummyVideoSource(
+ uint32_t width, uint32_t height,
+ uint64_t clipDuration, const char *imageUri) {
+
+ ALOGV("Constructor: E");
- LOG2("DummyVideoSource::DummyVideoSource constructor START");
mFrameWidth = width;
mFrameHeight = height;
mImageClipDuration = clipDuration;
mUri = imageUri;
mImageBuffer = NULL;
- LOG2("DummyVideoSource::DummyVideoSource constructor END");
+ ALOGV("%s", mUri);
+ ALOGV("Constructor: X");
}
-DummyVideoSource::~DummyVideoSource () {
+DummyVideoSource::~DummyVideoSource() {
/* Do nothing here? */
- LOG2("DummyVideoSource::~DummyVideoSource");
+ ALOGV("~DummyVideoSource");
}
status_t DummyVideoSource::start(MetaData *params) {
- status_t err = OK;
- LOG2("DummyVideoSource::start START, %s", mUri);
- //get the frame buffer from the rgb file and store into a MediaBuffer
- err = LvGetImageThumbNail((const char *)mUri,
- mFrameHeight , mFrameWidth ,
- (M4OSA_Void **)&mImageBuffer);
+ ALOGV("start: E");
+
+ // Get the frame buffer from the rgb file, mUri,
+ // and store its content into a MediaBuffer
+ status_t err = LvGetImageThumbNail(
+ (const char *)mUri,
+ mFrameHeight, mFrameWidth,
+ (M4OSA_Void **) &mImageBuffer);
+ if (err != OK) {
+ ALOGE("LvGetImageThumbNail failed: %d", err);
+ return err;
+ }
mIsFirstImageFrame = true;
mImageSeekTime = 0;
mImagePlayStartTime = 0;
mFrameTimeUs = 0;
- LOG2("DummyVideoSource::start END");
- return err;
+ ALOGV("start: X");
+ return OK;
}
status_t DummyVideoSource::stop() {
+ ALOGV("stop");
status_t err = OK;
- LOG2("DummyVideoSource::stop START");
if (mImageBuffer != NULL) {
free(mImageBuffer);
mImageBuffer = NULL;
}
- LOG2("DummyVideoSource::stop END");
return err;
}
sp<MetaData> DummyVideoSource::getFormat() {
- LOG2("DummyVideoSource::getFormat");
+ ALOGV("getFormat");
sp<MetaData> meta = new MetaData;
-
meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
meta->setInt32(kKeyWidth, mFrameWidth);
meta->setInt32(kKeyHeight, mFrameHeight);
@@ -119,45 +116,54 @@ sp<MetaData> DummyVideoSource::getFormat() {
}
status_t DummyVideoSource::read(
- MediaBuffer **out,
- const MediaSource::ReadOptions *options) {
- status_t err = OK;
- MediaBuffer *buffer;
- LOG2("DummyVideoSource::read START");
+ MediaBuffer **out,
+ const MediaSource::ReadOptions *options) {
+ ALOGV("read: E");
+
+ const int32_t kTimeScale = 1000; /* time scale in ms */
bool seeking = false;
int64_t seekTimeUs;
ReadOptions::SeekMode seekMode;
-
if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
seeking = true;
mImageSeekTime = seekTimeUs;
- M4OSA_clockGetTime(&mImagePlayStartTime, 1000); //1000 time scale for time in ms
+ M4OSA_clockGetTime(&mImagePlayStartTime, kTimeScale);
}
- if ((mImageSeekTime == mImageClipDuration) || (mFrameTimeUs == (int64_t)mImageClipDuration)) {
- LOG2("DummyVideoSource::read() End of stream reached; return NULL buffer");
+ if ((mImageSeekTime == mImageClipDuration) ||
+ (mFrameTimeUs == (int64_t)mImageClipDuration)) {
+ ALOGV("read: EOS reached");
*out = NULL;
return ERROR_END_OF_STREAM;
}
- buffer = new MediaBuffer(mImageBuffer, (mFrameWidth*mFrameHeight*1.5));
+ status_t err = OK;
+ MediaBuffer *buffer = new MediaBuffer(
+ mImageBuffer, (mFrameWidth * mFrameHeight * 1.5));
- //set timestamp of buffer
+ // Set timestamp of buffer
if (mIsFirstImageFrame) {
- M4OSA_clockGetTime(&mImagePlayStartTime, 1000); //1000 time scale for time in ms
+ M4OSA_clockGetTime(&mImagePlayStartTime, kTimeScale);
mFrameTimeUs = (mImageSeekTime + 1);
- LOG2("DummyVideoSource::read() jpg 1st frame timeUs = %lld, begin cut time = %ld", mFrameTimeUs, mImageSeekTime);
+ ALOGV("read: jpg 1st frame timeUs = %lld, begin cut time = %ld",
+ mFrameTimeUs, mImageSeekTime);
+
mIsFirstImageFrame = false;
} else {
M4OSA_Time currentTimeMs;
- M4OSA_clockGetTime(&currentTimeMs, 1000);
+ M4OSA_clockGetTime(&currentTimeMs, kTimeScale);
+
+ mFrameTimeUs = mImageSeekTime +
+ (currentTimeMs - mImagePlayStartTime) * 1000LL;
- mFrameTimeUs = mImageSeekTime + (currentTimeMs - mImagePlayStartTime)*1000;
- LOG2("DummyVideoSource::read() jpg frame timeUs = %lld", mFrameTimeUs);
+ ALOGV("read: jpg frame timeUs = %lld", mFrameTimeUs);
}
+
buffer->meta_data()->setInt64(kKeyTime, mFrameTimeUs);
- buffer->set_range(buffer->range_offset(), mFrameWidth*mFrameHeight*1.5);
+ buffer->set_range(buffer->range_offset(),
+ mFrameWidth * mFrameHeight * 1.5);
+
*out = buffer;
return err;
}
diff --git a/libvideoeditor/lvpp/DummyVideoSource.h b/libvideoeditor/lvpp/DummyVideoSource.h
index 28c33c3..16514f2 100755
--- a/libvideoeditor/lvpp/DummyVideoSource.h
+++ b/libvideoeditor/lvpp/DummyVideoSource.h
@@ -15,43 +15,34 @@
*/
#ifndef DUMMY_VIDEOSOURCE_H_
-
#define DUMMY_VIDEOSOURCE_H_
-#include <utils/RefBase.h>
-#include <utils/threads.h>
#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/DataSource.h>
-#include "OMX_IVCommon.h"
-#include "VideoEditorTools.h"
#include "M4OSA_Clock.h"
#include "M4OSA_Time.h"
#include "M4OSA_Types.h"
-
namespace android {
-
class MediaBuffer;
class MetaData;
struct DummyVideoSource : public MediaSource {
public:
- static sp<DummyVideoSource> Create(uint32_t width,
- uint32_t height,
- uint64_t clipDuration,
- const char *imageUri);
+ static sp<DummyVideoSource> Create(
+ uint32_t width, uint32_t height,
+ uint64_t clipDuration, const char *imageUri);
virtual status_t start(MetaData *params = NULL);
virtual status_t stop();
virtual sp<MetaData> getFormat();
- virtual status_t read(MediaBuffer **buffer,
- const MediaSource::ReadOptions *options = NULL);
+
+ virtual status_t read(
+ MediaBuffer **buffer,
+ const MediaSource::ReadOptions *options = NULL);
protected:
- DummyVideoSource (uint32_t width, uint32_t height,
- uint64_t clipDuration, const char *imageUri);
virtual ~DummyVideoSource();
private:
@@ -65,6 +56,11 @@ private:
M4OSA_Time mImagePlayStartTime;
uint32_t mImageSeekTime;
+ DummyVideoSource(
+ uint32_t width, uint32_t height,
+ uint64_t clipDuration, const char *imageUri);
+
+ // Don't call me
DummyVideoSource(const DummyVideoSource &);
DummyVideoSource &operator=(const DummyVideoSource &);
diff --git a/libvideoeditor/lvpp/PreviewPlayer.cpp b/libvideoeditor/lvpp/PreviewPlayer.cpp
index 9d2154a..77c70a5 100755
--- a/libvideoeditor/lvpp/PreviewPlayer.cpp
+++ b/libvideoeditor/lvpp/PreviewPlayer.cpp
@@ -15,36 +15,45 @@
*/
-#define LOG_NDEBUG 1
+// #define LOG_NDEBUG 0
#define LOG_TAG "PreviewPlayer"
#include <utils/Log.h>
-#include <dlfcn.h>
-
-#include "PreviewPlayer.h"
-#include "DummyAudioSource.h"
-#include "DummyVideoSource.h"
-#include "VideoEditorSRC.h"
-#include "include/NuCachedSource2.h"
-#include "include/ThrottledSource.h"
-
-
#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <media/IMediaPlayerService.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaExtractor.h>
-#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXCodec.h>
-
+#include <media/stagefright/foundation/ADebug.h>
#include <surfaceflinger/Surface.h>
-#include <media/stagefright/foundation/ALooper.h>
+#include <gui/ISurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+
+#include "VideoEditorPreviewController.h"
+#include "AudioPlayerBase.h"
+#include "DummyAudioSource.h"
+#include "DummyVideoSource.h"
+#include "VideoEditorSRC.h"
+#include "PreviewPlayer.h"
namespace android {
+void addBatteryData(uint32_t params) {
+ sp<IBinder> binder =
+ defaultServiceManager()->getService(String16("media.player"));
+ sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
+ CHECK(service.get() != NULL);
+
+ service->addBatteryData(params);
+}
+
struct PreviewPlayerEvent : public TimedEventQueue::Event {
PreviewPlayerEvent(
PreviewPlayer *player,
@@ -69,12 +78,25 @@ private:
};
PreviewPlayer::PreviewPlayer(NativeWindowRenderer* renderer)
- : PreviewPlayerBase(),
+ : mQueueStarted(false),
+ mTimeSource(NULL),
+ mVideoRendererIsPreview(false),
+ mAudioPlayer(NULL),
+ mDisplayWidth(0),
+ mDisplayHeight(0),
+ mFlags(0),
+ mExtractorFlags(0),
+ mVideoBuffer(NULL),
+ mLastVideoTimeUs(-1),
mNativeWindowRenderer(renderer),
mCurrFramingEffectIndex(0),
mFrameRGBBuffer(NULL),
mFrameYUVBuffer(NULL) {
+ CHECK_EQ(mClient.connect(), (status_t)OK);
+ DataSource::RegisterDefaultSniffers();
+
+
mVideoRenderer = NULL;
mEffectsSettings = NULL;
mVeAudioPlayer = NULL;
@@ -92,16 +114,14 @@ PreviewPlayer::PreviewPlayer(NativeWindowRenderer* renderer)
mVideoEvent = new PreviewPlayerEvent(this, &PreviewPlayer::onVideoEvent);
mVideoEventPending = false;
- mStreamDoneEvent = new PreviewPlayerEvent(this,
- &PreviewPlayer::onStreamDone);
-
- mStreamDoneEventPending = false;
-
+ mVideoLagEvent = new PreviewPlayerEvent(this, &PreviewPlayer::onVideoLagUpdate);
+ mVideoEventPending = false;
mCheckAudioStatusEvent = new PreviewPlayerEvent(
- this, &PreviewPlayerBase::onCheckAudioStatus);
-
+ this, &PreviewPlayer::onCheckAudioStatus);
mAudioStatusEventPending = false;
-
+ mStreamDoneEvent = new PreviewPlayerEvent(
+ this, &PreviewPlayer::onStreamDone);
+ mStreamDoneEventPending = false;
mProgressCbEvent = new PreviewPlayerEvent(this,
&PreviewPlayer::onProgressCbEvent);
@@ -126,18 +146,25 @@ PreviewPlayer::~PreviewPlayer() {
if (mVideoRenderer) {
mNativeWindowRenderer->destroyRenderInput(mVideoRenderer);
}
+
+ Mutex::Autolock lock(mLock);
+ clear_l();
+ mClient.disconnect();
}
-void PreviewPlayer::cancelPlayerEvents() {
+void PreviewPlayer::cancelPlayerEvents_l(bool updateProgressCb) {
mQueue.cancelEvent(mVideoEvent->eventID());
mVideoEventPending = false;
mQueue.cancelEvent(mStreamDoneEvent->eventID());
mStreamDoneEventPending = false;
mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
mAudioStatusEventPending = false;
-
- mQueue.cancelEvent(mProgressCbEvent->eventID());
- mProgressCbEventPending = false;
+ mQueue.cancelEvent(mVideoLagEvent->eventID());
+ mVideoLagEventPending = false;
+ if (updateProgressCb) {
+ mQueue.cancelEvent(mProgressCbEvent->eventID());
+ mProgressCbEventPending = false;
+ }
}
status_t PreviewPlayer::setDataSource(const char *path) {
@@ -194,11 +221,8 @@ status_t PreviewPlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
/* Add the support for Dummy audio*/
if( !haveAudio ){
- ALOGV("PreviewPlayer: setDataSource_l Dummyaudiocreation started");
-
mAudioTrack = DummyAudioSource::Create(32000, 2, 20000,
((mPlayEndTimeMsec)*1000LL));
- ALOGV("PreviewPlayer: setDataSource_l Dummyauiosource created");
if(mAudioTrack != NULL) {
haveAudio = true;
}
@@ -213,18 +237,18 @@ status_t PreviewPlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
}
status_t PreviewPlayer::setDataSource_l_jpg() {
+ ALOGV("setDataSource_l_jpg");
+
M4OSA_ERR err = M4NO_ERROR;
- ALOGV("PreviewPlayer: setDataSource_l_jpg started");
mAudioSource = DummyAudioSource::Create(32000, 2, 20000,
((mPlayEndTimeMsec)*1000LL));
- ALOGV("PreviewPlayer: setDataSource_l_jpg Dummyaudiosource created");
if(mAudioSource != NULL) {
setAudioSource(mAudioSource);
}
status_t error = mAudioSource->start();
if (error != OK) {
- ALOGV("Error starting dummy audio source");
+ ALOGE("Error starting dummy audio source");
mAudioSource.clear();
return err;
}
@@ -246,11 +270,6 @@ status_t PreviewPlayer::setDataSource_l_jpg() {
return OK;
}
-void PreviewPlayer::reset() {
- Mutex::Autolock autoLock(mLock);
- reset_l();
-}
-
void PreviewPlayer::reset_l() {
if (mFlags & PREPARING) {
@@ -261,7 +280,7 @@ void PreviewPlayer::reset_l() {
mPreparedCondition.wait(mLock);
}
- cancelPlayerEvents();
+ cancelPlayerEvents_l();
mAudioTrack.clear();
mVideoTrack.clear();
@@ -328,6 +347,7 @@ void PreviewPlayer::reset_l() {
}
status_t PreviewPlayer::play() {
+ ALOGV("play");
Mutex::Autolock autoLock(mLock);
mFlags &= ~CACHE_UNDERRUN;
@@ -336,6 +356,7 @@ status_t PreviewPlayer::play() {
}
status_t PreviewPlayer::startAudioPlayer_l() {
+ ALOGV("startAudioPlayer_l");
CHECK(!(mFlags & AUDIO_RUNNING));
if (mAudioSource == NULL || mAudioPlayer == NULL) {
@@ -366,6 +387,7 @@ status_t PreviewPlayer::startAudioPlayer_l() {
}
status_t PreviewPlayer::setAudioPlayer(AudioPlayerBase *audioPlayer) {
+ ALOGV("setAudioPlayer");
Mutex::Autolock autoLock(mLock);
CHECK(!(mFlags & PLAYING));
mAudioPlayer = audioPlayer;
@@ -428,6 +450,7 @@ status_t PreviewPlayer::setAudioPlayer(AudioPlayerBase *audioPlayer) {
}
void PreviewPlayer::onStreamDone() {
+ ALOGV("onStreamDone");
// Posted whenever any stream finishes playing.
Mutex::Autolock autoLock(mLock);
@@ -496,6 +519,7 @@ void PreviewPlayer::onStreamDone() {
status_t PreviewPlayer::play_l() {
+ ALOGV("play_l");
mFlags &= ~SEEK_PREVIEW;
@@ -658,9 +682,8 @@ status_t PreviewPlayer::initRenderer_l() {
status_t PreviewPlayer::seekTo(int64_t timeUs) {
-
+ Mutex::Autolock autoLock(mLock);
if ((mExtractorFlags & MediaExtractor::CAN_SEEK) || (mIsVideoSourceJpg)) {
- Mutex::Autolock autoLock(mLock);
return seekTo_l(timeUs);
}
@@ -683,7 +706,7 @@ status_t PreviewPlayer::getVideoDimensions(
}
-status_t PreviewPlayer::initAudioDecoder() {
+status_t PreviewPlayer::initAudioDecoder_l() {
sp<MetaData> meta = mAudioTrack->getFormat();
const char *mime;
CHECK(meta->findCString(kKeyMIMEType, &mime));
@@ -698,7 +721,6 @@ status_t PreviewPlayer::initAudioDecoder() {
mAudioTrack);
if(aRawSource != NULL) {
- ALOGV("initAudioDecoder: new VideoEditorSRC");
mAudioSource = new VideoEditorSRC(aRawSource);
}
}
@@ -706,10 +728,7 @@ status_t PreviewPlayer::initAudioDecoder() {
if (mAudioSource != NULL) {
int64_t durationUs;
if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
- Mutex::Autolock autoLock(mMiscStateLock);
- if (mDurationUs < 0 || durationUs > mDurationUs) {
- mDurationUs = durationUs;
- }
+ setDuration_l(durationUs);
}
status_t err = mAudioSource->start();
@@ -727,9 +746,7 @@ status_t PreviewPlayer::initAudioDecoder() {
return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
}
-
-status_t PreviewPlayer::initVideoDecoder(uint32_t flags) {
-
+status_t PreviewPlayer::initVideoDecoder_l(uint32_t flags) {
initRenderer_l();
if (mVideoRenderer == NULL) {
@@ -746,10 +763,7 @@ status_t PreviewPlayer::initVideoDecoder(uint32_t flags) {
if (mVideoSource != NULL) {
int64_t durationUs;
if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
- Mutex::Autolock autoLock(mMiscStateLock);
- if (mDurationUs < 0 || durationUs > mDurationUs) {
- mDurationUs = durationUs;
- }
+ setDuration_l(durationUs);
}
updateSizeToRender(mVideoTrack->getFormat());
@@ -821,7 +835,7 @@ void PreviewPlayer::onVideoEvent() {
options.clearSeekTo();
if (err != OK) {
- CHECK_EQ(mVideoBuffer, NULL);
+ CHECK(!mVideoBuffer);
if (err == INFO_FORMAT_CHANGED) {
ALOGV("LV PLAYER VideoSource signalled format change");
@@ -892,16 +906,11 @@ void PreviewPlayer::onVideoEvent() {
int64_t timeUs;
CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
+ setPosition_l(timeUs);
- {
- Mutex::Autolock autoLock(mMiscStateLock);
- mVideoTimeUs = timeUs;
- }
-
-
- if(!mStartNextPlayer) {
- int64_t playbackTimeRemaining = (mPlayEndTimeMsec*1000LL) - timeUs;
- if(playbackTimeRemaining <= 1500000) {
+ if (!mStartNextPlayer) {
+ int64_t playbackTimeRemaining = (mPlayEndTimeMsec * 1000LL) - timeUs;
+ if (playbackTimeRemaining <= 1500000) {
//When less than 1.5 sec of playback left
// send notification to start next player
@@ -1047,7 +1056,7 @@ void PreviewPlayer::onVideoEvent() {
mCurrFramingEffectIndex = index;
mOverlayUpdateEventPosted = true;
postOverlayUpdateEvent_l();
- ALOGV("Framing index = %d", mCurrFramingEffectIndex);
+ ALOGV("Framing index = %ld", mCurrFramingEffectIndex);
} else {
ALOGV("No framing effects found");
}
@@ -1100,11 +1109,13 @@ void PreviewPlayer::onVideoEvent() {
}
status_t PreviewPlayer::prepare() {
+ ALOGV("prepare");
Mutex::Autolock autoLock(mLock);
return prepare_l();
}
status_t PreviewPlayer::prepare_l() {
+ ALOGV("prepare_l");
if (mFlags & PREPARED) {
return OK;
}
@@ -1127,7 +1138,14 @@ status_t PreviewPlayer::prepare_l() {
return mPrepareResult;
}
+status_t PreviewPlayer::prepareAsync() {
+ ALOGV("prepareAsync");
+ Mutex::Autolock autoLock(mLock);
+ return prepareAsync_l();
+}
+
status_t PreviewPlayer::prepareAsync_l() {
+ ALOGV("prepareAsync_l");
if (mFlags & PREPARING) {
return UNKNOWN_ERROR; // async prepare already pending
}
@@ -1168,27 +1186,19 @@ status_t PreviewPlayer::finishSetDataSource_l() {
}
if (extractor == NULL) {
- ALOGV("PreviewPlayer::finishSetDataSource_l extractor == NULL");
+ ALOGV("finishSetDataSource_l: failed to create extractor");
return setDataSource_l_jpg();
}
return setDataSource_l(extractor);
}
-
-// static
-bool PreviewPlayer::ContinuePreparation(void *cookie) {
- PreviewPlayer *me = static_cast<PreviewPlayer *>(cookie);
-
- return (me->mFlags & PREPARE_CANCELLED) == 0;
-}
-
void PreviewPlayer::onPrepareAsyncEvent() {
Mutex::Autolock autoLock(mLock);
ALOGV("onPrepareAsyncEvent");
if (mFlags & PREPARE_CANCELLED) {
- ALOGV("LV PLAYER prepare was cancelled before doing anything");
+ ALOGV("prepare was cancelled before doing anything");
abortPrepare(UNKNOWN_ERROR);
return;
}
@@ -1203,7 +1213,7 @@ void PreviewPlayer::onPrepareAsyncEvent() {
}
if (mVideoTrack != NULL && mVideoSource == NULL) {
- status_t err = initVideoDecoder(OMXCodec::kHardwareCodecsOnly);
+ status_t err = initVideoDecoder_l(OMXCodec::kHardwareCodecsOnly);
if (err != OK) {
abortPrepare(err);
@@ -1212,7 +1222,7 @@ void PreviewPlayer::onPrepareAsyncEvent() {
}
if (mAudioTrack != NULL && mAudioSource == NULL) {
- status_t err = initAudioDecoder();
+ status_t err = initAudioDecoder_l();
if (err != OK) {
abortPrepare(err);
@@ -1224,15 +1234,13 @@ void PreviewPlayer::onPrepareAsyncEvent() {
}
void PreviewPlayer::finishAsyncPrepare_l() {
+ ALOGV("finishAsyncPrepare_l");
if (mIsAsyncPrepare) {
if (mVideoSource == NULL) {
- ALOGV("finishAsyncPrepare_l: MEDIA_SET_VIDEO_SIZE 0 0 ");
notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
} else {
- ALOGV("finishAsyncPrepare_l: MEDIA_SET_VIDEO_SIZE");
notifyVideoSize_l();
}
- ALOGV("finishAsyncPrepare_l: MEDIA_PREPARED");
notifyListener_l(MEDIA_PREPARED);
}
@@ -1254,36 +1262,36 @@ void PreviewPlayer::releaseLock() {
}
status_t PreviewPlayer::loadEffectsSettings(
- M4VSS3GPP_EffectSettings* pEffectSettings, int nEffects) {
- M4OSA_UInt32 i = 0, rgbSize = 0;
- M4VIFI_UInt8 *tmp = M4OSA_NULL;
+ M4VSS3GPP_EffectSettings* pEffectSettings, int nEffects) {
+ ALOGV("loadEffectsSettings");
mNumberEffects = nEffects;
mEffectsSettings = pEffectSettings;
return OK;
}
status_t PreviewPlayer::loadAudioMixSettings(
- M4xVSS_AudioMixingSettings* pAudioMixSettings) {
+ M4xVSS_AudioMixingSettings* pAudioMixSettings) {
- ALOGV("PreviewPlayer: loadAudioMixSettings: ");
+ ALOGV("loadAudioMixSettings");
mPreviewPlayerAudioMixSettings = pAudioMixSettings;
return OK;
}
status_t PreviewPlayer::setAudioMixPCMFileHandle(
- M4OSA_Context pAudioMixPCMFileHandle) {
+ M4OSA_Context pAudioMixPCMFileHandle) {
- ALOGV("PreviewPlayer: setAudioMixPCMFileHandle: ");
+ ALOGV("setAudioMixPCMFileHandle");
mAudioMixPCMFileHandle = pAudioMixPCMFileHandle;
return OK;
}
status_t PreviewPlayer::setAudioMixStoryBoardParam(
- M4OSA_UInt32 audioMixStoryBoardTS,
- M4OSA_UInt32 currentMediaBeginCutTime,
- M4OSA_UInt32 primaryTrackVolValue ) {
+ M4OSA_UInt32 audioMixStoryBoardTS,
+ M4OSA_UInt32 currentMediaBeginCutTime,
+ M4OSA_UInt32 primaryTrackVolValue ) {
+ ALOGV("setAudioMixStoryBoardParam");
mAudioMixStoryBoardTS = audioMixStoryBoardTS;
mCurrentMediaBeginCutTime = currentMediaBeginCutTime;
mCurrentMediaVolumeValue = primaryTrackVolValue;
@@ -1305,7 +1313,7 @@ status_t PreviewPlayer::setPlaybackEndTime(uint32_t msec) {
status_t PreviewPlayer::setStoryboardStartTime(uint32_t msec) {
mStoryboardStartTimeMsec = msec;
- mDecVideoTsStoryBoard = mStoryboardStartTimeMsec*1000LL;
+ mDecVideoTsStoryBoard = mStoryboardStartTimeMsec * 1000LL;
return OK;
}
@@ -1322,17 +1330,16 @@ status_t PreviewPlayer::setMediaRenderingMode(
mRenderingMode = mode;
- status_t err = OK;
/* get the video width and height by resolution */
- err = getVideoSizeByResolution(outputVideoSize,
- &mOutputVideoWidth, &mOutputVideoHeight);
+ return getVideoSizeByResolution(
+ outputVideoSize,
+ &mOutputVideoWidth, &mOutputVideoHeight);
- return err;
}
status_t PreviewPlayer::resetJniCallbackTimeStamp() {
- mDecVideoTsStoryBoard = mStoryboardStartTimeMsec*1000LL;
+ mDecVideoTsStoryBoard = mStoryboardStartTimeMsec * 1000LL;
return OK;
}
@@ -1354,10 +1361,9 @@ void PreviewPlayer::onProgressCbEvent() {
mProgressCbEventPending = false;
// If playback starts from previous I-frame,
// then send frame storyboard duration
- if((mDecodedVideoTs/1000) < mPlayBeginTimeMsec) {
+ if ((mDecodedVideoTs/1000) < mPlayBeginTimeMsec) {
notifyListener_l(MEDIA_INFO, 0, mDecVideoTsStoryBoard/1000);
- }
- else {
+ } else {
notifyListener_l(MEDIA_INFO, 0,
(((mDecodedVideoTs+mDecVideoTsStoryBoard)/1000)-mPlayBeginTimeMsec));
}
@@ -1379,18 +1385,13 @@ void PreviewPlayer::onUpdateOverlayEvent() {
}
mOverlayUpdateEventPending = false;
- int updateState;
- if (mOverlayUpdateEventPosted) {
- updateState = 1;
- } else {
- updateState = 0;
- }
+ int updateState = mOverlayUpdateEventPosted? 1: 0;
notifyListener_l(0xBBBBBBBB, updateState, mCurrFramingEffectIndex);
}
void PreviewPlayer::setVideoPostProcessingNode(
- M4VSS3GPP_VideoEffectType type, M4OSA_Bool enable) {
+ M4VSS3GPP_VideoEffectType type, M4OSA_Bool enable) {
uint32_t effect = VIDEO_EFFECT_NONE;
@@ -1445,18 +1446,17 @@ void PreviewPlayer::setVideoPostProcessingNode(
break;
}
- if(enable == M4OSA_TRUE) {
+ if (enable == M4OSA_TRUE) {
//If already set, then no need to set again
- if(!(mCurrentVideoEffect & effect)) {
+ if (!(mCurrentVideoEffect & effect)) {
mCurrentVideoEffect |= effect;
- if(effect == VIDEO_EFFECT_FIFTIES) {
+ if (effect == VIDEO_EFFECT_FIFTIES) {
mIsFiftiesEffectStarted = true;
}
}
- }
- else {
+ } else {
//Reset only if already set
- if(mCurrentVideoEffect & effect) {
+ if (mCurrentVideoEffect & effect) {
mCurrentVideoEffect &= ~effect;
}
}
@@ -1469,12 +1469,12 @@ status_t PreviewPlayer::setImageClipProperties(uint32_t width,uint32_t height) {
}
status_t PreviewPlayer::readFirstVideoFrame() {
- ALOGV("PreviewPlayer::readFirstVideoFrame");
+ ALOGV("readFirstVideoFrame");
if (!mVideoBuffer) {
MediaSource::ReadOptions options;
if (mSeeking != NO_SEEK) {
- ALOGV("LV PLAYER seeking to %lld us (%.2f secs)", mSeekTimeUs,
+ ALOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs,
mSeekTimeUs / 1E6);
options.setSeekTo(
@@ -1485,10 +1485,10 @@ status_t PreviewPlayer::readFirstVideoFrame() {
options.clearSeekTo();
if (err != OK) {
- CHECK_EQ(mVideoBuffer, NULL);
+ CHECK(!mVideoBuffer);
if (err == INFO_FORMAT_CHANGED) {
- ALOGV("LV PLAYER VideoSource signalled format change");
+ ALOGV("VideoSource signalled format change");
notifyVideoSize_l();
if (mVideoRenderer != NULL) {
@@ -1502,7 +1502,7 @@ status_t PreviewPlayer::readFirstVideoFrame() {
updateSizeToRender(mVideoSource->getFormat());
continue;
}
- ALOGV("PreviewPlayer: onVideoEvent EOS reached.");
+ ALOGV("EOS reached.");
mFlags |= VIDEO_AT_EOS;
mFlags |= AUDIO_AT_EOS;
postStreamDoneEvent_l(err);
@@ -1529,7 +1529,7 @@ status_t PreviewPlayer::readFirstVideoFrame() {
continue;
}
} else {
- if((videoTimeUs/1000) < mPlayBeginTimeMsec) {
+ if ((videoTimeUs/1000) < mPlayBeginTimeMsec) {
// buffers are before begin cut time
// ignore them
mVideoBuffer->release();
@@ -1543,11 +1543,7 @@ status_t PreviewPlayer::readFirstVideoFrame() {
int64_t timeUs;
CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
-
- {
- Mutex::Autolock autoLock(mMiscStateLock);
- mVideoTimeUs = timeUs;
- }
+ setPosition_l(timeUs);
mDecodedVideoTs = timeUs;
@@ -1566,4 +1562,529 @@ void PreviewPlayer::updateSizeToRender(sp<MetaData> meta) {
}
}
+void PreviewPlayer::setListener(const wp<MediaPlayerBase> &listener) {
+ Mutex::Autolock autoLock(mLock);
+ mListener = listener;
+}
+
+status_t PreviewPlayer::setDataSource(const sp<IStreamSource> &source) {
+ return INVALID_OPERATION;
+}
+
+void PreviewPlayer::reset() {
+ Mutex::Autolock autoLock(mLock);
+ reset_l();
+}
+
+void PreviewPlayer::clear_l() {
+ mDisplayWidth = 0;
+ mDisplayHeight = 0;
+
+ if (mFlags & PLAYING) {
+ updateBatteryUsage_l();
+ }
+
+ if (mFlags & PREPARING) {
+ mFlags |= PREPARE_CANCELLED;
+
+ if (mFlags & PREPARING_CONNECTED) {
+ // We are basically done preparing, we're just buffering
+ // enough data to start playback, we can safely interrupt that.
+ finishAsyncPrepare_l();
+ }
+ }
+
+ while (mFlags & PREPARING) {
+ mPreparedCondition.wait(mLock);
+ }
+
+ cancelPlayerEvents_l(true);
+
+ mAudioTrack.clear();
+ mVideoTrack.clear();
+
+ // Shutdown audio first, so that the respone to the reset request
+ // appears to happen instantaneously as far as the user is concerned
+ // If we did this later, audio would continue playing while we
+ // shutdown the video-related resources and the player appear to
+ // not be as responsive to a reset request.
+ if (mAudioPlayer == NULL && mAudioSource != NULL) {
+ // If we had an audio player, it would have effectively
+ // taken possession of the audio source and stopped it when
+ // _it_ is stopped. Otherwise this is still our responsibility.
+ mAudioSource->stop();
+ }
+ mAudioSource.clear();
+
+ mTimeSource = NULL;
+
+ delete mAudioPlayer;
+ mAudioPlayer = NULL;
+
+ if (mVideoSource != NULL) {
+ shutdownVideoDecoder_l();
+ }
+
+ mDurationUs = -1;
+ mFlags = 0;
+ mExtractorFlags = 0;
+ mTimeSourceDeltaUs = 0;
+ mVideoTimeUs = 0;
+
+ mSeeking = NO_SEEK;
+ mSeekNotificationSent = false;
+ mSeekTimeUs = 0;
+
+ mUri.setTo("");
+
+ mBitrate = -1;
+ mLastVideoTimeUs = -1;
+}
+
+void PreviewPlayer::notifyListener_l(int msg, int ext1, int ext2) {
+ if (mListener != NULL) {
+ sp<MediaPlayerBase> listener = mListener.promote();
+
+ if (listener != NULL) {
+ listener->sendEvent(msg, ext1, ext2);
+ }
+ }
+}
+
+void PreviewPlayer::onVideoLagUpdate() {
+ Mutex::Autolock autoLock(mLock);
+ if (!mVideoLagEventPending) {
+ return;
+ }
+ mVideoLagEventPending = false;
+
+ int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs();
+ int64_t videoLateByUs = audioTimeUs - mVideoTimeUs;
+
+ if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) {
+ ALOGV("video late by %lld ms.", videoLateByUs / 1000ll);
+
+ notifyListener_l(
+ MEDIA_INFO,
+ MEDIA_INFO_VIDEO_TRACK_LAGGING,
+ videoLateByUs / 1000ll);
+ }
+
+ postVideoLagEvent_l();
+}
+
+void PreviewPlayer::notifyVideoSize_l() {
+ sp<MetaData> meta = mVideoSource->getFormat();
+
+ int32_t vWidth, vHeight;
+ int32_t cropLeft, cropTop, cropRight, cropBottom;
+
+ CHECK(meta->findInt32(kKeyWidth, &vWidth));
+ CHECK(meta->findInt32(kKeyHeight, &vHeight));
+
+ mGivenWidth = vWidth;
+ mGivenHeight = vHeight;
+
+ if (!meta->findRect(
+ kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
+
+ cropLeft = cropTop = 0;
+ cropRight = vWidth - 1;
+ cropBottom = vHeight - 1;
+
+ ALOGD("got dimensions only %d x %d", vWidth, vHeight);
+ } else {
+ ALOGD("got crop rect %d, %d, %d, %d",
+ cropLeft, cropTop, cropRight, cropBottom);
+ }
+
+ mCropRect.left = cropLeft;
+ mCropRect.right = cropRight;
+ mCropRect.top = cropTop;
+ mCropRect.bottom = cropBottom;
+
+ int32_t displayWidth;
+ if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
+ ALOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth);
+ mDisplayWidth = displayWidth;
+ }
+ int32_t displayHeight;
+ if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
+ ALOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight);
+ mDisplayHeight = displayHeight;
+ }
+
+ int32_t usableWidth = cropRight - cropLeft + 1;
+ int32_t usableHeight = cropBottom - cropTop + 1;
+ if (mDisplayWidth != 0) {
+ usableWidth = mDisplayWidth;
+ }
+ if (mDisplayHeight != 0) {
+ usableHeight = mDisplayHeight;
+ }
+
+ int32_t rotationDegrees;
+ if (!mVideoTrack->getFormat()->findInt32(
+ kKeyRotation, &rotationDegrees)) {
+ rotationDegrees = 0;
+ }
+
+ if (rotationDegrees == 90 || rotationDegrees == 270) {
+ notifyListener_l(
+ MEDIA_SET_VIDEO_SIZE, usableHeight, usableWidth);
+ } else {
+ notifyListener_l(
+ MEDIA_SET_VIDEO_SIZE, usableWidth, usableHeight);
+ }
+}
+
+status_t PreviewPlayer::pause() {
+ Mutex::Autolock autoLock(mLock);
+
+ mFlags &= ~CACHE_UNDERRUN;
+
+ return pause_l();
+}
+
+status_t PreviewPlayer::pause_l(bool at_eos) {
+ if (!(mFlags & PLAYING)) {
+ return OK;
+ }
+
+ cancelPlayerEvents_l();
+
+ if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
+ if (at_eos) {
+ // If we played the audio stream to completion we
+ // want to make sure that all samples remaining in the audio
+ // track's queue are played out.
+ mAudioPlayer->pause(true /* playPendingSamples */);
+ } else {
+ mAudioPlayer->pause();
+ }
+
+ mFlags &= ~AUDIO_RUNNING;
+ }
+
+ mFlags &= ~PLAYING;
+ updateBatteryUsage_l();
+
+ return OK;
+}
+
+bool PreviewPlayer::isPlaying() const {
+ return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
+}
+
+void PreviewPlayer::setSurface(const sp<Surface> &surface) {
+ Mutex::Autolock autoLock(mLock);
+
+ mSurface = surface;
+ setNativeWindow_l(surface);
+}
+
+void PreviewPlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
+ Mutex::Autolock autoLock(mLock);
+
+ mSurface.clear();
+ if (surfaceTexture != NULL) {
+ setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
+ }
+}
+
+void PreviewPlayer::shutdownVideoDecoder_l() {
+ if (mVideoBuffer) {
+ mVideoBuffer->release();
+ mVideoBuffer = NULL;
+ }
+
+ mVideoSource->stop();
+
+ // The following hack is necessary to ensure that the OMX
+ // component is completely released by the time we may try
+ // to instantiate it again.
+ wp<MediaSource> tmp = mVideoSource;
+ mVideoSource.clear();
+ while (tmp.promote() != NULL) {
+ usleep(1000);
+ }
+ IPCThreadState::self()->flushCommands();
+}
+
+void PreviewPlayer::setNativeWindow_l(const sp<ANativeWindow> &native) {
+ mNativeWindow = native;
+
+ if (mVideoSource == NULL) {
+ return;
+ }
+
+ ALOGI("attempting to reconfigure to use new surface");
+
+ bool wasPlaying = (mFlags & PLAYING) != 0;
+
+ pause_l();
+
+ shutdownVideoDecoder_l();
+
+ CHECK_EQ(initVideoDecoder_l(), (status_t)OK);
+
+ if (mLastVideoTimeUs >= 0) {
+ mSeeking = SEEK;
+ mSeekNotificationSent = true;
+ mSeekTimeUs = mLastVideoTimeUs;
+ mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
+ }
+
+ if (wasPlaying) {
+ play_l();
+ }
+}
+
+void PreviewPlayer::setAudioSink(
+ const sp<MediaPlayerBase::AudioSink> &audioSink) {
+ Mutex::Autolock autoLock(mLock);
+
+ mAudioSink = audioSink;
+}
+
+status_t PreviewPlayer::setLooping(bool shouldLoop) {
+ Mutex::Autolock autoLock(mLock);
+
+ mFlags = mFlags & ~LOOPING;
+
+ if (shouldLoop) {
+ mFlags |= LOOPING;
+ }
+
+ return OK;
+}
+
+void PreviewPlayer::setDuration_l(int64_t durationUs) {
+ if (mDurationUs < 0 || durationUs > mDurationUs) {
+ mDurationUs = durationUs;
+ }
+}
+
+status_t PreviewPlayer::getDuration(int64_t *durationUs) {
+ Mutex::Autolock autoLock(mLock);
+ if (mDurationUs < 0) {
+ return UNKNOWN_ERROR;
+ }
+
+ *durationUs = mDurationUs;
+ return OK;
+}
+
+status_t PreviewPlayer::getPosition(int64_t *positionUs) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mSeeking != NO_SEEK) {
+ *positionUs = mSeekTimeUs;
+ } else if (mVideoSource != NULL
+ && (mAudioPlayer == NULL || !(mFlags & VIDEO_AT_EOS))) {
+ *positionUs = mVideoTimeUs;
+ } else if (mAudioPlayer != NULL) {
+ *positionUs = mAudioPlayer->getMediaTimeUs();
+ } else {
+ *positionUs = 0;
+ }
+
+ return OK;
+}
+
+void PreviewPlayer::setPosition_l(int64_t timeUs) {
+ mVideoTimeUs = timeUs;
+}
+
+status_t PreviewPlayer::seekTo_l(int64_t timeUs) {
+ ALOGV("seekTo_l");
+ if (mFlags & CACHE_UNDERRUN) {
+ mFlags &= ~CACHE_UNDERRUN;
+ play_l();
+ }
+
+ if ((mFlags & PLAYING) && mVideoSource != NULL && (mFlags & VIDEO_AT_EOS)) {
+ // Video playback completed before, there's no pending
+ // video event right now. In order for this new seek
+ // to be honored, we need to post one.
+
+ postVideoEvent_l();
+ }
+
+ mSeeking = SEEK;
+ mSeekNotificationSent = false;
+ mSeekTimeUs = timeUs;
+ mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
+
+ seekAudioIfNecessary_l();
+
+ if (!(mFlags & PLAYING)) {
+ ALOGV("seeking while paused, sending SEEK_COMPLETE notification"
+ " immediately.");
+
+ notifyListener_l(MEDIA_SEEK_COMPLETE);
+ mSeekNotificationSent = true;
+
+ if ((mFlags & PREPARED) && mVideoSource != NULL) {
+ mFlags |= SEEK_PREVIEW;
+ postVideoEvent_l();
+ }
+ }
+
+ return OK;
+}
+
+void PreviewPlayer::seekAudioIfNecessary_l() {
+ if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
+ mAudioPlayer->seekTo(mSeekTimeUs);
+
+ mWatchForAudioSeekComplete = true;
+ mWatchForAudioEOS = true;
+ }
+}
+
+void PreviewPlayer::setAudioSource(const sp<MediaSource>& source) {
+ CHECK(source != NULL);
+ mAudioTrack = source;
+}
+
+void PreviewPlayer::setVideoSource(const sp<MediaSource>& source) {
+ CHECK(source != NULL);
+ mVideoTrack = source;
+}
+
+void PreviewPlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
+ if (mSeeking == SEEK_VIDEO_ONLY) {
+ mSeeking = NO_SEEK;
+ return;
+ }
+
+ if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
+ return;
+ }
+
+ if (mAudioPlayer != NULL) {
+ ALOGV("seeking audio to %lld us (%.2f secs).", videoTimeUs, videoTimeUs / 1E6);
+
+ // If we don't have a video time, seek audio to the originally
+ // requested seek time instead.
+
+ mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
+ mWatchForAudioSeekComplete = true;
+ mWatchForAudioEOS = true;
+ } else if (!mSeekNotificationSent) {
+ // If we're playing video only, report seek complete now,
+ // otherwise audio player will notify us later.
+ notifyListener_l(MEDIA_SEEK_COMPLETE);
+ mSeekNotificationSent = true;
+ }
+
+ mFlags |= FIRST_FRAME;
+ mSeeking = NO_SEEK;
+}
+
+void PreviewPlayer::onCheckAudioStatus() {
+ Mutex::Autolock autoLock(mLock);
+ if (!mAudioStatusEventPending) {
+ // Event was dispatched and while we were blocking on the mutex,
+ // has already been cancelled.
+ return;
+ }
+
+ mAudioStatusEventPending = false;
+
+ if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
+ mWatchForAudioSeekComplete = false;
+
+ if (!mSeekNotificationSent) {
+ notifyListener_l(MEDIA_SEEK_COMPLETE);
+ mSeekNotificationSent = true;
+ }
+
+ mSeeking = NO_SEEK;
+ }
+
+ status_t finalStatus;
+ if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
+ mWatchForAudioEOS = false;
+ mFlags |= AUDIO_AT_EOS;
+ mFlags |= FIRST_FRAME;
+ postStreamDoneEvent_l(finalStatus);
+ }
+}
+
+void PreviewPlayer::postVideoEvent_l(int64_t delayUs) {
+ if (mVideoEventPending) {
+ return;
+ }
+
+ mVideoEventPending = true;
+ mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
+}
+
+void PreviewPlayer::postStreamDoneEvent_l(status_t status) {
+ if (mStreamDoneEventPending) {
+ return;
+ }
+ mStreamDoneEventPending = true;
+
+ mStreamDoneStatus = status;
+ mQueue.postEvent(mStreamDoneEvent);
+}
+
+void PreviewPlayer::postVideoLagEvent_l() {
+ if (mVideoLagEventPending) {
+ return;
+ }
+ mVideoLagEventPending = true;
+ mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
+}
+
+void PreviewPlayer::postCheckAudioStatusEvent_l(int64_t delayUs) {
+ if (mAudioStatusEventPending) {
+ return;
+ }
+ mAudioStatusEventPending = true;
+ mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
+}
+
+void PreviewPlayer::abortPrepare(status_t err) {
+ CHECK(err != OK);
+
+ if (mIsAsyncPrepare) {
+ notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
+ }
+
+ mPrepareResult = err;
+ mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED);
+ mAsyncPrepareEvent = NULL;
+ mPreparedCondition.broadcast();
+}
+
+uint32_t PreviewPlayer::getSourceSeekFlags() const {
+ Mutex::Autolock lock(mLock);
+ return mExtractorFlags;
+}
+
+void PreviewPlayer::postAudioEOS(int64_t delayUs) {
+ Mutex::Autolock autoLock(mLock);
+ postCheckAudioStatusEvent_l(delayUs);
+}
+
+void PreviewPlayer::postAudioSeekComplete() {
+ Mutex::Autolock autoLock(mLock);
+ postCheckAudioStatusEvent_l(0 /* delayUs */);
+}
+
+void PreviewPlayer::updateBatteryUsage_l() {
+ uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
+ if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
+ params |= IMediaPlayerService::kBatteryDataTrackAudio;
+ }
+ if (mVideoSource != NULL) {
+ params |= IMediaPlayerService::kBatteryDataTrackVideo;
+ }
+ addBatteryData(params);
+}
+
} // namespace android
diff --git a/libvideoeditor/lvpp/PreviewPlayer.h b/libvideoeditor/lvpp/PreviewPlayer.h
index a5afaee..45f3fc2 100755
--- a/libvideoeditor/lvpp/PreviewPlayer.h
+++ b/libvideoeditor/lvpp/PreviewPlayer.h
@@ -25,35 +25,51 @@
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/TimeSource.h>
#include <utils/threads.h>
-#include "PreviewPlayerBase.h"
-#include "VideoEditorPreviewController.h"
#include "NativeWindowRenderer.h"
namespace android {
+struct VideoEditorAudioPlayer;
struct AudioPlayerBase;
struct MediaExtractor;
-struct PreviewPlayer : public PreviewPlayerBase {
+struct PreviewPlayer {
PreviewPlayer(NativeWindowRenderer* renderer);
~PreviewPlayer();
- //Override baseclass methods
+ void setListener(const wp<MediaPlayerBase> &listener);
void reset();
status_t play();
+ status_t pause();
+ bool isPlaying() const;
+ void setSurface(const sp<Surface> &surface);
+ void setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
status_t seekTo(int64_t timeUs);
status_t getVideoDimensions(int32_t *width, int32_t *height) const;
+
+ // FIXME: Sync between ...
void acquireLock();
void releaseLock();
status_t prepare();
+ status_t prepareAsync();
status_t setDataSource(const char *path);
+ status_t setDataSource(const sp<IStreamSource> &source);
+
+ void setAudioSink(const sp<MediaPlayerBase::AudioSink> &audioSink);
+ status_t setLooping(bool shouldLoop);
+ status_t getDuration(int64_t *durationUs);
+ status_t getPosition(int64_t *positionUs);
+
+ uint32_t getSourceSeekFlags() const;
+
+ void postAudioEOS(int64_t delayUs = 0ll);
+ void postAudioSeekComplete();
- //Added methods
status_t loadEffectsSettings(M4VSS3GPP_EffectSettings* pEffectSettings,
int nEffects);
status_t loadAudioMixSettings(M4xVSS_AudioMixingSettings* pAudioMixSettings);
@@ -76,8 +92,6 @@ struct PreviewPlayer : public PreviewPlayerBase {
status_t setAudioPlayer(AudioPlayerBase *audioPlayer);
private:
- friend struct PreviewPlayerEvent;
-
enum {
PLAYING = 1,
LOOPING = 2,
@@ -91,23 +105,92 @@ private:
VIDEO_AT_EOS = 512,
AUTO_LOOPING = 1024,
INFORMED_AV_EOS = 2048,
+
+ // We are basically done preparing but are currently buffering
+ // sufficient data to begin playback and finish the preparation phase
+ // for good.
+ PREPARING_CONNECTED = 2048,
+
+ // We're triggering a single video event to display the first frame
+ // after the seekpoint.
+ SEEK_PREVIEW = 4096,
+
+ AUDIO_RUNNING = 8192,
+ AUDIOPLAYER_STARTED = 16384,
+
+ INCOGNITO = 32768,
};
- void cancelPlayerEvents();
- status_t setDataSource_l(const sp<MediaExtractor> &extractor);
- status_t setDataSource_l(const char *path);
- void reset_l();
- status_t play_l();
- status_t initRenderer_l();
- status_t initAudioDecoder();
- status_t initVideoDecoder(uint32_t flags = 0);
- void onVideoEvent();
- void onStreamDone();
- status_t finishSetDataSource_l();
- static bool ContinuePreparation(void *cookie);
- void onPrepareAsyncEvent();
- void finishAsyncPrepare_l();
- status_t startAudioPlayer_l();
+ mutable Mutex mLock;
+
+ OMXClient mClient;
+ TimedEventQueue mQueue;
+ bool mQueueStarted;
+ wp<MediaPlayerBase> mListener;
+
+ sp<Surface> mSurface;
+ sp<ANativeWindow> mNativeWindow;
+ sp<MediaPlayerBase::AudioSink> mAudioSink;
+
+ SystemTimeSource mSystemTimeSource;
+ TimeSource *mTimeSource;
+
+ String8 mUri;
+
+ sp<MediaSource> mVideoTrack;
+ sp<MediaSource> mVideoSource;
+ bool mVideoRendererIsPreview;
+
+ sp<MediaSource> mAudioTrack;
+ sp<MediaSource> mAudioSource;
+ AudioPlayerBase *mAudioPlayer;
+ int64_t mDurationUs;
+
+ int32_t mDisplayWidth;
+ int32_t mDisplayHeight;
+
+ uint32_t mFlags;
+ uint32_t mExtractorFlags;
+
+ int64_t mTimeSourceDeltaUs;
+ int64_t mVideoTimeUs;
+
+ enum SeekType {
+ NO_SEEK,
+ SEEK,
+ SEEK_VIDEO_ONLY
+ };
+ SeekType mSeeking;
+
+ bool mSeekNotificationSent;
+ int64_t mSeekTimeUs;
+
+ int64_t mBitrate; // total bitrate of the file (in bps) or -1 if unknown.
+
+ bool mWatchForAudioSeekComplete;
+ bool mWatchForAudioEOS;
+
+ sp<TimedEventQueue::Event> mVideoEvent;
+ bool mVideoEventPending;
+ sp<TimedEventQueue::Event> mStreamDoneEvent;
+ bool mStreamDoneEventPending;
+ sp<TimedEventQueue::Event> mCheckAudioStatusEvent;
+ bool mAudioStatusEventPending;
+ sp<TimedEventQueue::Event> mVideoLagEvent;
+ bool mVideoLagEventPending;
+
+ sp<TimedEventQueue::Event> mAsyncPrepareEvent;
+ Condition mPreparedCondition;
+ bool mIsAsyncPrepare;
+ status_t mPrepareResult;
+ status_t mStreamDoneStatus;
+
+ MediaBuffer *mVideoBuffer;
+ int64_t mLastVideoTimeUs;
+ ARect mCropRect;
+ int32_t mGivenWidth, mGivenHeight;
+
+
bool mIsChangeSourceRequired;
NativeWindowRenderer *mNativeWindowRenderer;
@@ -152,23 +235,60 @@ private:
M4VIFI_UInt8* mFrameRGBBuffer;
M4VIFI_UInt8* mFrameYUVBuffer;
+ VideoEditorAudioPlayer *mVeAudioPlayer;
+ void cancelPlayerEvents_l(bool updateProgressCb = false);
+ status_t setDataSource_l(const sp<MediaExtractor> &extractor);
+ status_t setDataSource_l(const char *path);
+ void setNativeWindow_l(const sp<ANativeWindow> &native);
+ void reset_l();
+ void clear_l();
+ status_t play_l();
+ status_t pause_l(bool at_eos = false);
+ status_t initRenderer_l();
+ status_t initAudioDecoder_l();
+ status_t initVideoDecoder_l(uint32_t flags = 0);
+ void notifyVideoSize_l();
+ void notifyListener_l(int msg, int ext1 = 0, int ext2 = 0);
+ void onVideoEvent();
+ void onVideoLagUpdate();
+ void onStreamDone();
+ void onCheckAudioStatus();
+ void onPrepareAsyncEvent();
+
+ void finishAsyncPrepare_l();
+ void abortPrepare(status_t err);
+
+ status_t startAudioPlayer_l();
+ void setVideoSource(const sp<MediaSource>& source);
+ status_t finishSetDataSource_l();
+ void setAudioSource(const sp<MediaSource>& source);
+
+ status_t seekTo_l(int64_t timeUs);
+ void seekAudioIfNecessary_l();
+ void finishSeekIfNecessary(int64_t videoTimeUs);
+
+ void postCheckAudioStatusEvent_l(int64_t delayUs);
+ void postVideoLagEvent_l();
+ void postStreamDoneEvent_l(status_t status);
+ void postVideoEvent_l(int64_t delayUs = -1);
void setVideoPostProcessingNode(
M4VSS3GPP_VideoEffectType type, M4OSA_Bool enable);
void postProgressCallbackEvent_l();
+ void shutdownVideoDecoder_l();
void onProgressCbEvent();
void postOverlayUpdateEvent_l();
void onUpdateOverlayEvent();
status_t setDataSource_l_jpg();
-
status_t prepare_l();
status_t prepareAsync_l();
-
+ void updateBatteryUsage_l();
void updateSizeToRender(sp<MetaData> meta);
- VideoEditorAudioPlayer *mVeAudioPlayer;
+ void setDuration_l(int64_t durationUs);
+ void setPosition_l(int64_t timeUs);
PreviewPlayer(const PreviewPlayer &);
PreviewPlayer &operator=(const PreviewPlayer &);
diff --git a/libvideoeditor/lvpp/PreviewPlayerBase.cpp b/libvideoeditor/lvpp/PreviewPlayerBase.cpp
deleted file mode 100644
index 2a59095..0000000
--- a/libvideoeditor/lvpp/PreviewPlayerBase.cpp
+++ /dev/null
@@ -1,1456 +0,0 @@
-/*
- * 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_NDEBUG 0
-#define LOG_TAG "PreviewPlayerBase"
-#include <utils/Log.h>
-
-#include <dlfcn.h>
-
-#include "PreviewPlayerBase.h"
-#include "AudioPlayerBase.h"
-#include "include/SoftwareRenderer.h"
-
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <media/IMediaPlayerService.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/DataSource.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaExtractor.h>
-#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/OMXCodec.h>
-
-#include <surfaceflinger/Surface.h>
-#include <gui/ISurfaceTexture.h>
-#include <gui/SurfaceTextureClient.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-
-#include <cutils/properties.h>
-
-#define USE_SURFACE_ALLOC 1
-
-namespace android {
-
-struct AwesomeEvent : public TimedEventQueue::Event {
- AwesomeEvent(
- PreviewPlayerBase *player,
- void (PreviewPlayerBase::*method)())
- : mPlayer(player),
- mMethod(method) {
- }
-
-protected:
- virtual ~AwesomeEvent() {}
-
- virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
- (mPlayer->*mMethod)();
- }
-
-private:
- PreviewPlayerBase *mPlayer;
- void (PreviewPlayerBase::*mMethod)();
-
- AwesomeEvent(const AwesomeEvent &);
- AwesomeEvent &operator=(const AwesomeEvent &);
-};
-
-struct AwesomeLocalRenderer : public AwesomeRenderer {
- AwesomeLocalRenderer(
- const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
- : mTarget(new SoftwareRenderer(nativeWindow, meta)) {
- }
-
- virtual void render(MediaBuffer *buffer) {
- render((const uint8_t *)buffer->data() + buffer->range_offset(),
- buffer->range_length());
- }
-
- void render(const void *data, size_t size) {
- mTarget->render(data, size, NULL);
- }
-
-protected:
- virtual ~AwesomeLocalRenderer() {
- delete mTarget;
- mTarget = NULL;
- }
-
-private:
- SoftwareRenderer *mTarget;
-
- AwesomeLocalRenderer(const AwesomeLocalRenderer &);
- AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);;
-};
-
-struct AwesomeNativeWindowRenderer : public AwesomeRenderer {
- AwesomeNativeWindowRenderer(
- const sp<ANativeWindow> &nativeWindow,
- int32_t rotationDegrees)
- : mNativeWindow(nativeWindow) {
- applyRotation(rotationDegrees);
- }
-
- virtual void render(MediaBuffer *buffer) {
- status_t err = mNativeWindow->queueBuffer(
- mNativeWindow.get(), buffer->graphicBuffer().get());
- if (err != 0) {
- ALOGE("queueBuffer failed with error %s (%d)", strerror(-err),
- -err);
- return;
- }
-
- sp<MetaData> metaData = buffer->meta_data();
- metaData->setInt32(kKeyRendered, 1);
- }
-
-protected:
- virtual ~AwesomeNativeWindowRenderer() {}
-
-private:
- sp<ANativeWindow> mNativeWindow;
-
- void applyRotation(int32_t rotationDegrees) {
- uint32_t transform;
- switch (rotationDegrees) {
- case 0: transform = 0; break;
- case 90: transform = HAL_TRANSFORM_ROT_90; break;
- case 180: transform = HAL_TRANSFORM_ROT_180; break;
- case 270: transform = HAL_TRANSFORM_ROT_270; break;
- default: transform = 0; break;
- }
-
- if (transform) {
- CHECK_EQ(0, native_window_set_buffers_transform(
- mNativeWindow.get(), transform));
- }
- }
-
- AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &);
- AwesomeNativeWindowRenderer &operator=(
- const AwesomeNativeWindowRenderer &);
-};
-
-// To collect the decoder usage
-void addBatteryData(uint32_t params) {
- sp<IBinder> binder =
- defaultServiceManager()->getService(String16("media.player"));
- sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
- CHECK(service.get() != NULL);
-
- service->addBatteryData(params);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-PreviewPlayerBase::PreviewPlayerBase()
- : mQueueStarted(false),
- mTimeSource(NULL),
- mVideoRendererIsPreview(false),
- mAudioPlayer(NULL),
- mDisplayWidth(0),
- mDisplayHeight(0),
- mFlags(0),
- mExtractorFlags(0),
- mVideoBuffer(NULL),
- mLastVideoTimeUs(-1) {
- CHECK_EQ(mClient.connect(), (status_t)OK);
-
- DataSource::RegisterDefaultSniffers();
-
- mVideoEvent = new AwesomeEvent(this, &PreviewPlayerBase::onVideoEvent);
- mVideoEventPending = false;
- mStreamDoneEvent = new AwesomeEvent(this, &PreviewPlayerBase::onStreamDone);
- mStreamDoneEventPending = false;
- mVideoLagEvent = new AwesomeEvent(this, &PreviewPlayerBase::onVideoLagUpdate);
- mVideoEventPending = false;
-
- mCheckAudioStatusEvent = new AwesomeEvent(
- this, &PreviewPlayerBase::onCheckAudioStatus);
-
- mAudioStatusEventPending = false;
-
- reset();
-}
-
-PreviewPlayerBase::~PreviewPlayerBase() {
- if (mQueueStarted) {
- mQueue.stop();
- }
-
- reset();
-
- mClient.disconnect();
-}
-
-void PreviewPlayerBase::cancelPlayerEvents() {
- mQueue.cancelEvent(mVideoEvent->eventID());
- mVideoEventPending = false;
- mQueue.cancelEvent(mStreamDoneEvent->eventID());
- mStreamDoneEventPending = false;
- mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
- mAudioStatusEventPending = false;
- mQueue.cancelEvent(mVideoLagEvent->eventID());
- mVideoLagEventPending = false;
-}
-
-void PreviewPlayerBase::setListener(const wp<MediaPlayerBase> &listener) {
- Mutex::Autolock autoLock(mLock);
- mListener = listener;
-}
-
-status_t PreviewPlayerBase::setDataSource(const char *path) {
- Mutex::Autolock autoLock(mLock);
- return setDataSource_l(path);
-}
-
-status_t PreviewPlayerBase::setDataSource_l(const char *path) {
- reset_l();
-
- mUri = path;
-
- if (!(mFlags & INCOGNITO)) {
- ALOGI("setDataSource_l('%s')", mUri.string());
- } else {
- ALOGI("setDataSource_l(URL suppressed)");
- }
-
- // The actual work will be done during preparation in the call to
- // ::finishSetDataSource_l to avoid blocking the calling thread in
- // setDataSource for any significant time.
-
- return OK;
-}
-
-status_t PreviewPlayerBase::setDataSource(const sp<IStreamSource> &source) {
- return INVALID_OPERATION;
-}
-
-status_t PreviewPlayerBase::setDataSource_l(const sp<MediaExtractor> &extractor) {
- if (extractor == NULL) {
- return UNKNOWN_ERROR;
- }
-
- if (extractor->getDrmFlag()) {
- ALOGE("Data source is drm protected");
- return INVALID_OPERATION;
- }
-
- // Attempt to approximate overall stream bitrate by summing all
- // tracks' individual bitrates, if not all of them advertise bitrate,
- // we have to fail.
-
- int64_t totalBitRate = 0;
-
- for (size_t i = 0; i < extractor->countTracks(); ++i) {
- sp<MetaData> meta = extractor->getTrackMetaData(i);
-
- int32_t bitrate;
- if (!meta->findInt32(kKeyBitRate, &bitrate)) {
- totalBitRate = -1;
- break;
- }
-
- totalBitRate += bitrate;
- }
-
- mBitrate = totalBitRate;
-
- ALOGV("mBitrate = %lld bits/sec", mBitrate);
-
- bool haveAudio = false;
- bool haveVideo = false;
- for (size_t i = 0; i < extractor->countTracks(); ++i) {
- sp<MetaData> meta = extractor->getTrackMetaData(i);
-
- const char *mime;
- CHECK(meta->findCString(kKeyMIMEType, &mime));
-
- if (!haveVideo && !strncasecmp(mime, "video/", 6)) {
- setVideoSource(extractor->getTrack(i));
- haveVideo = true;
-
- // Set the presentation/display size
- int32_t displayWidth, displayHeight;
- bool success = meta->findInt32(kKeyDisplayWidth, &displayWidth);
- if (success) {
- success = meta->findInt32(kKeyDisplayHeight, &displayHeight);
- }
- if (success) {
- mDisplayWidth = displayWidth;
- mDisplayHeight = displayHeight;
- }
-
- } else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
- setAudioSource(extractor->getTrack(i));
- haveAudio = true;
-
- if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
- // Only do this for vorbis audio, none of the other audio
- // formats even support this ringtone specific hack and
- // retrieving the metadata on some extractors may turn out
- // to be very expensive.
- sp<MetaData> fileMeta = extractor->getMetaData();
- int32_t loop;
- if (fileMeta != NULL
- && fileMeta->findInt32(kKeyAutoLoop, &loop) && loop != 0) {
- mFlags |= AUTO_LOOPING;
- }
- }
- }
-
- if (haveAudio && haveVideo) {
- break;
- }
- }
-
- if (!haveAudio && !haveVideo) {
- return UNKNOWN_ERROR;
- }
-
- mExtractorFlags = extractor->flags();
-
- return OK;
-}
-
-void PreviewPlayerBase::reset() {
- Mutex::Autolock autoLock(mLock);
- reset_l();
-}
-
-void PreviewPlayerBase::reset_l() {
- mDisplayWidth = 0;
- mDisplayHeight = 0;
-
- if (mFlags & PLAYING) {
- uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
- if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
- params |= IMediaPlayerService::kBatteryDataTrackAudio;
- }
- if (mVideoSource != NULL) {
- params |= IMediaPlayerService::kBatteryDataTrackVideo;
- }
- addBatteryData(params);
- }
-
- if (mFlags & PREPARING) {
- mFlags |= PREPARE_CANCELLED;
-
- if (mFlags & PREPARING_CONNECTED) {
- // We are basically done preparing, we're just buffering
- // enough data to start playback, we can safely interrupt that.
- finishAsyncPrepare_l();
- }
- }
-
- while (mFlags & PREPARING) {
- mPreparedCondition.wait(mLock);
- }
-
- cancelPlayerEvents();
-
- mAudioTrack.clear();
- mVideoTrack.clear();
-
- // Shutdown audio first, so that the respone to the reset request
- // appears to happen instantaneously as far as the user is concerned
- // If we did this later, audio would continue playing while we
- // shutdown the video-related resources and the player appear to
- // not be as responsive to a reset request.
- if (mAudioPlayer == NULL && mAudioSource != NULL) {
- // If we had an audio player, it would have effectively
- // taken possession of the audio source and stopped it when
- // _it_ is stopped. Otherwise this is still our responsibility.
- mAudioSource->stop();
- }
- mAudioSource.clear();
-
- mTimeSource = NULL;
-
- delete mAudioPlayer;
- mAudioPlayer = NULL;
-
- mVideoRenderer.clear();
-
- if (mVideoSource != NULL) {
- shutdownVideoDecoder_l();
- }
-
- mDurationUs = -1;
- mFlags = 0;
- mExtractorFlags = 0;
- mTimeSourceDeltaUs = 0;
- mVideoTimeUs = 0;
-
- mSeeking = NO_SEEK;
- mSeekNotificationSent = false;
- mSeekTimeUs = 0;
-
- mUri.setTo("");
-
- mBitrate = -1;
- mLastVideoTimeUs = -1;
-}
-
-void PreviewPlayerBase::notifyListener_l(int msg, int ext1, int ext2) {
- if (mListener != NULL) {
- sp<MediaPlayerBase> listener = mListener.promote();
-
- if (listener != NULL) {
- listener->sendEvent(msg, ext1, ext2);
- }
- }
-}
-
-void PreviewPlayerBase::onVideoLagUpdate() {
- Mutex::Autolock autoLock(mLock);
- if (!mVideoLagEventPending) {
- return;
- }
- mVideoLagEventPending = false;
-
- int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs();
- int64_t videoLateByUs = audioTimeUs - mVideoTimeUs;
-
- if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) {
- ALOGV("video late by %lld ms.", videoLateByUs / 1000ll);
-
- notifyListener_l(
- MEDIA_INFO,
- MEDIA_INFO_VIDEO_TRACK_LAGGING,
- videoLateByUs / 1000ll);
- }
-
- postVideoLagEvent_l();
-}
-
-void PreviewPlayerBase::onStreamDone() {
- // Posted whenever any stream finishes playing.
-
- Mutex::Autolock autoLock(mLock);
- if (!mStreamDoneEventPending) {
- return;
- }
- mStreamDoneEventPending = false;
-
- if (mStreamDoneStatus != ERROR_END_OF_STREAM) {
- ALOGV("MEDIA_ERROR %d", mStreamDoneStatus);
-
- notifyListener_l(
- MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus);
-
- pause_l(true /* at eos */);
-
- mFlags |= AT_EOS;
- return;
- }
-
- const bool allDone =
- (mVideoSource == NULL || (mFlags & VIDEO_AT_EOS))
- && (mAudioSource == NULL || (mFlags & AUDIO_AT_EOS));
-
- if (!allDone) {
- return;
- }
-
- if (mFlags & (LOOPING | AUTO_LOOPING)) {
- seekTo_l(0);
-
- if (mVideoSource != NULL) {
- postVideoEvent_l();
- }
- } else {
- ALOGV("MEDIA_PLAYBACK_COMPLETE");
- notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
-
- pause_l(true /* at eos */);
-
- mFlags |= AT_EOS;
- }
-}
-
-status_t PreviewPlayerBase::play() {
- Mutex::Autolock autoLock(mLock);
-
- mFlags &= ~CACHE_UNDERRUN;
-
- return play_l();
-}
-
-status_t PreviewPlayerBase::play_l() {
- mFlags &= ~SEEK_PREVIEW;
-
- if (mFlags & PLAYING) {
- return OK;
- }
-
- if (!(mFlags & PREPARED)) {
- status_t err = prepare_l();
-
- if (err != OK) {
- return err;
- }
- }
-
- mFlags |= PLAYING;
- mFlags |= FIRST_FRAME;
-
- if (mAudioSource != NULL) {
- if (mAudioPlayer == NULL) {
- if (mAudioSink != NULL) {
- mAudioPlayer = new AudioPlayerBase(mAudioSink, this);
- mAudioPlayer->setSource(mAudioSource);
-
- mTimeSource = mAudioPlayer;
-
- // If there was a seek request before we ever started,
- // honor the request now.
- // Make sure to do this before starting the audio player
- // to avoid a race condition.
- seekAudioIfNecessary_l();
- }
- }
-
- CHECK(!(mFlags & AUDIO_RUNNING));
-
- if (mVideoSource == NULL) {
- status_t err = startAudioPlayer_l();
-
- if (err != OK) {
- delete mAudioPlayer;
- mAudioPlayer = NULL;
-
- mFlags &= ~(PLAYING | FIRST_FRAME);
-
- return err;
- }
- }
- }
-
- if (mTimeSource == NULL && mAudioPlayer == NULL) {
- mTimeSource = &mSystemTimeSource;
- }
-
- if (mVideoSource != NULL) {
- // Kick off video playback
- postVideoEvent_l();
-
- if (mAudioSource != NULL && mVideoSource != NULL) {
- postVideoLagEvent_l();
- }
- }
-
- if (mFlags & AT_EOS) {
- // Legacy behaviour, if a stream finishes playing and then
- // is started again, we play from the start...
- seekTo_l(0);
- }
-
- uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted
- | IMediaPlayerService::kBatteryDataTrackDecoder;
- if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
- params |= IMediaPlayerService::kBatteryDataTrackAudio;
- }
- if (mVideoSource != NULL) {
- params |= IMediaPlayerService::kBatteryDataTrackVideo;
- }
- addBatteryData(params);
-
- return OK;
-}
-
-status_t PreviewPlayerBase::startAudioPlayer_l() {
- CHECK(!(mFlags & AUDIO_RUNNING));
-
- if (mAudioSource == NULL || mAudioPlayer == NULL) {
- return OK;
- }
-
- if (!(mFlags & AUDIOPLAYER_STARTED)) {
- mFlags |= AUDIOPLAYER_STARTED;
-
- // We've already started the MediaSource in order to enable
- // the prefetcher to read its data.
- status_t err = mAudioPlayer->start(
- true /* sourceAlreadyStarted */);
-
- if (err != OK) {
- notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
- return err;
- }
- } else {
- mAudioPlayer->resume();
- }
-
- mFlags |= AUDIO_RUNNING;
-
- mWatchForAudioEOS = true;
-
- return OK;
-}
-
-void PreviewPlayerBase::notifyVideoSize_l() {
- sp<MetaData> meta = mVideoSource->getFormat();
-
- int32_t vWidth, vHeight;
- int32_t cropLeft, cropTop, cropRight, cropBottom;
-
- CHECK(meta->findInt32(kKeyWidth, &vWidth));
- CHECK(meta->findInt32(kKeyHeight, &vHeight));
-
- mGivenWidth = vWidth;
- mGivenHeight = vHeight;
-
- if (!meta->findRect(
- kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
-
- cropLeft = cropTop = 0;
- cropRight = vWidth - 1;
- cropBottom = vHeight - 1;
-
- ALOGD("got dimensions only %d x %d", vWidth, vHeight);
- } else {
- ALOGD("got crop rect %d, %d, %d, %d",
- cropLeft, cropTop, cropRight, cropBottom);
- }
-
- mCropRect.left = cropLeft;
- mCropRect.right = cropRight;
- mCropRect.top = cropTop;
- mCropRect.bottom = cropBottom;
-
- int32_t displayWidth;
- if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
- ALOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth);
- mDisplayWidth = displayWidth;
- }
- int32_t displayHeight;
- if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
- ALOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight);
- mDisplayHeight = displayHeight;
- }
-
- int32_t usableWidth = cropRight - cropLeft + 1;
- int32_t usableHeight = cropBottom - cropTop + 1;
- if (mDisplayWidth != 0) {
- usableWidth = mDisplayWidth;
- }
- if (mDisplayHeight != 0) {
- usableHeight = mDisplayHeight;
- }
-
- int32_t rotationDegrees;
- if (!mVideoTrack->getFormat()->findInt32(
- kKeyRotation, &rotationDegrees)) {
- rotationDegrees = 0;
- }
-
- if (rotationDegrees == 90 || rotationDegrees == 270) {
- notifyListener_l(
- MEDIA_SET_VIDEO_SIZE, usableHeight, usableWidth);
- } else {
- notifyListener_l(
- MEDIA_SET_VIDEO_SIZE, usableWidth, usableHeight);
- }
-}
-
-void PreviewPlayerBase::initRenderer_l() {
- if (mNativeWindow == NULL) {
- return;
- }
-
- sp<MetaData> meta = mVideoSource->getFormat();
-
- int32_t format;
- const char *component;
- CHECK(meta->findInt32(kKeyColorFormat, &format));
- CHECK(meta->findCString(kKeyDecoderComponent, &component));
-
- int32_t rotationDegrees;
- if (!mVideoTrack->getFormat()->findInt32(
- kKeyRotation, &rotationDegrees)) {
- rotationDegrees = 0;
- }
-
- mVideoRenderer.clear();
-
- // Must ensure that mVideoRenderer's destructor is actually executed
- // before creating a new one.
- IPCThreadState::self()->flushCommands();
-
- if (USE_SURFACE_ALLOC && strncmp(component, "OMX.", 4) == 0) {
- // Hardware decoders avoid the CPU color conversion by decoding
- // directly to ANativeBuffers, so we must use a renderer that
- // just pushes those buffers to the ANativeWindow.
- mVideoRenderer =
- new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees);
- } else {
- // Other decoders are instantiated locally and as a consequence
- // allocate their buffers in local address space. This renderer
- // then performs a color conversion and copy to get the data
- // into the ANativeBuffer.
- mVideoRenderer = new AwesomeLocalRenderer(mNativeWindow, meta);
- }
-}
-
-status_t PreviewPlayerBase::pause() {
- Mutex::Autolock autoLock(mLock);
-
- mFlags &= ~CACHE_UNDERRUN;
-
- return pause_l();
-}
-
-status_t PreviewPlayerBase::pause_l(bool at_eos) {
- if (!(mFlags & PLAYING)) {
- return OK;
- }
-
- cancelPlayerEvents();
-
- if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
- if (at_eos) {
- // If we played the audio stream to completion we
- // want to make sure that all samples remaining in the audio
- // track's queue are played out.
- mAudioPlayer->pause(true /* playPendingSamples */);
- } else {
- mAudioPlayer->pause();
- }
-
- mFlags &= ~AUDIO_RUNNING;
- }
-
- mFlags &= ~PLAYING;
-
- uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
- if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
- params |= IMediaPlayerService::kBatteryDataTrackAudio;
- }
- if (mVideoSource != NULL) {
- params |= IMediaPlayerService::kBatteryDataTrackVideo;
- }
-
- addBatteryData(params);
-
- return OK;
-}
-
-bool PreviewPlayerBase::isPlaying() const {
- return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
-}
-
-void PreviewPlayerBase::setSurface(const sp<Surface> &surface) {
- Mutex::Autolock autoLock(mLock);
-
- mSurface = surface;
- setNativeWindow_l(surface);
-}
-
-void PreviewPlayerBase::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
- Mutex::Autolock autoLock(mLock);
-
- mSurface.clear();
- if (surfaceTexture != NULL) {
- setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
- }
-}
-
-void PreviewPlayerBase::shutdownVideoDecoder_l() {
- if (mVideoBuffer) {
- mVideoBuffer->release();
- mVideoBuffer = NULL;
- }
-
- mVideoSource->stop();
-
- // The following hack is necessary to ensure that the OMX
- // component is completely released by the time we may try
- // to instantiate it again.
- wp<MediaSource> tmp = mVideoSource;
- mVideoSource.clear();
- while (tmp.promote() != NULL) {
- usleep(1000);
- }
- IPCThreadState::self()->flushCommands();
-}
-
-void PreviewPlayerBase::setNativeWindow_l(const sp<ANativeWindow> &native) {
- mNativeWindow = native;
-
- if (mVideoSource == NULL) {
- return;
- }
-
- ALOGI("attempting to reconfigure to use new surface");
-
- bool wasPlaying = (mFlags & PLAYING) != 0;
-
- pause_l();
- mVideoRenderer.clear();
-
- shutdownVideoDecoder_l();
-
- CHECK_EQ(initVideoDecoder(), (status_t)OK);
-
- if (mLastVideoTimeUs >= 0) {
- mSeeking = SEEK;
- mSeekNotificationSent = true;
- mSeekTimeUs = mLastVideoTimeUs;
- mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
- }
-
- if (wasPlaying) {
- play_l();
- }
-}
-
-void PreviewPlayerBase::setAudioSink(
- const sp<MediaPlayerBase::AudioSink> &audioSink) {
- Mutex::Autolock autoLock(mLock);
-
- mAudioSink = audioSink;
-}
-
-status_t PreviewPlayerBase::setLooping(bool shouldLoop) {
- Mutex::Autolock autoLock(mLock);
-
- mFlags = mFlags & ~LOOPING;
-
- if (shouldLoop) {
- mFlags |= LOOPING;
- }
-
- return OK;
-}
-
-status_t PreviewPlayerBase::getDuration(int64_t *durationUs) {
- Mutex::Autolock autoLock(mMiscStateLock);
-
- if (mDurationUs < 0) {
- return UNKNOWN_ERROR;
- }
-
- *durationUs = mDurationUs;
-
- return OK;
-}
-
-status_t PreviewPlayerBase::getPosition(int64_t *positionUs) {
- if (mSeeking != NO_SEEK) {
- *positionUs = mSeekTimeUs;
- } else if (mVideoSource != NULL
- && (mAudioPlayer == NULL || !(mFlags & VIDEO_AT_EOS))) {
- Mutex::Autolock autoLock(mMiscStateLock);
- *positionUs = mVideoTimeUs;
- } else if (mAudioPlayer != NULL) {
- *positionUs = mAudioPlayer->getMediaTimeUs();
- } else {
- *positionUs = 0;
- }
-
- return OK;
-}
-
-status_t PreviewPlayerBase::seekTo(int64_t timeUs) {
- if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
- Mutex::Autolock autoLock(mLock);
- return seekTo_l(timeUs);
- }
-
- return OK;
-}
-
-status_t PreviewPlayerBase::seekTo_l(int64_t timeUs) {
- if (mFlags & CACHE_UNDERRUN) {
- mFlags &= ~CACHE_UNDERRUN;
- play_l();
- }
-
- if ((mFlags & PLAYING) && mVideoSource != NULL && (mFlags & VIDEO_AT_EOS)) {
- // Video playback completed before, there's no pending
- // video event right now. In order for this new seek
- // to be honored, we need to post one.
-
- postVideoEvent_l();
- }
-
- mSeeking = SEEK;
- mSeekNotificationSent = false;
- mSeekTimeUs = timeUs;
- mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
-
- seekAudioIfNecessary_l();
-
- if (!(mFlags & PLAYING)) {
- ALOGV("seeking while paused, sending SEEK_COMPLETE notification"
- " immediately.");
-
- notifyListener_l(MEDIA_SEEK_COMPLETE);
- mSeekNotificationSent = true;
-
- if ((mFlags & PREPARED) && mVideoSource != NULL) {
- mFlags |= SEEK_PREVIEW;
- postVideoEvent_l();
- }
- }
-
- return OK;
-}
-
-void PreviewPlayerBase::seekAudioIfNecessary_l() {
- if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
- mAudioPlayer->seekTo(mSeekTimeUs);
-
- mWatchForAudioSeekComplete = true;
- mWatchForAudioEOS = true;
- }
-}
-
-void PreviewPlayerBase::setAudioSource(sp<MediaSource> source) {
- CHECK(source != NULL);
-
- mAudioTrack = source;
-}
-
-status_t PreviewPlayerBase::initAudioDecoder() {
- sp<MetaData> meta = mAudioTrack->getFormat();
-
- const char *mime;
- CHECK(meta->findCString(kKeyMIMEType, &mime));
-
- if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
- mAudioSource = mAudioTrack;
- } else {
- mAudioSource = OMXCodec::Create(
- mClient.interface(), mAudioTrack->getFormat(),
- false, // createEncoder
- mAudioTrack);
- }
-
- if (mAudioSource != NULL) {
- int64_t durationUs;
- if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
- Mutex::Autolock autoLock(mMiscStateLock);
- if (mDurationUs < 0 || durationUs > mDurationUs) {
- mDurationUs = durationUs;
- }
- }
-
- status_t err = mAudioSource->start();
-
- if (err != OK) {
- mAudioSource.clear();
- return err;
- }
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
- // For legacy reasons we're simply going to ignore the absence
- // of an audio decoder for QCELP instead of aborting playback
- // altogether.
- return OK;
- }
-
- return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
-}
-
-void PreviewPlayerBase::setVideoSource(sp<MediaSource> source) {
- CHECK(source != NULL);
-
- mVideoTrack = source;
-}
-
-status_t PreviewPlayerBase::initVideoDecoder(uint32_t flags) {
- ALOGV("initVideoDecoder flags=0x%x", flags);
- mVideoSource = OMXCodec::Create(
- mClient.interface(), mVideoTrack->getFormat(),
- false, // createEncoder
- mVideoTrack,
- NULL, flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL);
-
- if (mVideoSource != NULL) {
- int64_t durationUs;
- if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
- Mutex::Autolock autoLock(mMiscStateLock);
- if (mDurationUs < 0 || durationUs > mDurationUs) {
- mDurationUs = durationUs;
- }
- }
-
- status_t err = mVideoSource->start();
-
- if (err != OK) {
- mVideoSource.clear();
- return err;
- }
- }
-
- return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
-}
-
-void PreviewPlayerBase::finishSeekIfNecessary(int64_t videoTimeUs) {
- if (mSeeking == SEEK_VIDEO_ONLY) {
- mSeeking = NO_SEEK;
- return;
- }
-
- if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
- return;
- }
-
- if (mAudioPlayer != NULL) {
- ALOGV("seeking audio to %lld us (%.2f secs).", videoTimeUs, videoTimeUs / 1E6);
-
- // If we don't have a video time, seek audio to the originally
- // requested seek time instead.
-
- mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
- mWatchForAudioSeekComplete = true;
- mWatchForAudioEOS = true;
- } else if (!mSeekNotificationSent) {
- // If we're playing video only, report seek complete now,
- // otherwise audio player will notify us later.
- notifyListener_l(MEDIA_SEEK_COMPLETE);
- mSeekNotificationSent = true;
- }
-
- mFlags |= FIRST_FRAME;
- mSeeking = NO_SEEK;
-}
-
-void PreviewPlayerBase::onVideoEvent() {
- Mutex::Autolock autoLock(mLock);
- if (!mVideoEventPending) {
- // The event has been cancelled in reset_l() but had already
- // been scheduled for execution at that time.
- return;
- }
- mVideoEventPending = false;
-
- if (mSeeking != NO_SEEK) {
- if (mVideoBuffer) {
- mVideoBuffer->release();
- mVideoBuffer = NULL;
- }
- }
-
- if (!mVideoBuffer) {
- MediaSource::ReadOptions options;
- if (mSeeking != NO_SEEK) {
- ALOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
-
- options.setSeekTo(
- mSeekTimeUs,
- mSeeking == SEEK_VIDEO_ONLY
- ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
- : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
- }
- for (;;) {
- status_t err = mVideoSource->read(&mVideoBuffer, &options);
- options.clearSeekTo();
-
- if (err != OK) {
- CHECK(mVideoBuffer == NULL);
-
- if (err == INFO_FORMAT_CHANGED) {
- ALOGV("VideoSource signalled format change.");
-
- notifyVideoSize_l();
-
- if (mVideoRenderer != NULL) {
- mVideoRendererIsPreview = false;
- initRenderer_l();
- }
- continue;
- }
-
- // So video playback is complete, but we may still have
- // a seek request pending that needs to be applied
- // to the audio track.
- if (mSeeking != NO_SEEK) {
- ALOGV("video stream ended while seeking!");
- }
- finishSeekIfNecessary(-1);
-
- if (mAudioPlayer != NULL
- && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
- startAudioPlayer_l();
- }
-
- mFlags |= VIDEO_AT_EOS;
- postStreamDoneEvent_l(err);
- return;
- }
-
- if (mVideoBuffer->range_length() == 0) {
- // Some decoders, notably the PV AVC software decoder
- // return spurious empty buffers that we just want to ignore.
-
- mVideoBuffer->release();
- mVideoBuffer = NULL;
- continue;
- }
-
- break;
- }
- }
-
- int64_t timeUs;
- CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
-
- mLastVideoTimeUs = timeUs;
-
- if (mSeeking == SEEK_VIDEO_ONLY) {
- if (mSeekTimeUs > timeUs) {
- ALOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us",
- mSeekTimeUs, timeUs);
- }
- }
-
- {
- Mutex::Autolock autoLock(mMiscStateLock);
- mVideoTimeUs = timeUs;
- }
-
- SeekType wasSeeking = mSeeking;
- finishSeekIfNecessary(timeUs);
-
- if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
- status_t err = startAudioPlayer_l();
- if (err != OK) {
- ALOGE("Startung the audio player failed w/ err %d", err);
- return;
- }
- }
-
- TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource;
-
- if (mFlags & FIRST_FRAME) {
- mFlags &= ~FIRST_FRAME;
- mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
- }
-
- int64_t realTimeUs, mediaTimeUs;
- if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL
- && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {
- mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
- }
-
- if (wasSeeking == SEEK_VIDEO_ONLY) {
- int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
-
- int64_t latenessUs = nowUs - timeUs;
-
- if (latenessUs > 0) {
- ALOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6);
- }
- }
-
- if (wasSeeking == NO_SEEK) {
- // Let's display the first frame after seeking right away.
-
- int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
-
- int64_t latenessUs = nowUs - timeUs;
-
- if (latenessUs > 500000ll
- && mAudioPlayer != NULL
- && mAudioPlayer->getMediaTimeMapping(
- &realTimeUs, &mediaTimeUs)) {
- ALOGI("we're much too late (%.2f secs), video skipping ahead",
- latenessUs / 1E6);
-
- mVideoBuffer->release();
- mVideoBuffer = NULL;
-
- mSeeking = SEEK_VIDEO_ONLY;
- mSeekTimeUs = mediaTimeUs;
-
- postVideoEvent_l();
- return;
- }
-
- if (latenessUs > 40000) {
- // We're more than 40ms late.
- ALOGV("we're late by %lld us (%.2f secs), dropping frame",
- latenessUs, latenessUs / 1E6);
- mVideoBuffer->release();
- mVideoBuffer = NULL;
-
- postVideoEvent_l();
- return;
- }
-
- if (latenessUs < -10000) {
- // We're more than 10ms early.
-
- postVideoEvent_l(10000);
- return;
- }
- }
-
- if (mVideoRendererIsPreview || mVideoRenderer == NULL) {
- mVideoRendererIsPreview = false;
-
- initRenderer_l();
- }
-
- if (mVideoRenderer != NULL) {
- mVideoRenderer->render(mVideoBuffer);
- }
-
- mVideoBuffer->release();
- mVideoBuffer = NULL;
-
- if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
- mFlags &= ~SEEK_PREVIEW;
- return;
- }
-
- postVideoEvent_l();
-}
-
-void PreviewPlayerBase::postVideoEvent_l(int64_t delayUs) {
- if (mVideoEventPending) {
- return;
- }
-
- mVideoEventPending = true;
- mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
-}
-
-void PreviewPlayerBase::postStreamDoneEvent_l(status_t status) {
- if (mStreamDoneEventPending) {
- return;
- }
- mStreamDoneEventPending = true;
-
- mStreamDoneStatus = status;
- mQueue.postEvent(mStreamDoneEvent);
-}
-
-void PreviewPlayerBase::postVideoLagEvent_l() {
- if (mVideoLagEventPending) {
- return;
- }
- mVideoLagEventPending = true;
- mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
-}
-
-void PreviewPlayerBase::postCheckAudioStatusEvent_l(int64_t delayUs) {
- if (mAudioStatusEventPending) {
- return;
- }
- mAudioStatusEventPending = true;
- mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
-}
-
-void PreviewPlayerBase::onCheckAudioStatus() {
- Mutex::Autolock autoLock(mLock);
- if (!mAudioStatusEventPending) {
- // Event was dispatched and while we were blocking on the mutex,
- // has already been cancelled.
- return;
- }
-
- mAudioStatusEventPending = false;
-
- if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
- mWatchForAudioSeekComplete = false;
-
- if (!mSeekNotificationSent) {
- notifyListener_l(MEDIA_SEEK_COMPLETE);
- mSeekNotificationSent = true;
- }
-
- mSeeking = NO_SEEK;
- }
-
- status_t finalStatus;
- if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
- mWatchForAudioEOS = false;
- mFlags |= AUDIO_AT_EOS;
- mFlags |= FIRST_FRAME;
- postStreamDoneEvent_l(finalStatus);
- }
-}
-
-status_t PreviewPlayerBase::prepare() {
- Mutex::Autolock autoLock(mLock);
- return prepare_l();
-}
-
-status_t PreviewPlayerBase::prepare_l() {
- if (mFlags & PREPARED) {
- return OK;
- }
-
- if (mFlags & PREPARING) {
- return UNKNOWN_ERROR;
- }
-
- mIsAsyncPrepare = false;
- status_t err = prepareAsync_l();
-
- if (err != OK) {
- return err;
- }
-
- while (mFlags & PREPARING) {
- mPreparedCondition.wait(mLock);
- }
-
- return mPrepareResult;
-}
-
-status_t PreviewPlayerBase::prepareAsync() {
- Mutex::Autolock autoLock(mLock);
-
- if (mFlags & PREPARING) {
- return UNKNOWN_ERROR; // async prepare already pending
- }
-
- mIsAsyncPrepare = true;
- return prepareAsync_l();
-}
-
-status_t PreviewPlayerBase::prepareAsync_l() {
- if (mFlags & PREPARING) {
- return UNKNOWN_ERROR; // async prepare already pending
- }
-
- if (!mQueueStarted) {
- mQueue.start();
- mQueueStarted = true;
- }
-
- mFlags |= PREPARING;
- mAsyncPrepareEvent = new AwesomeEvent(
- this, &PreviewPlayerBase::onPrepareAsyncEvent);
-
- mQueue.postEvent(mAsyncPrepareEvent);
-
- return OK;
-}
-
-status_t PreviewPlayerBase::finishSetDataSource_l() {
- sp<DataSource> dataSource =
- DataSource::CreateFromURI(mUri.string(), NULL);
-
- if (dataSource == NULL) {
- return UNKNOWN_ERROR;
- }
-
- sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
-
- return setDataSource_l(extractor);
-}
-
-void PreviewPlayerBase::abortPrepare(status_t err) {
- CHECK(err != OK);
-
- if (mIsAsyncPrepare) {
- notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
- }
-
- mPrepareResult = err;
- mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED);
- mAsyncPrepareEvent = NULL;
- mPreparedCondition.broadcast();
-}
-
-// static
-bool PreviewPlayerBase::ContinuePreparation(void *cookie) {
- PreviewPlayerBase *me = static_cast<PreviewPlayerBase *>(cookie);
-
- return (me->mFlags & PREPARE_CANCELLED) == 0;
-}
-
-void PreviewPlayerBase::onPrepareAsyncEvent() {
- Mutex::Autolock autoLock(mLock);
-
- if (mFlags & PREPARE_CANCELLED) {
- ALOGI("prepare was cancelled before doing anything");
- abortPrepare(UNKNOWN_ERROR);
- return;
- }
-
- if (mUri.size() > 0) {
- status_t err = finishSetDataSource_l();
-
- if (err != OK) {
- abortPrepare(err);
- return;
- }
- }
-
- if (mVideoTrack != NULL && mVideoSource == NULL) {
- status_t err = initVideoDecoder();
-
- if (err != OK) {
- abortPrepare(err);
- return;
- }
- }
-
- if (mAudioTrack != NULL && mAudioSource == NULL) {
- status_t err = initAudioDecoder();
-
- if (err != OK) {
- abortPrepare(err);
- return;
- }
- }
-
- mFlags |= PREPARING_CONNECTED;
-
- finishAsyncPrepare_l();
-}
-
-void PreviewPlayerBase::finishAsyncPrepare_l() {
- if (mIsAsyncPrepare) {
- if (mVideoSource == NULL) {
- notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
- } else {
- notifyVideoSize_l();
- }
-
- notifyListener_l(MEDIA_PREPARED);
- }
-
- mPrepareResult = OK;
- mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED);
- mFlags |= PREPARED;
- mAsyncPrepareEvent = NULL;
- mPreparedCondition.broadcast();
-}
-
-uint32_t PreviewPlayerBase::flags() const {
- return mExtractorFlags;
-}
-
-void PreviewPlayerBase::postAudioEOS(int64_t delayUs) {
- Mutex::Autolock autoLock(mLock);
- postCheckAudioStatusEvent_l(delayUs);
-}
-
-void PreviewPlayerBase::postAudioSeekComplete() {
- Mutex::Autolock autoLock(mLock);
- postCheckAudioStatusEvent_l(0 /* delayUs */);
-}
-
-} // namespace android
diff --git a/libvideoeditor/lvpp/PreviewPlayerBase.h b/libvideoeditor/lvpp/PreviewPlayerBase.h
deleted file mode 100644
index 750df49..0000000
--- a/libvideoeditor/lvpp/PreviewPlayerBase.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * 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 PREVIEW_PLAYER_BASE_H_
-
-#define PREVIEW_PLAYER_BASE_H_
-
-#include "TimedEventQueue.h"
-
-#include <media/MediaPlayerInterface.h>
-#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/OMXClient.h>
-#include <media/stagefright/TimeSource.h>
-#include <utils/threads.h>
-
-namespace android {
-
-struct AudioPlayerBase;
-struct MediaBuffer;
-struct MediaExtractor;
-struct MediaSource;
-struct ISurfaceTexture;
-
-struct AwesomeRenderer : public RefBase {
- AwesomeRenderer() {}
-
- virtual void render(MediaBuffer *buffer) = 0;
-
-private:
- AwesomeRenderer(const AwesomeRenderer &);
- AwesomeRenderer &operator=(const AwesomeRenderer &);
-};
-
-struct PreviewPlayerBase {
- PreviewPlayerBase();
- ~PreviewPlayerBase();
-
- void setListener(const wp<MediaPlayerBase> &listener);
-
- status_t setDataSource(const char *path);
- status_t setDataSource(const sp<IStreamSource> &source);
-
- void reset();
-
- status_t prepare();
- status_t prepare_l();
- status_t prepareAsync();
- status_t prepareAsync_l();
-
- status_t play();
- status_t pause();
-
- bool isPlaying() const;
-
- void setSurface(const sp<Surface> &surface);
- void setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
- void setAudioSink(const sp<MediaPlayerBase::AudioSink> &audioSink);
- status_t setLooping(bool shouldLoop);
-
- status_t getDuration(int64_t *durationUs);
- status_t getPosition(int64_t *positionUs);
-
- status_t seekTo(int64_t timeUs);
-
- // This is a mask of MediaExtractor::Flags.
- uint32_t flags() const;
-
- void postAudioEOS(int64_t delayUs = 0ll);
- void postAudioSeekComplete();
-
-private:
- friend struct AwesomeEvent;
- friend struct PreviewPlayer;
-
- enum {
- PLAYING = 1,
- LOOPING = 2,
- FIRST_FRAME = 4,
- PREPARING = 8,
- PREPARED = 16,
- AT_EOS = 32,
- PREPARE_CANCELLED = 64,
- CACHE_UNDERRUN = 128,
- AUDIO_AT_EOS = 256,
- VIDEO_AT_EOS = 512,
- AUTO_LOOPING = 1024,
-
- // We are basically done preparing but are currently buffering
- // sufficient data to begin playback and finish the preparation phase
- // for good.
- PREPARING_CONNECTED = 2048,
-
- // We're triggering a single video event to display the first frame
- // after the seekpoint.
- SEEK_PREVIEW = 4096,
-
- AUDIO_RUNNING = 8192,
- AUDIOPLAYER_STARTED = 16384,
-
- INCOGNITO = 32768,
- };
-
- mutable Mutex mLock;
- Mutex mMiscStateLock;
-
- OMXClient mClient;
- TimedEventQueue mQueue;
- bool mQueueStarted;
- wp<MediaPlayerBase> mListener;
-
- sp<Surface> mSurface;
- sp<ANativeWindow> mNativeWindow;
- sp<MediaPlayerBase::AudioSink> mAudioSink;
-
- SystemTimeSource mSystemTimeSource;
- TimeSource *mTimeSource;
-
- String8 mUri;
- KeyedVector<String8, String8> mUriHeaders;
-
- sp<MediaSource> mVideoTrack;
- sp<MediaSource> mVideoSource;
- sp<AwesomeRenderer> mVideoRenderer;
- bool mVideoRendererIsPreview;
-
- sp<MediaSource> mAudioTrack;
- sp<MediaSource> mAudioSource;
- AudioPlayerBase *mAudioPlayer;
- int64_t mDurationUs;
-
- int32_t mDisplayWidth;
- int32_t mDisplayHeight;
-
- uint32_t mFlags;
- uint32_t mExtractorFlags;
-
- int64_t mTimeSourceDeltaUs;
- int64_t mVideoTimeUs;
-
- enum SeekType {
- NO_SEEK,
- SEEK,
- SEEK_VIDEO_ONLY
- };
- SeekType mSeeking;
-
- bool mSeekNotificationSent;
- int64_t mSeekTimeUs;
-
- int64_t mBitrate; // total bitrate of the file (in bps) or -1 if unknown.
-
- bool mWatchForAudioSeekComplete;
- bool mWatchForAudioEOS;
-
- sp<TimedEventQueue::Event> mVideoEvent;
- bool mVideoEventPending;
- sp<TimedEventQueue::Event> mStreamDoneEvent;
- bool mStreamDoneEventPending;
- sp<TimedEventQueue::Event> mCheckAudioStatusEvent;
- bool mAudioStatusEventPending;
- sp<TimedEventQueue::Event> mVideoLagEvent;
- bool mVideoLagEventPending;
-
- sp<TimedEventQueue::Event> mAsyncPrepareEvent;
- Condition mPreparedCondition;
- bool mIsAsyncPrepare;
- status_t mPrepareResult;
- status_t mStreamDoneStatus;
-
- void postVideoEvent_l(int64_t delayUs = -1);
- void postBufferingEvent_l();
- void postStreamDoneEvent_l(status_t status);
- void postCheckAudioStatusEvent_l(int64_t delayUs);
- void postVideoLagEvent_l();
- status_t play_l();
-
- MediaBuffer *mVideoBuffer;
-
- int64_t mLastVideoTimeUs;
-
- ARect mCropRect;
- int32_t mGivenWidth, mGivenHeight;
-
- status_t setDataSource_l(const char *path);
- status_t setDataSource_l(const sp<MediaExtractor> &extractor);
- void reset_l();
- status_t seekTo_l(int64_t timeUs);
- status_t pause_l(bool at_eos = false);
- void initRenderer_l();
- void notifyVideoSize_l();
- void seekAudioIfNecessary_l();
-
- void cancelPlayerEvents();
-
- void setAudioSource(sp<MediaSource> source);
- status_t initAudioDecoder();
-
- void setVideoSource(sp<MediaSource> source);
- status_t initVideoDecoder(uint32_t flags = 0);
-
- void onStreamDone();
-
- void notifyListener_l(int msg, int ext1 = 0, int ext2 = 0);
-
- void onVideoEvent();
- void onBufferingUpdate();
- void onCheckAudioStatus();
- void onPrepareAsyncEvent();
- void abortPrepare(status_t err);
- void finishAsyncPrepare_l();
- void onVideoLagUpdate();
-
- status_t finishSetDataSource_l();
-
- static bool ContinuePreparation(void *cookie);
-
- void finishSeekIfNecessary(int64_t videoTimeUs);
-
- status_t startAudioPlayer_l();
-
- void shutdownVideoDecoder_l();
- void setNativeWindow_l(const sp<ANativeWindow> &native);
-
- PreviewPlayerBase(const PreviewPlayerBase &);
- PreviewPlayerBase &operator=(const PreviewPlayerBase &);
-};
-
-} // namespace android
-
-#endif // PREVIEW_PLAYER_BASE_H_
-
diff --git a/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp b/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp
index b3d63ed..0b642ac 100755
--- a/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp
+++ b/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp
@@ -34,7 +34,7 @@ namespace android {
VideoEditorAudioPlayer::VideoEditorAudioPlayer(
const sp<MediaPlayerBase::AudioSink> &audioSink,
- PreviewPlayerBase *observer)
+ PreviewPlayer *observer)
: AudioPlayerBase(audioSink, observer) {
ALOGV("VideoEditorAudioPlayer");
@@ -96,7 +96,7 @@ sp<MediaSource> VideoEditorAudioPlayer::getSource() {
return mSource;
}
-void VideoEditorAudioPlayer::setObserver(PreviewPlayerBase *observer) {
+void VideoEditorAudioPlayer::setObserver(PreviewPlayer *observer) {
ALOGV("setObserver");
//CHECK(!mStarted);
mObserver = observer;
diff --git a/libvideoeditor/lvpp/VideoEditorAudioPlayer.h b/libvideoeditor/lvpp/VideoEditorAudioPlayer.h
index 450a70a..2eab4c5 100755
--- a/libvideoeditor/lvpp/VideoEditorAudioPlayer.h
+++ b/libvideoeditor/lvpp/VideoEditorAudioPlayer.h
@@ -27,7 +27,7 @@
#include "M4OSA_FileReader.h"
#include "VideoEditorBGAudioProcessing.h"
#include "AudioPlayerBase.h"
-#include "PreviewPlayerBase.h"
+#include "PreviewPlayer.h"
namespace android {
@@ -44,7 +44,7 @@ public:
};
VideoEditorAudioPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink,
- PreviewPlayerBase *audioObserver = NULL);
+ PreviewPlayer *audioObserver = NULL);
virtual ~VideoEditorAudioPlayer();
@@ -58,7 +58,7 @@ public:
M4OSA_UInt32 pBGAudioCurrentMediaBeginCutTS,
M4OSA_UInt32 pBGAudioCurrentMediaVolumeVal);
- void setObserver(PreviewPlayerBase *observer);
+ void setObserver(PreviewPlayer *observer);
void setSource(const sp<MediaSource> &source);
sp<MediaSource> getSource();
diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.cpp b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
index 8e66f73..fa2834a 100755
--- a/libvideoeditor/lvpp/VideoEditorPlayer.cpp
+++ b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
@@ -201,7 +201,7 @@ status_t VideoEditorPlayer::getMetadata(
const media::Metadata::Filter& ids, Parcel *records) {
using media::Metadata;
- uint32_t flags = mPlayer->flags();
+ uint32_t flags = mPlayer->getSourceSeekFlags();
Metadata metadata(records);
diff --git a/libvideoeditor/lvpp/VideoEditorSRC.cpp b/libvideoeditor/lvpp/VideoEditorSRC.cpp
index 3e8c498..27ae26e 100755
--- a/libvideoeditor/lvpp/VideoEditorSRC.cpp
+++ b/libvideoeditor/lvpp/VideoEditorSRC.cpp
@@ -17,24 +17,27 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "VideoEditorSRC"
-#include "VideoEditorSRC.h"
+#include <stdlib.h>
+#include <utils/Log.h>
#include <audio_utils/primitives.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDefs.h>
#include "AudioMixer.h"
-#include <utils/Log.h>
+#include "VideoEditorSRC.h"
+
namespace android {
VideoEditorSRC::VideoEditorSRC(const sp<MediaSource> &source) {
- ALOGV("VideoEditorSRC::VideoEditorSRC %p(%p)", this, source.get());
+ ALOGV("VideoEditorSRC %p(%p)", this, source.get());
+ static const int32_t kDefaultSamplingFreqencyHz = kFreq32000Hz;
mSource = source;
mResampler = NULL;
mChannelCnt = 0;
mSampleRate = 0;
- mOutputSampleRate = DEFAULT_SAMPLING_FREQ;
+ mOutputSampleRate = kDefaultSamplingFreqencyHz;
mStarted = false;
mInitialTimeStampUs = -1;
mAccuOutBufferSize = 0;
@@ -54,18 +57,18 @@ VideoEditorSRC::VideoEditorSRC(const sp<MediaSource> &source) {
// Set the metadata of the output after resampling.
mOutputFormat = new MetaData;
mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
- mOutputFormat->setInt32(kKeySampleRate, DEFAULT_SAMPLING_FREQ);
- mOutputFormat->setInt32(kKeyChannelCount, 2);
+ mOutputFormat->setInt32(kKeySampleRate, kDefaultSamplingFreqencyHz);
+ mOutputFormat->setInt32(kKeyChannelCount, 2); // always stereo
}
VideoEditorSRC::~VideoEditorSRC() {
- ALOGV("VideoEditorSRC::~VideoEditorSRC %p(%p)", this, mSource.get());
+ ALOGV("~VideoEditorSRC %p(%p)", this, mSource.get());
stop();
}
status_t VideoEditorSRC::start(MetaData *params) {
+ ALOGV("start %p(%p)", this, mSource.get());
CHECK(!mStarted);
- ALOGV("VideoEditorSRC:start %p(%p)", this, mSource.get());
// Set resampler if required
checkAndSetResampler();
@@ -79,17 +82,21 @@ status_t VideoEditorSRC::start(MetaData *params) {
}
status_t VideoEditorSRC::stop() {
- ALOGV("VideoEditorSRC::stop %p(%p)", this, mSource.get());
- if (!mStarted) return OK;
+ ALOGV("stop %p(%p)", this, mSource.get());
+ if (!mStarted) {
+ return OK;
+ }
+
if (mBuffer) {
mBuffer->release();
mBuffer = NULL;
}
mSource->stop();
- if(mResampler != NULL) {
+ if (mResampler != NULL) {
delete mResampler;
mResampler = NULL;
}
+
mStarted = false;
mInitialTimeStampUs = -1;
mAccuOutBufferSize = 0;
@@ -99,13 +106,13 @@ status_t VideoEditorSRC::stop() {
}
sp<MetaData> VideoEditorSRC::getFormat() {
- ALOGV("VideoEditorSRC::getFormat");
+ ALOGV("getFormat");
return mOutputFormat;
}
status_t VideoEditorSRC::read(
MediaBuffer **buffer_out, const ReadOptions *options) {
- ALOGV("VideoEditorSRC::read %p(%p)", this, mSource.get());
+ ALOGV("read %p(%p)", this, mSource.get());
*buffer_out = NULL;
if (!mStarted) {
@@ -123,11 +130,17 @@ status_t VideoEditorSRC::read(
}
// We ask for 1024 frames in output
- const size_t outFrameCnt = 1024;
// resampler output is always 2 channels and 32 bits
- int32_t *pTmpBuffer = (int32_t *)calloc(1, outFrameCnt * 2 * sizeof(int32_t));
+ const size_t kOutputFrameCount = 1024;
+ const size_t kBytes = kOutputFrameCount * 2 * sizeof(int32_t);
+ int32_t *pTmpBuffer = (int32_t *)calloc(1, kBytes);
+ if (!pTmpBuffer) {
+ ALOGE("calloc failed to allocate memory: %d bytes", kBytes);
+ return NO_MEMORY;
+ }
+
// Resample to target quality
- mResampler->resample(pTmpBuffer, outFrameCnt, this);
+ mResampler->resample(pTmpBuffer, kOutputFrameCount, this);
if (mStopPending) {
stop();
@@ -143,13 +156,13 @@ status_t VideoEditorSRC::read(
}
// Create a new MediaBuffer
- int32_t outBufferSize = outFrameCnt * 2 * sizeof(int16_t);
+ int32_t outBufferSize = kOutputFrameCount * 2 * sizeof(int16_t);
MediaBuffer* outBuffer = new MediaBuffer(outBufferSize);
// Convert back to 2 channels and 16 bits
ditherAndClamp(
(int32_t *)((uint8_t*)outBuffer->data() + outBuffer->range_offset()),
- pTmpBuffer, outFrameCnt);
+ pTmpBuffer, kOutputFrameCount);
free(pTmpBuffer);
// Compute and set the new timestamp
@@ -187,7 +200,7 @@ status_t VideoEditorSRC::read(
}
status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) {
- ALOGV("Requesting %d, chan = %d", pBuffer->frameCount, mChannelCnt);
+ ALOGV("getNextBuffer %d, chan = %d", pBuffer->frameCount, mChannelCnt);
uint32_t done = 0;
uint32_t want = pBuffer->frameCount * mChannelCnt * 2;
pBuffer->raw = malloc(want);
@@ -272,6 +285,7 @@ status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) {
void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
+ ALOGV("releaseBuffer: %p", pBuffers);
free(pBuffer->raw);
pBuffer->raw = NULL;
pBuffer->frameCount = 0;
@@ -280,6 +294,7 @@ void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
void VideoEditorSRC::checkAndSetResampler() {
ALOGV("checkAndSetResampler");
+ static const uint16_t kUnityGain = 0x1000;
sp<MetaData> format = mSource->getFormat();
const char *mime;
CHECK(format->findCString(kKeyMIMEType, &mime));
@@ -301,7 +316,7 @@ void VideoEditorSRC::checkAndSetResampler() {
}
if (mSampleRate != mOutputSampleRate || mChannelCnt != 2) {
- ALOGV("Resampling required (in rate %d, out rate %d, in channel %d)",
+ ALOGV("Resampling required (%d => %d Hz, # channels = %d)",
mSampleRate, mOutputSampleRate, mChannelCnt);
mResampler = AudioResampler::create(
@@ -311,9 +326,10 @@ void VideoEditorSRC::checkAndSetResampler() {
AudioResampler::DEFAULT);
CHECK(mResampler);
mResampler->setSampleRate(mSampleRate);
- mResampler->setVolume(UNITY_GAIN, UNITY_GAIN);
+ mResampler->setVolume(kUnityGain, kUnityGain);
} else {
- ALOGV("Resampling not required (%d = %d)", mSampleRate, mOutputSampleRate);
+ ALOGV("Resampling not required (%d => %d Hz, # channels = %d)",
+ mSampleRate, mOutputSampleRate, mChannelCnt);
}
}
diff --git a/libvideoeditor/lvpp/VideoEditorSRC.h b/libvideoeditor/lvpp/VideoEditorSRC.h
index eabafde..3eb8c6c 100755
--- a/libvideoeditor/lvpp/VideoEditorSRC.h
+++ b/libvideoeditor/lvpp/VideoEditorSRC.h
@@ -14,13 +14,9 @@
* limitations under the License.
*/
-#include <stdint.h>
-
-#include <utils/RefBase.h>
-#include <utils/threads.h>
+#include <stdint.h>
#include <media/stagefright/MediaSource.h>
-
#include "AudioBufferProvider.h"
#include "AudioResampler.h"
@@ -30,61 +26,61 @@ struct MediaBuffer;
class VideoEditorSRC : public MediaSource , public AudioBufferProvider {
- public:
- VideoEditorSRC(
- const sp<MediaSource> &source);
+public:
+ VideoEditorSRC(const sp<MediaSource> &source);
- virtual status_t start (MetaData *params = NULL);
- virtual status_t stop();
- virtual sp<MetaData> getFormat();
- virtual status_t read (
- MediaBuffer **buffer, const ReadOptions *options = NULL);
+ virtual status_t start (MetaData *params = NULL);
+ virtual status_t stop();
+ virtual sp<MetaData> getFormat();
+ virtual status_t read (
+ MediaBuffer **buffer, const ReadOptions *options = NULL);
- virtual status_t getNextBuffer(Buffer* buffer);
- virtual void releaseBuffer(Buffer* buffer);
+ virtual status_t getNextBuffer(Buffer* buffer);
+ virtual void releaseBuffer(Buffer* buffer);
- enum { //Sampling freq
- kFreq8000Hz = 8000,
+ // Sampling freqencies
+ enum {
+ kFreq8000Hz = 8000,
kFreq11025Hz = 11025,
kFreq12000Hz = 12000,
kFreq16000Hz = 16000,
kFreq22050Hz = 22050,
kFreq24000Hz = 24000,
kFreq32000Hz = 32000,
- kFreq44100 = 44100,
- kFreq48000 = 48000,
+ kFreq44100Hz = 44100,
+ kFreq48000Hz = 48000,
};
- static const uint16_t UNITY_GAIN = 0x1000;
- static const int32_t DEFAULT_SAMPLING_FREQ = (int32_t)kFreq32000Hz;
+protected :
+ virtual ~VideoEditorSRC();
- protected :
- virtual ~VideoEditorSRC();
- private:
+private:
+ AudioResampler *mResampler;
+ sp<MediaSource> mSource;
+ int mChannelCnt;
+ int mSampleRate;
+ int32_t mOutputSampleRate;
+ bool mStarted;
+ sp<MetaData> mOutputFormat;
- VideoEditorSRC();
- VideoEditorSRC &operator=(const VideoEditorSRC &);
+ MediaBuffer* mBuffer;
+ int32_t mLeftover;
+ bool mFormatChanged;
+ bool mStopPending;
- void checkAndSetResampler();
+ int64_t mInitialTimeStampUs;
+ int64_t mAccuOutBufferSize;
- AudioResampler *mResampler;
- sp<MediaSource> mSource;
- int mChannelCnt;
- int mSampleRate;
- int32_t mOutputSampleRate;
- bool mStarted;
- sp<MetaData> mOutputFormat;
+ int64_t mSeekTimeUs;
+ ReadOptions::SeekMode mSeekMode;
- MediaBuffer* mBuffer;
- int32_t mLeftover;
- bool mFormatChanged;
- bool mStopPending;
+ VideoEditorSRC();
+ void checkAndSetResampler();
- int64_t mInitialTimeStampUs;
- int64_t mAccuOutBufferSize;
+ // Don't call me
+ VideoEditorSRC(const VideoEditorSRC&);
+ VideoEditorSRC &operator=(const VideoEditorSRC &);
- int64_t mSeekTimeUs;
- ReadOptions::SeekMode mSeekMode;
};
} //namespce android