1 /* smplayer, GUI front-end for mplayer.
2 Copyright (C) 2006-2021 Ricardo Villalba <ricardo@smplayer.info>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #include "connectioncv.h"
20 #include "mconnection.h"
21
22 #include <QCoreApplication>
23 #include <QDebug>
24
25 #include <fcntl.h>
26 #include <sys/mman.h>
27 #include <stdint.h>
28 #include <errno.h>
29
ConnectionCV(VideoLayerRender * parent)30 ConnectionCV::ConnectionCV(VideoLayerRender * parent)
31 : ConnectionBase(parent)
32 , shm_fd(0)
33 , image_buffer(0)
34 , buffer_size(0)
35 #ifdef COPY_BUFFER
36 , copy_buffer(0)
37 , copy_buffer_size(0)
38 #endif
39 {
40 buffer_name = QString("/smplayer-%1").arg(QCoreApplication::applicationPid());
41 mconnection = new MConnection(this, buffer_name);
42 start_connection();
43 }
44
~ConnectionCV()45 ConnectionCV::~ConnectionCV() {
46 delete mconnection;
47 stop_connection();
48
49 #ifdef COPY_BUFFER
50 if (copy_buffer != 0) {
51 free(copy_buffer);
52 }
53 #endif
54 }
55
stop()56 void ConnectionCV::stop() {
57 qDebug("ConnectionCV::stop");
58 //stop_connection();
59 }
60
start()61 void ConnectionCV::start() {
62 qDebug("ConnectionCV::start");
63 //start_connection();
64 }
65
init_slot(int width,int height,int bytes,int aspect)66 void ConnectionCV::init_slot(int width, int height, int bytes, int aspect) {
67 qDebug("ConnectionCV::init_slot: %d %d %d %d", width, height, bytes, aspect);
68
69 int image_width = width;
70 int image_height = height;
71 int image_bytes = bytes;
72
73 uint32_t format = ConnectionBase::UYVY;
74 if (bytes == 1) {
75 buffer_size = image_width * image_height * 2;
76 format = ConnectionBase::I420;
77 } else {
78 buffer_size = image_width * image_height * image_bytes;
79 }
80
81 shm_fd = shm_open(buffer_name.toLatin1().constData(), O_RDONLY, S_IRUSR);
82 if (shm_fd == -1) {
83 qDebug("ConnectionCV::init_slot: shm_open failed");
84 return;
85 }
86
87 image_buffer = (unsigned char*) mmap(NULL, buffer_size, PROT_READ, MAP_SHARED, shm_fd, 0);
88 if (image_buffer == MAP_FAILED) {
89 qDebug("ConnectionCV::init_slot: mmap failed");
90 return;
91 }
92
93 video_window->init(image_width, image_height, image_bytes, format, image_buffer);
94 }
95
render_slot()96 void ConnectionCV::render_slot() {
97 //qDebug("ConnectionCV::render_slot");
98 if (image_buffer) {
99 #ifdef COPY_BUFFER
100 if (copy_buffer == 0 || copy_buffer_size < buffer_size) {
101 qDebug("ConnectionCV::render_slot: creating copy_buffer");
102 if (copy_buffer != 0) free(copy_buffer);
103 copy_buffer = (unsigned char *) malloc(buffer_size);
104 copy_buffer_size = buffer_size;
105 video_window->setImageBuffer(copy_buffer);
106 }
107 memcpy(copy_buffer, image_buffer, buffer_size);
108 #endif
109 video_window->render();
110 }
111 }
112
stop_slot()113 void ConnectionCV::stop_slot() {
114 qDebug("ConnectionCV::stop_slot");
115 }
116
start_connection()117 void ConnectionCV::start_connection() {
118 mconnection->startConnection();
119 }
120
stop_connection()121 void ConnectionCV::stop_connection() {
122 mconnection->stopConnection();
123
124 // Destroy the shared buffer
125 if (munmap(image_buffer, buffer_size) == -1) {
126 qDebug("ConnectionCV::stop_connection: munmap failed");
127 }
128 image_buffer = 0;
129 }
130
131 #include "moc_connectioncv.cpp"
132