[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