[x265] [PATCH] yuv: make file reading threaded
kavitha at multicorewareinc.com
kavitha at multicorewareinc.com
Wed Oct 16 07:35:57 CEST 2013
# HG changeset patch
# User Kavitha Sampath <kavitha at multicorewareinc.com>
# Date 1381901438 -19800
# Wed Oct 16 11:00:38 2013 +0530
# Node ID 25a76f03553ecc58e56bc1fab9a5e98c41fcb815
# Parent a998daed845922b3b880b48c0cafa32c422c941e
yuv: make file reading threaded
diff -r a998daed8459 -r 25a76f03553e source/input/yuv.cpp
--- a/source/input/yuv.cpp Tue Oct 15 20:57:47 2013 -0500
+++ b/source/input/yuv.cpp Wed Oct 16 11:00:38 2013 +0530
@@ -23,6 +23,7 @@
#include "yuv.h"
#include "PPA/ppa.h"
+#include "common.h"
#include <stdio.h>
#include <string.h>
@@ -34,13 +35,28 @@
ifs.open(filename, ios::binary | ios::in);
width = height = 0;
depth = 8;
- buf = NULL;
+ threadActive = false;
+ if (!ifs.fail())
+ threadActive = true;
+ else
+ ifs.close();
+#if defined ENABLE_THREAD
+ head = 0;
+ tail = 0;
+#endif
}
YUVInput::~YUVInput()
{
ifs.close();
+#if defined ENABLE_THREAD
+ for (int i = 0; i < QUEUE_SIZE; i++)
+ {
+ delete[] buf[i];
+ }
+#else
delete[] buf;
+#endif
}
int YUVInput::guessFrameCount()
@@ -50,34 +66,111 @@
ifs.seekg(0, ios::end);
ifstream::pos_type size = ifs.tellg();
ifs.seekg(cur, ios::beg);
- int pixelbytes = depth > 8 ? 2 : 1;
return (int)((size - cur) / (width * height * pixelbytes * 3 / 2));
}
void YUVInput::skipFrames(int numFrames)
{
- int pixelbytes = depth > 8 ? 2 : 1;
-
- int framesize = (width * height * 3 / 2) * pixelbytes;
-
ifs.seekg(framesize * numFrames, ios::cur);
}
+void YUVInput::setDimensions(int w, int h)
+{
+ width = w;
+ height = h;
+ pixelbytes = depth > 8 ? 2 : 1;
+ framesize = (width * height * 3 / 2) * pixelbytes;
+ if (width < MIN_FRAME_WIDTH || width > MAX_FRAME_WIDTH ||
+ height < MIN_FRAME_HEIGHT || height > MAX_FRAME_HEIGHT)
+ {
+ threadActive = false;
+ ifs.close();
+ }
+ else
+ {
+#if defined ENABLE_THREAD
+ for (int i = 0; i < QUEUE_SIZE; i++)
+ {
+ buf[i] = new char[framesize];
+ if (buf[i] == NULL)
+ {
+ x265_log(NULL, X265_LOG_ERROR, "yuv: buffer allocation failure, aborting");
+ threadActive = false;
+ }
+ }
+ start();
+#else
+ buf = new char[framesize];
+#endif
+ }
+}
+
+#if defined ENABLE_THREAD
+void YUVInput::threadMain()
+{
+ do
+ {
+ if (!populateFrameQueue())
+ break;
+ }
+ while (threadActive);
+}
+
+bool YUVInput::populateFrameQueue()
+{
+ while ((tail + 1) % QUEUE_SIZE == head)
+ {
+ notFull.wait();
+ if (!threadActive)
+ break;
+ }
+ ifs.read(buf[tail], framesize);
+ frameStat[tail] = ifs.good();
+ if (!frameStat[tail])
+ return false;
+ tail = (tail + 1) % QUEUE_SIZE;
+ notEmpty.trigger();
+ return true;
+}
+
+bool YUVInput::readPicture(x265_picture_t& pic)
+{
+ PPAStartCpuEventFunc(read_yuv);
+ if (!threadActive)
+ return false;
+ while (head == tail)
+ {
+ notEmpty.wait();
+ }
+ if (!frameStat[head])
+ return false;
+ pic.planes[0] = buf[head];
+
+ pic.planes[1] = (char*)(pic.planes[0]) + width * height * pixelbytes;
+
+ pic.planes[2] = (char*)(pic.planes[1]) + ((width * height * pixelbytes) >> 2);
+
+ pic.bitDepth = depth;
+
+ pic.stride[0] = width * pixelbytes;
+
+ pic.stride[1] = pic.stride[2] = pic.stride[0] >> 1;
+
+ head = (head + 1) % QUEUE_SIZE;
+ notFull.trigger();
+
+ PPAStopCpuEventFunc(read_yuv);
+
+ return true;
+}
+#else
+
// TODO: only supports 4:2:0 chroma sampling
bool YUVInput::readPicture(x265_picture_t& pic)
{
PPAStartCpuEventFunc(read_yuv);
- int pixelbytes = depth > 8 ? 2 : 1;
-
- int bufsize = (width * height * 3 / 2) * pixelbytes;
-
- if (!buf)
- {
- buf = new char[bufsize];
- }
-
pic.planes[0] = buf;
pic.planes[1] = (char*)(pic.planes[0]) + width * height * pixelbytes;
@@ -90,8 +183,19 @@
pic.stride[1] = pic.stride[2] = pic.stride[0] >> 1;
- ifs.read(buf, bufsize);
+ ifs.read(buf, framesize);
PPAStopCpuEventFunc(read_yuv);
return ifs.good();
}
+#endif
+
+void YUVInput::release()
+{
+#if defined(ENABLE_THREAD)
+ threadActive = false;
+ notFull.trigger();
+ stop();
+#endif
+ delete this;
+}
diff -r a998daed8459 -r 25a76f03553e source/input/yuv.h
--- a/source/input/yuv.h Tue Oct 15 20:57:47 2013 -0500
+++ b/source/input/yuv.h Wed Oct 16 11:00:38 2013 +0530
@@ -27,10 +27,19 @@
#include "input.h"
#include <fstream>
+#if defined(ENABLE_THREAD)
+#define QUEUE_SIZE 5
+#include "threading.h"
+#endif
+
namespace x265 {
// private x265 namespace
+#if defined(ENABLE_THREAD)
+class YUVInput : public Input, public Thread
+#else
class YUVInput : public Input
+#endif
{
protected:
@@ -40,7 +49,27 @@
int depth;
+ int pixelbytes;
+
+ int framesize;
+
+ bool threadActive;
+
+#if defined(ENABLE_THREAD)
+ volatile int head;
+
+ volatile int tail;
+
+ bool frameStat[QUEUE_SIZE];
+
+ char* buf[QUEUE_SIZE];
+
+ Event notFull;
+
+ Event notEmpty;
+#else
char* buf;
+#endif
std::ifstream ifs;
@@ -50,7 +79,7 @@
virtual ~YUVInput();
- void setDimensions(int w, int h) { width = w; height = h; }
+ void setDimensions(int, int);
void setBitDepth(int bitDepth) { depth = bitDepth; }
@@ -62,9 +91,9 @@
bool isEof() const { return ifs.eof(); }
- bool isFail() { return !ifs.is_open(); }
+ bool isFail() { return !(ifs.is_open() && threadActive);}
- void release() { delete this; }
+ void release();
int guessFrameCount();
@@ -72,6 +101,14 @@
bool readPicture(x265_picture_t&);
+#if defined(ENABLE_THREAD)
+
+ void threadMain();
+
+ bool populateFrameQueue();
+
+#endif
+
const char *getName() const { return "yuv"; }
};
}
More information about the x265-devel
mailing list