From c6d3bd49ae4e41611ec061f06e54a1863e1e4e0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C3=ABl=20Carr=C3=A9?=
 <rafael.carre@savoirfairelinux.com>
Date: Mon, 4 Jul 2011 16:15:20 -0400
Subject: [PATCH] * #6345: Add a VideoPicture class and use it in video
 receiving

---
 sflphone-common/src/video/video_picture.h     | 54 +++++++++++++++++++
 .../src/video/video_receive_thread.cpp        | 17 ++++--
 2 files changed, 66 insertions(+), 5 deletions(-)
 create mode 100644 sflphone-common/src/video/video_picture.h

diff --git a/sflphone-common/src/video/video_picture.h b/sflphone-common/src/video/video_picture.h
new file mode 100644
index 0000000000..879042e1ee
--- /dev/null
+++ b/sflphone-common/src/video/video_picture.h
@@ -0,0 +1,54 @@
+/*
+ *  Copyright (C) 2011 Savoir-Faire Linux Inc.
+ *  Author: Rafaël Carré <rafael.carre@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#ifndef __VIDEO_PICTURE_H__
+#define __VIDEO_PICTURE_H__
+
+namespace sfl_video {
+
+class VideoPicture {
+    public:
+        VideoPicture(const unsigned bpp, const unsigned width, const unsigned height, const uint64_t pts) : bpp(bpp), width(width), height(height), pts(pts) {
+            // FIXME : stride must be equal to width * bpp
+            data = malloc(Size());
+        }
+
+        void* data; /** raw image data  */
+
+        const unsigned bpp;     /** bits per pixel  */
+        const unsigned width;   /** image width     */
+        const unsigned height;  /** image height    */
+        const uint64_t pts;     /** presentation timestamp */
+
+        size_t Size() { return (bpp >> 3) * width * height; }
+};
+}
+
+#endif // __VIDEO_PICTURE_H__
diff --git a/sflphone-common/src/video/video_receive_thread.cpp b/sflphone-common/src/video/video_receive_thread.cpp
index 4dc3169f6d..819dfbdbf7 100644
--- a/sflphone-common/src/video/video_receive_thread.cpp
+++ b/sflphone-common/src/video/video_receive_thread.cpp
@@ -54,6 +54,7 @@ extern "C" {
 #include <cstdlib>
 
 #include "manager.h"
+#include "video_picture.h"
 
 namespace sfl_video {
 
@@ -290,11 +291,6 @@ void VideoReceiveThread::setup()
     semSetID_ = createSemSet(shmID_, shmKey_, &semKey_);
     shmReady_.signal();
 
-    // assign appropriate parts of buffer to image planes in scaledPicture 
-    avpicture_fill(reinterpret_cast<AVPicture *>(scaledPicture_),
-            reinterpret_cast<uint8_t*>(shmBuffer_),
-            (enum PixelFormat) format_, dstWidth_, dstHeight_);
-
     // allocate video frame
     rawFrame_ = avcodec_alloc_frame();
 }
@@ -373,6 +369,8 @@ void VideoReceiveThread::run()
     AVPacket inpacket;
     int frameFinished;
     SwsContext *imgConvertCtx = createScalingContext();
+    enum PixelFormat fmt = (enum PixelFormat) format_;
+    int bpp = (av_get_bits_per_pixel(&av_pix_fmt_descriptors[fmt]) + 7) & ~7;
 
     while (not interrupted_ and av_read_frame(inputCtx_, &inpacket) >= 0)
     {
@@ -383,10 +381,19 @@ void VideoReceiveThread::run()
             avcodec_decode_video2(decoderCtx_, rawFrame_, &frameFinished, &inpacket);
             if (frameFinished)
             {
+                VideoPicture *pic = new VideoPicture(bpp, dstWidth_, dstHeight_, rawFrame_->pts);
+    // assign appropriate parts of buffer to image planes in scaledPicture 
+    avpicture_fill(reinterpret_cast<AVPicture *>(scaledPicture_),
+            reinterpret_cast<uint8_t*>(pic->data), fmt, dstWidth_, dstHeight_);
+
                 sws_scale(imgConvertCtx, rawFrame_->data, rawFrame_->linesize,
                         0, decoderCtx_->height, scaledPicture_->data,
                         scaledPicture_->linesize);
 
+                // FIXME : put pictures in a pool and use the PTS to get them out and displayed from a separate thread
+                memcpy(shmBuffer_, pic->data, pic->Size());
+                delete pic;
+
                 /* signal the semaphore that a new frame is ready */ 
                 sem_signal(semSetID_);
             }
-- 
GitLab