2 * yuv4mpeg.h: Functions for reading and writing "new" YUV4MPEG2 streams.
4 * Stream format is described at the end of this file.
7 * Copyright (C) 2001 Matthew J. Marjanovic <maddog@mir.com>
9 * This file is ripped from the lavtools package (mjpeg.sourceforge.net)
10 * Ported to mplayer by Rik Snel <rsnel@cube.dyndns.org>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 #include "stream/stream.h"
36 /************************************************************************
37 * error codes returned by y4m_* functions
38 ************************************************************************/
40 #define Y4M_ERR_RANGE 1
41 #define Y4M_ERR_SYSTEM 2
42 #define Y4M_ERR_HEADER 3
43 #define Y4M_ERR_BADTAG 4
44 #define Y4M_ERR_MAGIC 5
46 #define Y4M_ERR_XXTAGS 7
49 /* generic 'unknown' value for integer parameters (e.g. interlace, height) */
50 #define Y4M_UNKNOWN -1
54 /************************************************************************
55 * 'ratio' datatype, for rational numbers
56 * (see 'ratio' functions down below)
57 ************************************************************************/
58 typedef struct _y4m_ratio
{
59 int n
; /* numerator */
60 int d
; /* denominator */
64 /************************************************************************
65 * useful standard framerates (as ratios)
66 ************************************************************************/
67 extern const y4m_ratio_t y4m_fps_UNKNOWN
;
68 extern const y4m_ratio_t y4m_fps_NTSC_FILM
; /* 24000/1001 film (in NTSC) */
69 extern const y4m_ratio_t y4m_fps_FILM
; /* 24fps film */
70 extern const y4m_ratio_t y4m_fps_PAL
; /* 25fps PAL */
71 extern const y4m_ratio_t y4m_fps_NTSC
; /* 30000/1001 NTSC */
72 extern const y4m_ratio_t y4m_fps_30
; /* 30fps */
73 extern const y4m_ratio_t y4m_fps_PAL_FIELD
; /* 50fps PAL field rate */
74 extern const y4m_ratio_t y4m_fps_NTSC_FIELD
; /* 60000/1001 NTSC field rate */
75 extern const y4m_ratio_t y4m_fps_60
; /* 60fps */
77 /************************************************************************
78 * useful standard sample (pixel) aspect ratios
79 ************************************************************************/
80 extern const y4m_ratio_t y4m_sar_UNKNOWN
;
81 extern const y4m_ratio_t y4m_sar_SQUARE
; /* square pixels */
82 extern const y4m_ratio_t y4m_sar_NTSC_CCIR601
; /* 525-line (NTSC) Rec.601 */
83 extern const y4m_ratio_t y4m_sar_NTSC_16_9
; /* 16:9 NTSC/Rec.601 */
84 extern const y4m_ratio_t y4m_sar_NTSC_SVCD_4_3
; /* NTSC SVCD 4:3 */
85 extern const y4m_ratio_t y4m_sar_NTSC_SVCD_16_9
;/* NTSC SVCD 16:9 */
86 extern const y4m_ratio_t y4m_sar_PAL_CCIR601
; /* 625-line (PAL) Rec.601 */
87 extern const y4m_ratio_t y4m_sar_PAL_16_9
; /* 16:9 PAL/Rec.601 */
88 extern const y4m_ratio_t y4m_sar_PAL_SVCD_4_3
; /* PAL SVCD 4:3 */
89 extern const y4m_ratio_t y4m_sar_PAL_SVCD_16_9
; /* PAL SVCD 16:9 */
92 /************************************************************************
93 * 'xtag_list' --- list of unparsed and/or meta/X header tags
95 * Do not touch this structure directly!
97 * Use the y4m_xtag_*() functions (see below).
98 * You must initialize/finalize this structure before/after use.
99 ************************************************************************/
100 #define Y4M_MAX_XTAGS 32 /* maximum number of xtags in list */
101 #define Y4M_MAX_XTAG_SIZE 32 /* max length of an xtag (including 'X') */
102 typedef struct _y4m_xtag_list
{
104 char *tags
[Y4M_MAX_XTAGS
];
109 /************************************************************************
110 * 'stream_info' --- stream header information
112 * Do not touch this structure directly!
114 * Use the y4m_si_*() functions (see below).
115 * You must initialize/finalize this structure before/after use.
116 ************************************************************************/
117 typedef struct _y4m_stream_info
{
118 /* values from header */
121 int interlace
; /* see Y4M_ILACE_* definitions below */
122 y4m_ratio_t framerate
; /* frames-per-second; 0:0 == unknown */
123 y4m_ratio_t sampleaspect
; /* pixel width/height; 0:0 == unknown */
124 /* computed/derivative values */
125 int framelength
; /* bytes of data per frame (not including header) */
126 /* mystical X tags */
127 y4m_xtag_list_t x_tags
;
130 /* possible options for the interlace parameter */
131 #define Y4M_ILACE_NONE 0 /* non-interlaced, progressive frame */
132 #define Y4M_ILACE_TOP_FIRST 1 /* interlaced, top-field first */
133 #define Y4M_ILACE_BOTTOM_FIRST 2 /* interlaced, bottom-field first */
136 /************************************************************************
137 * 'frame_info' --- frame header information
139 * Do not touch this structure directly!
141 * Use the y4m_fi_*() functions (see below).
142 * You must initialize/finalize this structure before/after use.
143 ************************************************************************/
144 typedef struct _y4m_frame_info
{
145 /* mystical X tags */
146 y4m_xtag_list_t x_tags
;
157 /************************************************************************
159 ************************************************************************/
161 /* 'normalize' a ratio (remove common factors) */
162 void y4m_ratio_reduce(y4m_ratio_t
*r
);
164 /* parse "nnn:ddd" into a ratio (returns Y4M_OK or Y4M_ERR_RANGE) */
165 int y4m_parse_ratio(y4m_ratio_t
*r
, const char *s
);
167 /* quick test of two ratios for equality (i.e. identical components) */
168 #define Y4M_RATIO_EQL(a,b) ( ((a).n == (b).n) && ((a).d == (b).d) )
170 /* quick conversion of a ratio to a double (no divide-by-zero check!) */
171 #define Y4M_RATIO_DBL(r) ((double)(r).n / (double)(r).d)
175 /************************************************************************
178 * o Before using an xtag_list (but after the structure/memory has been
179 * allocated), you must initialize it via y4m_init_xtag_list().
180 * o After using an xtag_list (but before the structure is released),
181 * call y4m_fini_xtag_list() to free internal memory.
183 ************************************************************************/
185 /* initialize an xtag_list structure */
186 void y4m_init_xtag_list(y4m_xtag_list_t
*xtags
);
188 /* finalize an xtag_list structure */
189 void y4m_fini_xtag_list(y4m_xtag_list_t
*xtags
);
191 /* make one xtag_list into a copy of another */
192 void y4m_copy_xtag_list(y4m_xtag_list_t
*dest
, const y4m_xtag_list_t
*src
);
194 /* return number of tags in an xtag_list */
195 int y4m_xtag_count(const y4m_xtag_list_t
*xtags
);
197 /* access n'th tag in an xtag_list */
198 const char *y4m_xtag_get(const y4m_xtag_list_t
*xtags
, int n
);
200 /* append a new tag to an xtag_list
201 returns: Y4M_OK - success
202 Y4M_ERR_XXTAGS - list is already full */
203 int y4m_xtag_add(y4m_xtag_list_t
*xtags
, const char *tag
);
205 /* remove a tag from an xtag_list
206 returns: Y4M_OK - success
207 Y4M_ERR_RANGE - n is out of range */
208 int y4m_xtag_remove(y4m_xtag_list_t
*xtags
, int n
);
210 /* remove all tags from an xtag_list
211 returns: Y4M_OK - success */
212 int y4m_xtag_clearlist(y4m_xtag_list_t
*xtags
);
214 /* append copies of tags from src list to dest list
215 returns: Y4M_OK - success
216 Y4M_ERR_XXTAGS - operation would overfill dest list */
217 int y4m_xtag_addlist(y4m_xtag_list_t
*dest
, const y4m_xtag_list_t
*src
);
221 /************************************************************************
224 * o Before using a *_info structure (but after the structure/memory has
225 * been allocated), you must initialize it via y4m_init_*_info().
226 * o After using a *_info structure (but before the structure is released),
227 * call y4m_fini_*_info() to free internal memory.
228 * o Use the 'set' and 'get' accessors to modify or access the fields in
229 * the structures; don't touch the structure directly. (Ok, so there
230 * is no really convenient C syntax to prevent you from doing this,
231 * but we are all responsible programmers here, so just don't do it!)
233 ************************************************************************/
235 /* initialize a stream_info structure */
236 void y4m_init_stream_info(y4m_stream_info_t
*i
);
238 /* finalize a stream_info structure */
239 void y4m_fini_stream_info(y4m_stream_info_t
*i
);
241 /* make one stream_info into a copy of another */
242 void y4m_copy_stream_info(y4m_stream_info_t
*dest
, y4m_stream_info_t
*src
);
244 /* access or set stream_info fields */
245 void y4m_si_set_width(y4m_stream_info_t
*si
, int width
);
246 int y4m_si_get_width(y4m_stream_info_t
*si
);
247 void y4m_si_set_height(y4m_stream_info_t
*si
, int height
);
248 int y4m_si_get_height(y4m_stream_info_t
*si
);
249 void y4m_si_set_interlace(y4m_stream_info_t
*si
, int interlace
);
250 int y4m_si_get_interlace(y4m_stream_info_t
*si
);
251 void y4m_si_set_framerate(y4m_stream_info_t
*si
, y4m_ratio_t framerate
);
252 y4m_ratio_t
y4m_si_get_framerate(y4m_stream_info_t
*si
);
253 void y4m_si_set_sampleaspect(y4m_stream_info_t
*si
, y4m_ratio_t sar
);
254 y4m_ratio_t
y4m_si_get_sampleaspect(y4m_stream_info_t
*si
);
255 int y4m_si_get_framelength(y4m_stream_info_t
*si
);
257 /* access stream_info xtag_list */
258 y4m_xtag_list_t
*y4m_si_xtags(y4m_stream_info_t
*si
);
261 /* initialize a frame_info structure */
262 void y4m_init_frame_info(y4m_frame_info_t
*i
);
264 /* finalize a frame_info structure */
265 void y4m_fini_frame_info(y4m_frame_info_t
*i
);
267 /* make one frame_info into a copy of another */
268 void y4m_copy_frame_info(y4m_frame_info_t
*dest
, y4m_frame_info_t
*src
);
270 /* access frame_info xtag_list */
271 y4m_xtag_list_t
*y4m_fi_xtags(y4m_frame_info_t
*fi
);
275 /************************************************************************
276 * blocking read and write functions
278 * o guaranteed to transfer entire payload (or fail)
280 * 0 (zero) complete success
281 * -(# of remaining bytes) error (and errno left set)
282 * +(# of remaining bytes) EOF (for y4m_read only)
284 ************************************************************************/
286 /* read len bytes from fd into buf */
287 ssize_t
y4m_read(stream_t
*s
, char *buf
, size_t len
);
290 /* write len bytes from fd into buf */
291 ssize_t
y4m_write(int fd
, char *buf
, size_t len
);
295 /************************************************************************
296 * stream header processing functions
300 * Y4M_ERR_* - error (see y4m_strerr() for descriptions)
302 ************************************************************************/
304 /* parse a string of stream header tags */
305 int y4m_parse_stream_tags(char *s
, y4m_stream_info_t
*i
);
307 /* read a stream header from file descriptor fd */
308 int y4m_read_stream_header(stream_t
*s
, y4m_stream_info_t
*i
);
311 /* write a stream header to file descriptor fd */
312 int y4m_write_stream_header(int fd
, y4m_stream_info_t
*i
);
316 /************************************************************************
317 * frame processing functions
321 * Y4M_ERR_* - error (see y4m_strerr() for descriptions)
323 ************************************************************************/
325 /* read a frame header from file descriptor fd */
326 int y4m_read_frame_header(stream_t
*s
, y4m_frame_info_t
*i
);
329 /* write a frame header to file descriptor fd */
330 int y4m_write_frame_header(int fd
, y4m_frame_info_t
*i
);
333 /* read a complete frame (header + data)
334 o yuv[3] points to three buffers, one each for Y, U, V planes */
335 int y4m_read_frame(stream_t
*s
, y4m_stream_info_t
*si
,
336 y4m_frame_info_t
*fi
, unsigned char *yuv
[3]);
339 /* write a complete frame (header + data)
340 o yuv[3] points to three buffers, one each for Y, U, V planes */
341 int y4m_write_frame(int fd
, y4m_stream_info_t
*si
,
342 y4m_frame_info_t
*fi
, unsigned char *yuv
[3]);
346 /* read a complete frame (header + data), but de-interleave fields
347 into two separate buffers
348 o upper_field[3] same as yuv[3] above, but for upper field
349 o lower_field[3] same as yuv[3] above, but for lower field
351 int y4m_read_fields(int fd
, y4m_stream_info_t
*si
, y4m_frame_info_t
*fi
,
352 unsigned char *upper_field
[3],
353 unsigned char *lower_field
[3]);
355 /* write a complete frame (header + data), but interleave fields
356 from two separate buffers
357 o upper_field[3] same as yuv[3] above, but for upper field
358 o lower_field[3] same as yuv[3] above, but for lower field
360 int y4m_write_fields(int fd
, y4m_stream_info_t
*si
, y4m_frame_info_t
*fi
,
361 unsigned char *upper_field
[3],
362 unsigned char *lower_field
[3]);
366 /************************************************************************
367 * miscellaneous functions
368 ************************************************************************/
370 /* convenient dump of stream header info via mjpeg_log facility
371 * - each logged/printed line is prefixed by 'prefix'
373 void y4m_log_stream_info(const char *prefix
, y4m_stream_info_t
*i
);
375 /* convert a Y4M_ERR_* error code into mildly explanatory string */
376 const char *y4m_strerr(int err
);
378 /* set 'allow_unknown_tag' flag for library...
379 o yn = 0 : unknown header tags will produce a parsing error
380 o yn = 1 : unknown header tags/values will produce a warning, but
381 are otherwise passed along via the xtags list
382 o yn = -1: don't change, just return current setting
384 return value: previous setting of flag
386 int y4m_allow_unknown_tags(int yn
);
393 /************************************************************************
394 ************************************************************************
396 Description of the (new!, forever?) YUV4MPEG2 stream format:
399 o one '\n' terminated STREAM-HEADER
400 o unlimited number of FRAMEs
403 o one '\n' terminated FRAME-HEADER
404 o "length" octets of planar YCrCb 4:2:0 image data
405 (if frame is interlaced, then the two fields are interleaved)
408 STREAM-HEADER consists of
409 o string "YUV4MPEG2 " (note the space after the '2')
410 o unlimited number of ' ' separated TAGGED-FIELDs
411 o '\n' line terminator
413 FRAME-HEADER consists of
414 o string "FRAME " (note the space after the 'E')
415 o unlimited number of ' ' separated TAGGED-FIELDs
416 o '\n' line terminator
419 TAGGED-FIELD consists of
420 o single ascii character tag
421 o VALUE (which does not contain whitespace)
424 o integer (base 10 ascii representation)
426 or o single ascii character
427 or o generic ascii string
430 o numerator (integer)
432 o denominator (integer)
435 The currently supported tags for the STREAM-HEADER:
436 W - [integer] frame width, pixels, should be > 0
437 H - [integer] frame height, pixels, should be > 0
438 I - [char] interlacing: p - progressive (none)
440 b - bottom-field-first
442 F - [ratio] frame-rate, 0:0 == unknown
443 A - [ratio] sample (pixel) aspect ratio, 0:0 == unknown
444 X - [character string] 'metadata' (unparsed, but passed around)
446 The currently supported tags for the FRAME-HEADER:
447 X - character string 'metadata' (unparsed, but passed around)
449 ************************************************************************
450 ************************************************************************/
452 #endif /* YUV4MPEG_H */