Results 1 to 2 of 2

Thread: Create video widget using byte array

  1. #1
    Join Date
    Jun 2012
    Posts
    2

    Default Create video widget using byte array

    Hi,

    I have access to a framebuffer using SHM on Linux. I can get access to the data and I am quite sure they are valid. However, it only work at small resolution and somehow I get overscroll video. I try to use QImage and tried many combinaisons. Most wont work above 160x120. This one work with 340x240, but not above. The CPU does not seem to be the problem, my app use little. I can't use OpenGL (not supported on device)..

    What is the best way to make a video from a frame buffer?

    This is the current code:
    Qt Code:
    1. VideoWidget::VideoWidget(QWidget* parent) : QWidget(parent),m_Image(NULL) {
    2. setMinimumSize(200,200);
    3. connect(VideoModel::getInstance(),SIGNAL(frameUpdated()),this,SLOT(repaint2()));
    4. }
    5.  
    6. void VideoWidget::update() {
    7. QPainter painter(this);
    8. painter.drawImage(QRect(0,0,width(),height()),*(m_Image));
    9. painter.end();
    10. }
    11.  
    12. void VideoWidget::paintEvent(QPaintEvent* event)
    13. {
    14. Q_UNUSED(event)
    15. if (VideoModel::getInstance()->isPreviewing()) {
    16. update();
    17. }
    18. }
    19.  
    20. void VideoWidget::repaint2()
    21. {
    22. QSize size(VideoModel::getInstance()->getActiveResolution().width, VideoModel::getInstance()->getActiveResolution().height);
    23. if (size != minimumSize())
    24. setMinimumSize(size);
    25. //if (m_Image)
    26. // delete m_Image;
    27. m_Image = new QImage(size,QImage::Format_ARGB32);
    28. m_Image->loadFromData(VideoModel::getInstance()->getCurrentFrame(),"BMP");
    29. repaint();
    30. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. /************************************************************************************
    2.  * Copyright (C) 2012 by Savoir-Faire Linux *
    3.  * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
    4.  * *
    5.  * This library is free software; you can redistribute it and/or *
    6.  * modify it under the terms of the GNU Lesser General Public *
    7.  * License as published by the Free Software Foundation; either *
    8.  * version 2.1 of the License, or (at your option) any later version. *
    9.  * *
    10.  * This library is distributed in the hope that it will be useful, *
    11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
    12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
    13.  * Lesser General Public License for more details. *
    14.  * *
    15.  * You should have received a copy of the GNU Lesser General Public *
    16.  * License along with this library; if not, write to the Free Software *
    17.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
    18.  ***********************************************************************************/
    19. #include "VideoModel.h"
    20. #include "video_interface_singleton.h"
    21. #include <QSharedMemory>
    22. #include <QDBusPendingReply>
    23. #include <sys/ipc.h>
    24. #include <sys/sem.h>
    25. #include <sys/shm.h>
    26. #include <unistd.h>
    27.  
    28. VideoModel* VideoModel::m_spInstance = NULL;
    29.  
    30. ///@namespace ShmManager Low level function to access shared memory
    31. namespace ShmManager {
    32. static int getShm(unsigned numBytes, int shmKey)
    33. {
    34. key_t key = shmKey;
    35. int shm_id = shmget(key, numBytes, 0644);
    36.  
    37. if (shm_id == -1)
    38. qDebug() << ("shmget");
    39.  
    40. return shm_id;
    41. }
    42.  
    43.  
    44. static void * attachShm(int shm_id)
    45. {
    46. void *data = shmat(shm_id, (void *)0, 0);
    47. if (data == (char *)(-1)) {
    48. qDebug() << ("shmat");
    49. data = NULL;
    50. }
    51.  
    52. return data;
    53. }
    54.  
    55.  
    56. static void detachShm(char *data)
    57. {
    58. /* detach from the segment: */
    59. if (shmdt(data) == -1)
    60. qDebug() << ("shmdt");
    61. }
    62.  
    63. #if _SEM_SEMUN_UNDEFINED
    64. union semun
    65. {
    66. int val ; /* value for SETVAL */
    67. struct semid_ds* buf ; /* buffer for IPC_STAT & IPC_SET */
    68. unsigned short int* array; /* array for GETALL & SETALL */
    69. struct seminfo* __buf; /* buffer for IPC_INFO */
    70. };
    71. #endif
    72.  
    73. static int get_sem_set(int semKey)
    74. {
    75. int sem_set_id;
    76. key_t key = semKey;
    77.  
    78. union semun sem_val;
    79.  
    80. sem_set_id = semget(key, 1, 0600);
    81. if (sem_set_id == -1) {
    82. qDebug() << ("semget");
    83. return sem_set_id;
    84. }
    85. sem_val.val = 0;
    86. semctl(sem_set_id, 0, SETVAL, sem_val);
    87. return sem_set_id;
    88. }
    89.  
    90. static int sem_wait(int sem_set_id)
    91. {
    92. /* structure for semaphore operations. */
    93. struct sembuf sem_op;
    94.  
    95. /* wait on the semaphore, unless it's value is non-negative. */
    96. sem_op.sem_num = 0;
    97. sem_op.sem_op = -1;
    98. sem_op.sem_flg = IPC_NOWAIT;
    99. return semop(sem_set_id, &sem_op, 1);
    100. }
    101. };
    102.  
    103. ///Constructor
    104. VideoModel::VideoModel():m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_Res(0,0),m_pTimer(0),m_PreviewState(false),
    105. m_Attached(false)
    106. {
    107. VideoInterface& interface = VideoInterfaceSingleton::getInstance();
    108. connect( &interface , SIGNAL(receivingEvent(int,int,int,int,int) ), this, SLOT( receivingEvent(int,int,int,int,int) ));
    109. connect( &interface , SIGNAL(deviceEvent() ), this, SLOT( deviceEvent() ));
    110. connect( &interface , SIGNAL(stoppedReceivingEvent(int,int) ), this, SLOT( stoppedReceivingEvent(int,int) ));
    111. }
    112.  
    113. ///Singleton
    114. VideoModel* VideoModel::getInstance()
    115. {
    116. if (!m_spInstance) {
    117. m_spInstance = new VideoModel();
    118. }
    119. return m_spInstance;
    120. }
    121.  
    122. ///Stop video preview
    123. void VideoModel::stopPreview()
    124. {
    125. VideoInterface& interface = VideoInterfaceSingleton::getInstance();
    126. interface.stopPreview();
    127. m_PreviewState = false;
    128. if (m_pTimer)
    129. m_pTimer->stop();
    130. if (m_Attached) {
    131. ShmManager::detachShm((char*)m_pBuffer);
    132. m_Attached = false;
    133. }
    134. }
    135.  
    136. ///Start video preview
    137. void VideoModel::startPreview()
    138. {
    139. if (m_PreviewState) return;
    140. VideoInterface& interface = VideoInterfaceSingleton::getInstance();
    141. QDBusPendingReply<int,int,int,int,int> reply = interface.startPreview();
    142. reply.waitForFinished();
    143. if (!reply.isError()) {
    144. m_Res.width = reply.argumentAt(0).toInt();
    145. m_Res.height = reply.argumentAt(1).toInt();
    146. m_ShmKey = reply.argumentAt(2).toInt();
    147. m_SemKey = reply.argumentAt(3).toInt();
    148. m_BufferSize = reply.argumentAt(4).toInt();
    149. if (!m_pTimer) {
    150. m_pTimer = new QTimer(this);
    151. connect(m_pTimer,SIGNAL(timeout()),this,SLOT(timedEvents()));
    152. }
    153. m_pTimer->setInterval(42);
    154. m_pTimer->start();
    155. m_PreviewState = true;
    156. }
    157. }
    158.  
    159. bool VideoModel::isPreviewing()
    160. {
    161. return m_PreviewState;
    162. }
    163.  
    164. ///@todo Set the video buffer size
    165. void VideoModel::setBufferSize(uint size)
    166. {
    167. m_BufferSize = size;
    168. }
    169.  
    170. ///Event callback
    171. void VideoModel::receivingEvent(int shmKey, int semKey, int videoBufferSize, int destWidth, int destHeight)
    172. {
    173. m_ShmKey = (uint)shmKey;
    174. m_ShmKey = (uint)semKey;
    175. m_BufferSize = videoBufferSize;
    176. m_Res.width = destWidth;
    177. m_Res.height = destHeight;
    178.  
    179.  
    180. }
    181.  
    182. ///Callback when video is stopped
    183. void VideoModel::stoppedReceivingEvent(int shmKey, int semKey)
    184. {
    185. m_ShmKey = (uint)shmKey;
    186. m_ShmKey = (uint)semKey;
    187. }
    188.  
    189. ///Event callback
    190. void VideoModel::deviceEvent()
    191. {
    192.  
    193. }
    194.  
    195. ///Update the buffer
    196. void VideoModel::timedEvents()
    197. {
    198. if ( !m_Attached ) {
    199. int shm_id = ShmManager::getShm(m_BufferSize, m_ShmKey);
    200. m_pBuffer = ShmManager::attachShm(shm_id);
    201. m_Attached = true;
    202. m_SetSetId = ShmManager::get_sem_set(m_SemKey);
    203. }
    204.  
    205. int ret = ShmManager::sem_wait(m_SetSetId);
    206. if (ret != -1) {
    207. qDebug() << "Updating frame" << m_pBuffer << m_Res.width << m_Res.height << m_BufferSize;;
    208. QByteArray array((char*)m_pBuffer,m_BufferSize);
    209. m_Frame.resize(0);
    210. m_Frame = array;
    211. emit frameUpdated();
    212. }
    213. else {
    214. qDebug() << "Skipping" << ret;
    215. usleep(rand()%100000); //Be sure it can come back in sync
    216. }
    217. qDebug() << "Ret" << ret;
    218. }
    219.  
    220. ///Return the current framerate
    221. QByteArray VideoModel::getCurrentFrame()
    222. {
    223. return m_Frame;
    224. }
    225.  
    226. ///Return the current resolution
    227. Resolution VideoModel::getActiveResolution()
    228. {
    229. return m_Res;
    230. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Create video widget using byte array

    What is the original size of your frame?
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

Similar Threads

  1. Bitmap to byte array
    By Otherside in forum Newbie
    Replies: 6
    Last Post: 15th January 2012, 21:17
  2. PlEASE HELP: Hot To Use Byte Array, data stream
    By aash_89 in forum Qt Programming
    Replies: 7
    Last Post: 16th July 2010, 08:33
  3. Replies: 3
    Last Post: 19th April 2010, 14:16
  4. Playing video using Phonon video widget
    By Leolander in forum Newbie
    Replies: 0
    Last Post: 26th February 2010, 06:15
  5. Create an array of Widgets
    By gt.beta2 in forum Qt Tools
    Replies: 4
    Last Post: 25th February 2009, 19:44

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.