Use GL to render preview.
To speed up the preview, we direct the decoder output to a
SurfaceTexture, then draw the texture to a surface. The media
rendering parameters (crop, black-border) are implemented
using different vertex coordinates. The color effects are
implemented using fragment shaders. Currently only three color
effects are implemented, but that's all the appplication uses.
Change-Id: If84439fee572ed37ea077749ef9f2bd4f78703e1
diff --git a/libvideoeditor/lvpp/PreviewPlayer.cpp b/libvideoeditor/lvpp/PreviewPlayer.cpp
index 78ca1cd..b63d0d2 100755
--- a/libvideoeditor/lvpp/PreviewPlayer.cpp
+++ b/libvideoeditor/lvpp/PreviewPlayer.cpp
@@ -30,8 +30,6 @@
#include "include/ThrottledSource.h"
-#include "PreviewRenderer.h"
-
#include <binder/IPCThreadState.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/FileSource.h>
@@ -72,13 +70,12 @@
PreviewPlayerEvent &operator=(const PreviewPlayerEvent &);
};
-PreviewPlayer::PreviewPlayer()
+PreviewPlayer::PreviewPlayer(NativeWindowRenderer* renderer)
: PreviewPlayerBase(),
- mCurrFramingEffectIndex(0) ,
- mReportedWidth(0),
- mReportedHeight(0),
+ mNativeWindowRenderer(renderer),
+ mCurrFramingEffectIndex(0),
mFrameRGBBuffer(NULL),
- mFrameYUVBuffer(NULL){
+ mFrameYUVBuffer(NULL) {
mVideoRenderer = NULL;
mEffectsSettings = NULL;
@@ -115,8 +112,6 @@
mProgressCbEventPending = false;
mOverlayUpdateEventPending = false;
- mResizedVideoBuffer = NULL;
- mVideoResizedOrCropped = false;
mRenderingMode = (M4xVSS_MediaRendering)MEDIA_RENDERING_INVALID;
mIsFiftiesEffectStarted = false;
reset();
@@ -130,12 +125,9 @@
reset();
- if(mResizedVideoBuffer != NULL) {
- free((mResizedVideoBuffer->data()));
- mResizedVideoBuffer = NULL;
+ if (mVideoRenderer) {
+ mNativeWindowRenderer->destroyRenderInput(mVideoRenderer);
}
-
- delete mVideoRenderer;
}
void PreviewPlayer::cancelPlayerEvents(bool keepBufferingGoing) {
@@ -249,9 +241,8 @@
mVideoSource = DummyVideoSource::Create(mVideoWidth, mVideoHeight,
mDurationUs, mUri);
- mReportedWidth = mVideoWidth;
- mReportedHeight = mVideoHeight;
+ updateSizeToRender(mVideoSource->getFormat());
setVideoSource(mVideoSource);
status_t err1 = mVideoSource->start();
if (err1 != OK) {
@@ -650,33 +641,11 @@
status_t PreviewPlayer::initRenderer_l() {
if (mSurface != NULL) {
- sp<MetaData> meta = mVideoSource->getFormat();
-
- const char *component;
- CHECK(meta->findCString(kKeyDecoderComponent, &component));
-
- // Must ensure that mVideoRenderer's destructor is actually executed
- // before creating a new one.
- IPCThreadState::self()->flushCommands();
-
- // always use localrenderer since decoded buffers are modified
- // by postprocessing module
- // Other decoders are instantiated locally and as a consequence
- // allocate their buffers in local address space.
if(mVideoRenderer == NULL) {
-
- mVideoRenderer = PreviewRenderer::CreatePreviewRenderer(
- OMX_COLOR_FormatYUV420Planar,
- mSurface,
- mOutputVideoWidth, mOutputVideoHeight,
- mOutputVideoWidth, mOutputVideoHeight,
- 0);
-
- if ( mVideoRenderer == NULL )
- {
- return UNKNOWN_ERROR;
+ mVideoRenderer = mNativeWindowRenderer->createRenderInput();
+ if (mVideoSource != NULL) {
+ updateSizeToRender(mVideoSource->getFormat());
}
- return OK;
}
}
return OK;
@@ -756,11 +725,18 @@
status_t PreviewPlayer::initVideoDecoder(uint32_t flags) {
+ initRenderer_l();
+
+ if (mVideoRenderer == NULL) {
+ LOGE("Cannot create renderer");
+ return UNKNOWN_ERROR;
+ }
+
mVideoSource = OMXCodec::Create(
mClient.interface(), mVideoTrack->getFormat(),
false,
mVideoTrack,
- NULL, flags);
+ NULL, flags, mVideoRenderer->getTargetWindow());
if (mVideoSource != NULL) {
int64_t durationUs;
@@ -771,9 +747,7 @@
}
}
- getVideoBufferSize(mVideoTrack->getFormat(), &mVideoWidth, &mVideoHeight);
- mReportedWidth = mVideoWidth;
- mReportedHeight = mVideoHeight;
+ updateSizeToRender(mVideoTrack->getFormat());
status_t err = mVideoSource->start();
@@ -838,7 +812,7 @@
mSeekTimeUs, MediaSource::ReadOptions::SEEK_CLOSEST);
}
for (;;) {
- status_t err = readYV12Buffer(mVideoSource, &mVideoBuffer, &options);
+ status_t err = mVideoSource->read(&mVideoBuffer, &options);
options.clearSeekTo();
if (err != OK) {
@@ -847,8 +821,6 @@
if (err == INFO_FORMAT_CHANGED) {
LOGV("LV PLAYER VideoSource signalled format change");
notifyVideoSize_l();
- sp<MetaData> meta = mVideoSource->getFormat();
- getVideoBufferSize(meta, &mReportedWidth, &mReportedHeight);
if (mVideoRenderer != NULL) {
mVideoRendererIsPreview = false;
@@ -858,6 +830,8 @@
}
}
+
+ updateSizeToRender(mVideoSource->getFormat());
continue;
}
// So video playback is complete, but we may still have
@@ -1081,28 +1055,9 @@
postOverlayUpdateEvent_l();
}
-
- if (mCurrentVideoEffect != VIDEO_EFFECT_NONE) {
- err1 = doVideoPostProcessing();
- if(err1 != M4NO_ERROR) {
- LOGE("doVideoPostProcessing returned err");
- }
- }
- else {
- if(mRenderingMode != MEDIA_RENDERING_INVALID) {
- // No effects to be applied, but media rendering to be done
- err1 = doMediaRendering();
- if(err1 != M4NO_ERROR) {
- LOGE("doMediaRendering returned err");
- //Use original mVideoBuffer for rendering
- mVideoResizedOrCropped = false;
- }
- }
- }
-
if (mVideoRenderer != NULL) {
- LOGV("mVideoRenderer CALL render()");
- mVideoRenderer->renderYV12();
+ mVideoRenderer->render(mVideoBuffer, mCurrentVideoEffect,
+ mRenderingMode, mIsVideoSourceJpg);
}
mVideoBuffer->release();
@@ -1362,9 +1317,6 @@
mRenderingMode = mode;
- /* reset boolean for each clip*/
- mVideoResizedOrCropped = false;
-
status_t err = OK;
/* get the video width and height by resolution */
err = getVideoSizeByResolution(outputVideoSize,
@@ -1373,56 +1325,6 @@
return err;
}
-M4OSA_ERR PreviewPlayer::doMediaRendering() {
- M4OSA_ERR err = M4NO_ERROR;
- M4VIFI_ImagePlane planeIn[3], planeOut[3];
- M4VIFI_UInt8 *inBuffer = M4OSA_NULL, *finalOutputBuffer = M4OSA_NULL;
- M4VIFI_UInt8 *tempOutputBuffer= M4OSA_NULL;
- size_t videoBufferSize = 0;
- M4OSA_UInt32 frameSize = 0, i=0, index =0, nFrameCount =0, bufferOffset =0;
-
- videoBufferSize = mVideoBuffer->size();
- frameSize = (mVideoWidth*mVideoHeight*3) >> 1;
-
- uint8_t* outBuffer;
- size_t outBufferStride = 0;
-
- mVideoRenderer->getBufferYV12(&outBuffer, &outBufferStride);
-
- bufferOffset = index*frameSize;
- inBuffer = (M4OSA_UInt8 *)mVideoBuffer->data()+
- mVideoBuffer->range_offset()+bufferOffset;
-
-
- /* In plane*/
- prepareYUV420ImagePlane(planeIn, mVideoWidth,
- mVideoHeight, (M4VIFI_UInt8 *)inBuffer, mReportedWidth, mReportedHeight);
-
- // Set the output YUV420 plane to be compatible with YV12 format
- // W & H even
- // YVU instead of YUV
- // align buffers on 32 bits
-
- //In YV12 format, sizes must be even
- M4OSA_UInt32 yv12PlaneWidth = ((mOutputVideoWidth +1)>>1)<<1;
- M4OSA_UInt32 yv12PlaneHeight = ((mOutputVideoHeight+1)>>1)<<1;
-
- prepareYV12ImagePlane(planeOut, yv12PlaneWidth, yv12PlaneHeight,
- (M4OSA_UInt32)outBufferStride, (M4VIFI_UInt8 *)outBuffer);
-
-
- err = applyRenderingMode(planeIn, planeOut, mRenderingMode);
-
- if(err != M4NO_ERROR)
- {
- LOGE("doMediaRendering: applyRenderingMode returned err=0x%x", (int)err);
- return err;
- }
- mVideoResizedOrCropped = true;
-
- return err;
-}
-
status_t PreviewPlayer::resetJniCallbackTimeStamp() {
mDecVideoTsStoryBoard = mStoryboardStartTimeMsec*1000LL;
@@ -1561,41 +1463,6 @@
return OK;
}
-
-M4OSA_ERR PreviewPlayer::doVideoPostProcessing() {
- M4OSA_ERR err = M4NO_ERROR;
- vePostProcessParams postProcessParams;
-
- postProcessParams.vidBuffer = (M4VIFI_UInt8*)mVideoBuffer->data()
- + mVideoBuffer->range_offset();
-
- postProcessParams.videoWidth = mVideoWidth;
- postProcessParams.videoHeight = mVideoHeight;
- postProcessParams.timeMs = mDecodedVideoTs/1000;
- postProcessParams.timeOffset = mDecVideoTsStoryBoard/1000;
- postProcessParams.effectsSettings = mEffectsSettings;
- postProcessParams.numberEffects = mNumberEffects;
- postProcessParams.outVideoWidth = mOutputVideoWidth;
- postProcessParams.outVideoHeight = mOutputVideoHeight;
- postProcessParams.currentVideoEffect = mCurrentVideoEffect;
- postProcessParams.renderingMode = mRenderingMode;
- if(mIsFiftiesEffectStarted == M4OSA_TRUE) {
- postProcessParams.isFiftiesEffectStarted = M4OSA_TRUE;
- mIsFiftiesEffectStarted = M4OSA_FALSE;
- }
- else {
- postProcessParams.isFiftiesEffectStarted = M4OSA_FALSE;
- }
-
- postProcessParams.overlayFrameRGBBuffer = mFrameRGBBuffer;
- postProcessParams.overlayFrameYUVBuffer = mFrameYUVBuffer;
- mVideoRenderer->getBufferYV12(&(postProcessParams.pOutBuffer),
- &(postProcessParams.outBufferStride));
- err = applyEffectsAndRenderingMode(&postProcessParams, mReportedWidth, mReportedHeight);
-
- return err;
-}
-
status_t PreviewPlayer::readFirstVideoFrame() {
LOGV("PreviewPlayer::readFirstVideoFrame");
@@ -1609,7 +1476,7 @@
mSeekTimeUs, MediaSource::ReadOptions::SEEK_CLOSEST);
}
for (;;) {
- status_t err = readYV12Buffer(mVideoSource, &mVideoBuffer, &options);
+ status_t err = mVideoSource->read(&mVideoBuffer, &options);
options.clearSeekTo();
if (err != OK) {
@@ -1618,8 +1485,6 @@
if (err == INFO_FORMAT_CHANGED) {
LOGV("LV PLAYER VideoSource signalled format change");
notifyVideoSize_l();
- sp<MetaData> meta = mVideoSource->getFormat();
- getVideoBufferSize(meta, &mReportedWidth, &mReportedHeight);
if (mVideoRenderer != NULL) {
mVideoRendererIsPreview = false;
@@ -1628,6 +1493,8 @@
postStreamDoneEvent_l(err);
}
}
+
+ updateSizeToRender(mVideoSource->getFormat());
continue;
}
LOGV("PreviewPlayer: onVideoEvent EOS reached.");
@@ -1688,4 +1555,10 @@
return OK;
}
+void PreviewPlayer::updateSizeToRender(sp<MetaData> meta) {
+ if (mVideoRenderer) {
+ mVideoRenderer->updateVideoSize(meta);
+ }
+}
+
} // namespace android