1 /**
2  * xrdp: A Remote Desktop Protocol server.
3  *
4  * Copyright (C) Laxmikant Rashinkar 2012-2013 LK.Rashinkar@gmail.com
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * a program that uses xrdpapi and ffmpeg to redirect media streams
19  * to a FreeRDP client where it is decompressed and played locally
20  *
21  */
22 
23 #ifndef __XRDPVR_INTERNAL_H__
24 #define __XRDPVR_INTERNAL_H__
25 
26 #include <stdint.h>
27 #include <sys/types.h>
28 #include <fcntl.h>
29 #include <libavcodec/avcodec.h>
30 #include <libavformat/avformat.h>
31 
32 #if LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR == 20
33 #define DISTRO_DEBIAN6
34 #endif
35 
36 #if LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR == 72
37 #define DISTRO_UBUNTU1104
38 #endif
39 
40 #if LIBAVCODEC_VERSION_MAJOR == 53 && LIBAVCODEC_VERSION_MINOR == 35
41 #define DISTRO_UBUNTU1204
42 #endif
43 
44 #if !defined(DISTRO_DEBIAN6) && !defined(DISTRO_UBUNTU1104) && !defined(DISTRO_UBUNTU1204)
45 #warning unsupported distro
46 #endif
47 
48 #ifdef DISTRO_UBUNTU1204
49 #define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO
50 #define CODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO
51 #define PKT_FLAG_KEY AV_PKT_FLAG_KEY
52 #endif
53 
54 #define MAX_BUFSIZE (1024 * 1024 * 8)
55 
56 #define CMD_SET_VIDEO_FORMAT        1
57 #define CMD_SET_AUDIO_FORMAT        2
58 #define CMD_SEND_VIDEO_DATA         3
59 #define CMD_SEND_AUDIO_DATA         4
60 #define CMD_CREATE_META_DATA_FILE   5
61 #define CMD_CLOSE_META_DATA_FILE    6
62 #define CMD_WRITE_META_DATA         7
63 #define CMD_DEINIT_XRDPVR           8
64 #define CMD_SET_GEOMETRY            9
65 #define CMD_SET_VOLUME              10
66 #define CMD_INIT_XRDPVR             11
67 
68 /* max number of bytes we can send in one pkt */
69 #define MAX_PDU_SIZE                1600
70 
71 typedef uint8_t  u8;
72 typedef uint16_t u16;
73 typedef uint32_t u32;
74 
75 typedef struct stream
76 {
77     u8  *data;
78     u8  *p;
79     u32  size;
80     int  from_buf;
81 } STREAM;
82 
83 /**
84  * create and init a new stream
85  *
86  * @param  _s     stream to create and init
87  * @param  _len   number of bytes to store in stream
88  ******************************************************************************/
89 #define stream_new(_s, _len)                          \
90     do                                                \
91     {                                                 \
92         (_s) = (STREAM *) calloc(1, sizeof(STREAM));  \
93         (_s)->data = (u8 *) calloc(1, (_len));        \
94         (_s)->p = (_s)->data;                         \
95         (_s)->size = (_len);                          \
96         (_s)->from_buf = 0;                           \
97     } while (0)
98 
99 /**
100  * create a stream from an existing buffer
101  ******************************************************************************/
102 #define stream_from_buffer(_s, _buf, _buf_len)        \
103     do                                                \
104     {                                                 \
105         (_s) = (STREAM *) calloc(1, sizeof(STREAM));  \
106         (_s)->data = (u8 *) (_buf);                   \
107         (_s)->p = (_s)->data;                         \
108         (_s)->size = (_buf_len);                      \
109         (_s)->from_buf = 1;                           \
110     } while (0)
111 
112 /**
113  * release stream resources, including stream itself
114  * note: release _s->data only if we allocated it
115  *
116  * @param  _s  the stream whose resources are to be released
117  ******************************************************************************/
118 #define stream_free(_s)                               \
119     do                                                \
120     {                                                 \
121         if (!(_s)->from_buf)                          \
122         {                                             \
123             free((_s)->data);                         \
124         }                                             \
125         free((_s));                                   \
126         (_s) = NULL;                                  \
127     } while (0)
128 
129 /** return number of bytes in stream */
130 #define stream_length(_s) (int) ((_s)->p - (_s)->data)
131 
132 /** insert a 8 bit value into stream */
133 #define stream_ins_u8(_s, _val)                       \
134     do                                                \
135     {                                                 \
136         *(_s)->p++ = (unsigned char) (_val);          \
137     } while(0)
138 
139 /** insert a 16 bit value into stream */
140 #define stream_ins_u16_le(_s, _val)                   \
141     do                                                \
142     {                                                 \
143         *(_s)->p++ = (unsigned char) ((_val) >> 0);   \
144         *(_s)->p++ = (unsigned char) ((_val) >> 8);   \
145     } while (0)
146 
147 /** insert a 32 bit value into stream */
148 #define stream_ins_u32_le(_s, _val)                   \
149     do                                                \
150     {                                                 \
151         *(_s)->p++ = (unsigned char) ((_val) >> 0);   \
152         *(_s)->p++ = (unsigned char) ((_val) >> 8);   \
153         *(_s)->p++ = (unsigned char) ((_val) >> 16);  \
154         *(_s)->p++ = (unsigned char) ((_val) >> 24);  \
155     } while (0)
156 
157 /** insert a 64 bit value into stream */
158 #define stream_ins_u64_le(_s, _val)                   \
159     do                                                \
160     {                                                 \
161         *(_s)->p++ = (unsigned char) ((_val) >> 0);   \
162         *(_s)->p++ = (unsigned char) ((_val) >> 8);   \
163         *(_s)->p++ = (unsigned char) ((_val) >> 16);  \
164         *(_s)->p++ = (unsigned char) ((_val) >> 24);  \
165         *(_s)->p++ = (unsigned char) ((_val) >> 32);  \
166         *(_s)->p++ = (unsigned char) ((_val) >> 40);  \
167         *(_s)->p++ = (unsigned char) ((_val) >> 48);  \
168         *(_s)->p++ = (unsigned char) ((_val) >> 56);  \
169     } while (0)
170 
171 /** insert array of chars into stream */
172 #define stream_ins_byte_array(_s, _ba, _count)        \
173     do                                                \
174     {                                                 \
175         memcpy((_s)->p, (_ba), (_count));             \
176         (_s)->p += (_count);                          \
177     } while (0)
178 
179 /** extract a 8 bit value from stream */
180 #define stream_ext_u8(_s, _v)                         \
181     do                                                \
182     {                                                 \
183         (_v) = (u8) *(_s)->p++;                       \
184     } while (0)
185 
186 /** extract a 16 bit value from stream */
187 #define stream_ext_u16_le(_s, _v)                     \
188     do                                                \
189     {                                                 \
190         (_v) = (u16) ((_s)->p[1] << 8 | (_s)->p[0]);  \
191         (_s)->p += 2;                                 \
192     } while (0)
193 
194 /** extract a 32 bit value from stream */
195 #define stream_ext_u32_le(_s, _v)                     \
196     do                                                \
197     {                                                 \
198         (_v) = (u32) ((_s)->p[3] << 24 |              \
199                       (_s)->p[2] << 16 |              \
200                       (_s)->p[1] << 8  |              \
201                       (_s)->p[0]);                    \
202         (_s)->p += 4;                                 \
203     } while (0)
204 
205 typedef struct _player_state_info
206 {
207     AVFormatContext *p_format_ctx;
208     AVCodecContext  *p_audio_codec_ctx;
209     AVCodecContext  *p_video_codec_ctx;
210     AVCodec         *p_audio_codec;
211     AVCodec         *p_video_codec;
212 
213     int              audio_stream_index;
214     int              video_stream_index;
215     double           audioTimeout;
216     double           videoTimeout;
217 
218     /* LK_TODO delete this after we fix the problem */
219     AVFrame         *frame;
220     AVPacket        avpkt;
221 
222     AVBitStreamFilterContext *bsfc;
223 
224 } PLAYER_STATE_INFO;
225 
226 static int xrdpvr_read_from_client(void *channel, STREAM *s, int bytes, int timeout);
227 static int xrdpvr_write_to_client(void *channel, STREAM *s);
228 
229 #endif /* __XRDPVR_INTERNAL_H__ */
230