summaryrefslogtreecommitdiff
path: root/drivers/theoraplayer/src/TheoraVideoFrame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/theoraplayer/src/TheoraVideoFrame.cpp')
-rw-r--r--drivers/theoraplayer/src/TheoraVideoFrame.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/drivers/theoraplayer/src/TheoraVideoFrame.cpp b/drivers/theoraplayer/src/TheoraVideoFrame.cpp
new file mode 100644
index 0000000000..b70253dabf
--- /dev/null
+++ b/drivers/theoraplayer/src/TheoraVideoFrame.cpp
@@ -0,0 +1,159 @@
+/************************************************************************************
+This source file is part of the Theora Video Playback Library
+For latest info, see http://libtheoraplayer.googlecode.com
+*************************************************************************************
+Copyright (c) 2008-2014 Kresimir Spes (kspes@cateia.com)
+This program is free software; you can redistribute it and/or modify it under
+the terms of the BSD license: http://opensource.org/licenses/BSD-3-Clause
+*************************************************************************************/
+#include <memory.h>
+#include "TheoraPixelTransform.h"
+#include "TheoraVideoClip.h"
+#include "TheoraVideoFrame.h"
+#include "TheoraVideoManager.h"
+
+//#define YUV_TEST // uncomment this if you want to benchmark YUV decoding functions
+
+extern "C"
+{
+void decodeRGB (struct TheoraPixelTransform* t);
+void decodeRGBA (struct TheoraPixelTransform* t);
+void decodeRGBX (struct TheoraPixelTransform* t);
+void decodeARGB (struct TheoraPixelTransform* t);
+void decodeXRGB (struct TheoraPixelTransform* t);
+void decodeBGR (struct TheoraPixelTransform* t);
+void decodeBGRA (struct TheoraPixelTransform* t);
+void decodeBGRX (struct TheoraPixelTransform* t);
+void decodeABGR (struct TheoraPixelTransform* t);
+void decodeXBGR (struct TheoraPixelTransform* t);
+void decodeGrey (struct TheoraPixelTransform* t);
+void decodeGrey3(struct TheoraPixelTransform* t);
+void decodeGreyA(struct TheoraPixelTransform* t);
+void decodeGreyX(struct TheoraPixelTransform* t);
+void decodeAGrey(struct TheoraPixelTransform* t);
+void decodeXGrey(struct TheoraPixelTransform* t);
+void decodeYUV (struct TheoraPixelTransform* t);
+void decodeYUVA (struct TheoraPixelTransform* t);
+void decodeYUVX (struct TheoraPixelTransform* t);
+void decodeAYUV (struct TheoraPixelTransform* t);
+void decodeXYUV (struct TheoraPixelTransform* t);
+}
+
+static void (*conversion_functions[])(struct TheoraPixelTransform*) = {0,
+ decodeRGB,
+ decodeRGBA,
+ decodeRGBX,
+ decodeARGB,
+ decodeXRGB,
+ decodeBGR,
+ decodeBGRA,
+ decodeBGRX,
+ decodeABGR,
+ decodeXBGR,
+ decodeGrey,
+ decodeGrey3,
+ decodeGreyA,
+ decodeGreyX,
+ decodeAGrey,
+ decodeXGrey,
+ decodeYUV,
+ decodeYUVA,
+ decodeYUVX,
+ decodeAYUV,
+ decodeXYUV
+};
+
+TheoraVideoFrame::TheoraVideoFrame(TheoraVideoClip* parent)
+{
+ mReady = mInUse = false;
+ mParent = parent;
+ mIteration = 0;
+ // number of bytes based on output mode
+ int bytemap[]={0, 3, 4, 4, 4, 4, 3, 4, 4, 4, 4, 1, 3, 4, 4, 4, 4, 3, 4, 4, 4, 4};
+ mBpp = bytemap[mParent->getOutputMode()];
+ unsigned int size = mParent->getStride() * mParent->mHeight * mBpp;
+ try
+ {
+ mBuffer = new unsigned char[size];
+ }
+ catch (std::bad_alloc)
+ {
+ mBuffer = NULL;
+ return;
+ }
+ memset(mBuffer, 255, size);
+}
+
+TheoraVideoFrame::~TheoraVideoFrame()
+{
+ if (mBuffer) delete [] mBuffer;
+}
+
+int TheoraVideoFrame::getWidth()
+{
+ return mParent->getWidth();
+}
+
+int TheoraVideoFrame::getStride()
+{
+ return mParent->mStride;
+}
+
+int TheoraVideoFrame::getHeight()
+{
+ return mParent->getHeight();
+}
+
+unsigned char* TheoraVideoFrame::getBuffer()
+{
+ return mBuffer;
+}
+
+void TheoraVideoFrame::decode(struct TheoraPixelTransform* t)
+{
+ if (t->raw != NULL)
+ {
+ int bufferStride = mParent->getWidth() * mBpp;
+ if (bufferStride == t->rawStride)
+ {
+ memcpy(mBuffer, t->raw, t->rawStride * mParent->getHeight());
+ }
+ else
+ {
+ unsigned char *buff = mBuffer, *src = t->raw;
+ int i, h = mParent->getHeight();
+ for (i = 0; i < h; ++i, buff += bufferStride, src += t->rawStride)
+ {
+ memcpy(buff, src, bufferStride);
+ }
+ }
+ }
+ else
+ {
+ t->out = mBuffer;
+ t->w = mParent->getWidth();
+ t->h = mParent->getHeight();
+
+#ifdef YUV_TEST // when benchmarking yuv conversion functions during development, do a timed average
+ #define N 1000
+ clock_t time = clock();
+ for (int i = 0; i < N; ++i)
+ {
+ conversion_functions[mParent->getOutputMode()](t);
+ }
+ float diff = (clock() - time) * 1000.0f / CLOCKS_PER_SEC;
+
+ char s[128];
+ sprintf(s, "%.2f", diff / N);
+ TheoraVideoManager::getSingleton().logMessage("YUV Decoding time: " + std::string(s) + " ms\n");
+#else
+ conversion_functions[mParent->getOutputMode()](t);
+#endif
+ }
+ mReady = true;
+}
+
+void TheoraVideoFrame::clear()
+{
+ mInUse = mReady = false;
+}