Update Copyright
[rawv.git] / rawv.h
blobea91d6f322105945862024723621ca0ff56d3fc6
1 #ifndef _RAWV_H_
2 #define _RAWV_H_
4 /*
5 * RAWV coding-scheme for low-latency loosless video streaming
6 * Copyright (C) 2010 Kirill Smelkov <kirr@navytux.spb.ru>
8 * You may use and redistribute this work under the Creative Commons
9 * Attribution-Share Alike (CC-BY-SA) 3.0. You are free to Share (to copy,
10 * distribute, display, and perform the work) and to Remix (to make derivative
11 * works), under the following conditions:
13 * 1. Attribution. You must attribute the work in the manner specified by the
14 * author or licensor (but not in any way that suggests that they endorse you
15 * or your use of the work).
16 * 2. Share Alike. If you alter, transform, or build upon this work, you may
17 * distribute the resulting work only under the same, similar or a compatible
18 * license.
21 * Abstract
22 * --------
24 * A scheme for transmitting progressive PAL/NTSC video over 1Gbps Ethernet
25 * LAN is presented. Loosless coding, low end-to-end latencies (under 100ms in
26 * non-specialized test setup) and packet loss tolerance make this scheme
27 * applicable for specialized tasks in medical, industrial and military
28 * environments. Development effort for both software and hardware
29 * implementations is shown to be low because of design simplicity.
32 * Coding
33 * ------
35 * - each frame is transmitted in series of independent fragments
36 * - each fragment carries header and payload
37 * - header:
39 * 1. special 4-byte magic identifying this coding method,
40 * 2. version of coding subvariant and fragment flags,
41 * 3. fragment's frame sequence number,
42 * 4. fragment sequence number and number of fragments in the whole frame,
43 * 5. width, height and pixel format of its frame,
44 * 6. fragment startline and number of lines in this fragment,
45 * 7. padding;
48 * < - - - - - - w i d t h - - - - - - >
49 * +-----------------------------------+ ^
50 * | | |
51 * | | |
52 * | | |
53 * | |
54 * frag_startline -->|-----------------------------------| h
55 * | ' | e
56 * | ' frag_nlines | i
57 * | ' | g
58 * |-----------------------------------| h
59 * | | t
60 * | |
61 * | | |
62 * | | |
63 * | | |
64 * +-----------------------------------+ v
68 * 0 1 2 3
69 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
70 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71 * 0 | 0x52 ('R') | 0x41 ('A') | 0x57 ('W') | 0x56 ('V') |
72 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73 * 32 | Version | Flags | Frame Number |
74 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75 * 64 | Fragment Number | Fragments Total |
76 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77 * 96 | Frame Width | Frame Height |
78 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
79 * 128 | Pixel Format |
80 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
81 * 160 | Fragment Startline | Fragment Lines |
82 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
83 * 192 | Reserved |
84 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
85 * 224 | Reserved |
86 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
89 * Version
90 * Version of coding used. This specification describes coding for
91 * version 0x01.
93 * Flags
94 * This field is currently reserved to be 0x00.
96 * Frame Number (nframe)
97 * Sequence number of this fragment's frame.
99 * Fragment Number (nfragment)
100 * Sequence number of this fragment. Starts from 0 for each new frame.
102 * Fragments Total (fragments_total)
103 * Total number of fragments in current frame.
105 * Frame Width (width)
106 * Frame width in pixels.
108 * Frame Height (height)
109 * Frame height in pixels.
111 * Pixel Format (pixfmt)
112 * According to http://fourcc.org/yuv.php; recommended are YUYV, YUY2,
113 * UYVY, GREY, Y800 and Y8.
115 * Fragment Startline (frag_startline)
116 * Vertical position of this fragment's first line relative to frame top.
118 * Fragment Lines (frag_nlines)
119 * Number of lines in this fragment.
122 * - payload:
124 * 1. right after header go raw pixel data in specified-in-header pixel format.
125 * There should be data for at least
127 * frag_nlines * width (1)
129 * pixels, which is
131 * frag_nlines * width * pixsize(pixfmt) (2)
133 * bytes.
135 * 2. there could be more data than specified in (2). in such a case,
136 * trailer content is out of this specification scope.
139 * TODO talk about packet reordering
140 * TODO talk about packet loss
141 * TODO talk about needed bandwith for typical streams
142 * (PAL color, PAL mono, NTSC color, NTSC mono)
145 * References:
147 * [1] RFC3550 -- RTP: A Transport Protocol for Real-Time Applications
148 * [2] RFC3551 -- RTP Profile for Audio and Video Conferences with Minimal Control
149 * [3] RFC4175 -- RTP Payload Format for Uncompressed Video
150 * [4] IIDC 1394-based Digital Camera Specification Ver.1.32
151 * [5] MPEG-TS (?)
156 * RAWV library
157 * Copyright (C) 2010,2011 Kirill Smelkov <kirr@navytux.spb.ru>
158 * Copyright (C) 2011 Marine Bridge and Navigation Systems (http://mns.spb.ru/)
160 * This library is free software; you can redistribute it and/or
161 * modify it under the terms of the GNU Lesser General Public
162 * License as published by the Free Software Foundation; either
163 * version 2.1 of the License, or (at your option) any later version.
165 * This library is distributed in the hope that it will be useful,
166 * but WITHOUT ANY WARRANTY; without even the implied warranty of
167 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
168 * Lesser General Public License for more details.
170 * You should have received a copy of the GNU Lesser General Public
171 * License along with this library; if not, write to the Free Software
172 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
175 #include <asm/types.h>
176 #include <sys/types.h>
177 #include <stdexcept>
179 #include <vector>
180 #include <arpa/inet.h>
182 struct SDL_Surface;
183 struct SDL_Overlay;
185 namespace rawv {
187 using std::vector;
190 /* XXX endiannes ? */
191 #define MKTAG32(a,b,c,d) (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
195 * RAWV packet header
197 #pragma pack(push, 1)
198 struct rawv_header {
199 __u32 magic;
201 __u8 version;
202 __u8 __reserved_for_flags;
203 __u16 nframe;
204 // XXX here ?
205 #define NFRAME_MAX 0x10000
207 __u16 nfragment;
208 __u16 fragments_total;
210 __u16 width;
211 __u16 height;
213 __u32 pixfmt;
215 __u16 frag_startline;
216 __u16 frag_nlines;
218 /* padding, so that the whole header is 32 bytes */
219 __u32 __reserved[2];
221 #pragma pack(pop)
224 * One video frame
226 struct Frame {
227 __u8 *start;
228 size_t length; /* ~= height * bytesperline */
230 int width, height, bytesperline;
231 __u32 pixfmt_4cc;
232 __u32 sequence;
233 // XXX timestamp ?
235 /* flags */
237 /* if we know top/bottom fields are in wrong order in this frame
239 * +1 -- swap fields
240 * -1 -- swap and shift one filed XXX write more
242 signed int interlace_tb_swapped : 2;
245 struct FrameSubscription {
246 void (*func)(const Frame *, void *);
247 void *self;
249 bool operator== (const FrameSubscription &rhs)
251 return (func == rhs.func) && (self == rhs.self);
257 * Displays video frames to YUY2 overlay
259 struct View
261 View(int w, int h, bool upscale, const char *title);
262 ~View();
264 /* whether to upscale frame on display.
266 * NOTE: only upscale is supported, not downscale
268 bool upscale;
270 void display_frame(const Frame *f);
271 static void __display_frame(const Frame *f, void *self);
274 SDL_Surface *display;
275 SDL_Overlay *overlay;
280 * Captures video frames from V4L2 source
282 struct VideoCapture
284 VideoCapture(const char *dev_name, int width, int height, int interlace_tb_swapped=0, int queue_len=4);
285 ~VideoCapture();
287 void start_capture();
288 void stop_capture();
290 void subscribe(void (*func)(const Frame *, void *), void *self);
291 void unsubscribe(void (*func)(const Frame *, void *), void *self);
293 // XXX naming
294 int read_frame();
298 int fd;
300 vector<Frame> buffers;
301 vector<FrameSubscription> subscribers;
303 bool vcapture_on;
309 * Sends video frames to network
311 struct NetTx
313 NetTx(const char *dest, int port, int mtu);
314 ~NetTx();
316 void tx_frame(const Frame *f);
317 static void __tx_frame(const Frame *f, void *self);
319 int sk;
320 struct sockaddr_in tx_addr;
321 int mtu;
326 * Receives video frames from network
328 struct NetRx
330 NetRx(const char *listen_on, int port, int mtu);
331 ~NetRx();
333 void subscribe(void (*func)(const Frame *, void *), void *self);
334 void unsubscribe(void (*func)(const Frame *, void *), void *self);
336 int handle_recv();
337 void __handle_recv(unsigned len);
340 int sk;
341 struct sockaddr_in rx_addr;
342 int mtu;
344 vector<FrameSubscription> subscribers;
345 void flush_frame();
347 vector<__u8> fragbuf; // XXX align?
348 vector<__u8> framebuf; // XXX align?
350 struct Frame f; /* current frame */
352 /* current rx state */
353 __u16 nframe, nfragment, fragments_total;
354 __u16 frag_received; /* # of fragments received in current frame */
355 __u32 frag_dropped_total; /* total # of dropped fragments */
359 /* XXX is this a good idea ? */
360 struct RawvError : std::runtime_error
362 RawvError(const char *msg);
363 ~RawvError() throw();
366 void die(const char *fmt, ...);
367 void die_errno(const char *msg);
368 void warn(const char *fmt, ...);
369 void warn_errno(const char *msg);
371 } /* rawv:: */
373 #endif