1 /*
2 * YUV4MPEG format
3 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
25
26 #define Y4M_MAGIC "YUV4MPEG2"
27 #define Y4M_FRAME_MAGIC "FRAME"
28 #define Y4M_LINE_MAX 256
29
30 #if CONFIG_YUV4MPEGPIPE_MUXER
32 {
35 int raten, rated, aspectn, aspectd,
n;
36 char inter;
38
42
45
48
49 if (aspectn == 0 && aspectd == 1)
50 aspectd = 0; // 0:0 means unknown
51
52 inter = 'p'; /* progressive is the default */
56 inter = 'p';
58 inter = 't';
60 inter = 'b';
61 }
62
65 colorspace = " Cmono";
66 break;
68 colorspace = " Cmono16";
69 break;
71 colorspace = " C411 XYSCSS=411";
72 break;
77 default: colorspace = " C420jpeg XYSCSS=420JPEG"; break;
78 }
79 break;
81 colorspace = " C422 XYSCSS=422";
82 break;
84 colorspace = " C444 XYSCSS=444";
85 break;
87 colorspace = " C420p9 XYSCSS=420P9";
88 break;
90 colorspace = " C422p9 XYSCSS=422P9";
91 break;
93 colorspace = " C444p9 XYSCSS=444P9";
94 break;
96 colorspace = " C420p10 XYSCSS=420P10";
97 break;
99 colorspace = " C422p10 XYSCSS=422P10";
100 break;
102 colorspace = " C444p10 XYSCSS=444P10";
103 break;
105 colorspace = " C420p12 XYSCSS=420P12";
106 break;
108 colorspace = " C422p12 XYSCSS=422P12";
109 break;
111 colorspace = " C444p12 XYSCSS=444P12";
112 break;
114 colorspace = " C420p14 XYSCSS=420P14";
115 break;
117 colorspace = " C422p14 XYSCSS=422P14";
118 break;
120 colorspace = " C444p14 XYSCSS=444P14";
121 break;
123 colorspace = " C420p16 XYSCSS=420P16";
124 break;
126 colorspace = " C422p16 XYSCSS=422P16";
127 break;
129 colorspace = " C444p16 XYSCSS=444P16";
130 break;
131 }
132
133 /* construct stream header, if this is the first frame */
135 Y4M_MAGIC, width, height, raten, rated, inter,
136 aspectn, aspectd, colorspace);
137
139 }
140
142 {
148 int i;
150 char buf1[20];
152
154 picture = &picture_tmp;
155
156 /* for the first packet we have to output the header as well */
157 if (*first_pkt) {
158 *first_pkt = 0;
159 if (yuv4_generate_header(s, buf2) < 0) {
161 "Error. YUV4MPEG stream header write failed.\n");
163 } else {
165 }
166 }
167
168 /* construct frame header */
169
172
175
176 ptr = picture->
data[0];
177
184 break;
201 width *= 2;
202 break;
203 default:
207 }
208
209 for (i = 0; i <
height; i++) {
212 }
213
216 // Adjust for smaller Cb and Cr planes
218 &v_chroma_shift);
221
222 ptr1 = picture->
data[1];
223 ptr2 = picture->
data[2];
224 for (i = 0; i <
height; i++) {
/* Cb */
227 }
228 for (i = 0; i <
height; i++) {
/* Cr */
231 }
232 }
233
234 return 0;
235 }
236
238 {
240
243
247 }
248
252 "stream, some mjpegtools might not work.\n");
253 break;
259 break;
277 "Use '-strict -1' to encode to this pixel format.\n",
280 }
282 "Mjpegtools will not work.\n");
283 break;
284 default:
286 "yuv444p, yuv422p, yuv420p, yuv411p and gray8 pixel formats. "
287 "And using 'strict -1' also yuv444p9, yuv422p9, yuv420p9, "
288 "yuv444p10, yuv422p10, yuv420p10, "
289 "yuv444p12, yuv422p12, yuv420p12, "
290 "yuv444p14, yuv422p14, yuv420p14, "
291 "yuv444p16, yuv422p16, yuv420p16 "
292 "and gray16 pixel formats. "
293 "Use -pix_fmt to select one.\n");
295 }
296
297 *first_pkt = 1;
298 return 0;
299 }
300
302 .
name =
"yuv4mpegpipe",
304 .extensions = "y4m",
305 .priv_data_size = sizeof(int),
311 };
312 #endif
313
314 /* Header size increased to allow room for optional flags */
315 #define MAX_YUV4_HEADER 80
316 #define MAX_FRAME_HEADER 80
317
319 {
321 // the longest option
322 char *tokstart, *tokend, *header_end, interlaced = '?';
323 int i;
325 int width = -1, height = -1, raten = 0,
326 rated = 0, aspectn = 0, aspectd = 0;
330
333 if (header[i] == '\n') {
334 header[i + 1] = 0x20; // Add a space after last option.
335 // Makes parsing "444" vs "444alpha" easier.
336 header[i + 2] = 0;
337 break;
338 }
339 }
340 if (i == MAX_YUV4_HEADER)
341 return -1;
343 return -1;
344
345 header_end = &header[i + 1]; // Include space
346 for (tokstart = &header[strlen(
Y4M_MAGIC) + 1];
347 tokstart < header_end; tokstart++) {
348 if (*tokstart == 0x20)
349 continue;
350 switch (*tokstart++) {
351 case 'W': // Width. Required.
352 width = strtol(tokstart, &tokend, 10);
353 tokstart = tokend;
354 break;
355 case 'H': // Height. Required.
356 height = strtol(tokstart, &tokend, 10);
357 tokstart = tokend;
358 break;
359 case 'C': // Color space
360 if (strncmp("420jpeg", tokstart, 7) == 0) {
363 } else if (strncmp("420mpeg2", tokstart, 8) == 0) {
366 } else if (strncmp("420paldv", tokstart, 8) == 0) {
369 } else if (strncmp("420p16", tokstart, 6) == 0) {
371 } else if (strncmp("422p16", tokstart, 6) == 0) {
373 } else if (strncmp("444p16", tokstart, 6) == 0) {
375 } else if (strncmp("420p14", tokstart, 6) == 0) {
377 } else if (strncmp("422p14", tokstart, 6) == 0) {
379 } else if (strncmp("444p14", tokstart, 6) == 0) {
381 } else if (strncmp("420p12", tokstart, 6) == 0) {
383 } else if (strncmp("422p12", tokstart, 6) == 0) {
385 } else if (strncmp("444p12", tokstart, 6) == 0) {
387 } else if (strncmp("420p10", tokstart, 6) == 0) {
389 } else if (strncmp("422p10", tokstart, 6) == 0) {
391 } else if (strncmp("444p10", tokstart, 6) == 0) {
393 } else if (strncmp("420p9", tokstart, 5) == 0) {
395 } else if (strncmp("422p9", tokstart, 5) == 0) {
397 } else if (strncmp("444p9", tokstart, 5) == 0) {
399 } else if (strncmp("420", tokstart, 3) == 0) {
402 } else if (strncmp("411", tokstart, 3) == 0) {
404 } else if (strncmp("422", tokstart, 3) == 0) {
406 } else if (strncmp("444alpha", tokstart, 8) == 0 ) {
408 "YUV4MPEG stream.\n");
409 return -1;
410 } else if (strncmp("444", tokstart, 3) == 0) {
412 } else if (strncmp("mono16", tokstart, 6) == 0) {
414 } else if (strncmp("mono", tokstart, 4) == 0) {
416 } else {
418 "pixel format.\n");
419 return -1;
420 }
421 while (tokstart < header_end && *tokstart != 0x20)
422 tokstart++;
423 break;
424 case 'I': // Interlace type
425 interlaced = *tokstart++;
426 break;
427 case 'F': // Frame rate
428 sscanf(tokstart, "%d:%d", &raten, &rated); // 0:0 if unknown
429 while (tokstart < header_end && *tokstart != 0x20)
430 tokstart++;
431 break;
432 case 'A': // Pixel aspect
433 sscanf(tokstart, "%d:%d", &aspectn, &aspectd); // 0:0 if unknown
434 while (tokstart < header_end && *tokstart != 0x20)
435 tokstart++;
436 break;
437 case 'X': // Vendor extensions
438 if (strncmp("YSCSS=", tokstart, 6) == 0) {
439 // Older nonstandard pixel format representation
440 tokstart += 6;
441 if (strncmp("420JPEG", tokstart, 7) == 0)
443 else if (strncmp("420MPEG2", tokstart, 8) == 0)
445 else if (strncmp("420PALDV", tokstart, 8) == 0)
447 else if (strncmp("420P9", tokstart, 5) == 0)
449 else if (strncmp("422P9", tokstart, 5) == 0)
451 else if (strncmp("444P9", tokstart, 5) == 0)
453 else if (strncmp("420P10", tokstart, 6) == 0)
455 else if (strncmp("422P10", tokstart, 6) == 0)
457 else if (strncmp("444P10", tokstart, 6) == 0)
459 else if (strncmp("420P12", tokstart, 6) == 0)
461 else if (strncmp("422P12", tokstart, 6) == 0)
463 else if (strncmp("444P12", tokstart, 6) == 0)
465 else if (strncmp("420P14", tokstart, 6) == 0)
467 else if (strncmp("422P14", tokstart, 6) == 0)
469 else if (strncmp("444P14", tokstart, 6) == 0)
471 else if (strncmp("420P16", tokstart, 6) == 0)
473 else if (strncmp("422P16", tokstart, 6) == 0)
475 else if (strncmp("444P16", tokstart, 6) == 0)
477 else if (strncmp("411", tokstart, 3) == 0)
479 else if (strncmp("422", tokstart, 3) == 0)
481 else if (strncmp("444", tokstart, 3) == 0)
483 }
484 while (tokstart < header_end && *tokstart != 0x20)
485 tokstart++;
486 break;
487 }
488 }
489
490 if (width == -1 || height == -1) {
492 return -1;
493 }
494
498 else
499 pix_fmt = alt_pix_fmt;
500 }
501
502 if (raten <= 0 || rated <= 0) {
503 // Frame rate unknown
504 raten = 25;
505 rated = 1;
506 }
507
508 if (aspectn == 0 && aspectd == 0) {
509 // Pixel aspect unknown
510 aspectd = 1;
511 }
512
514 if (!st)
518 av_reduce(&raten, &rated, raten, rated, (1UL << 31) - 1);
525
526 switch (interlaced){
527 case 'p':
529 break;
530 case 't':
532 break;
533 case 'b':
535 break;
536 case 'm':
538 "interlaced and non-interlaced frames.\n");
539 case '?':
541 break;
542 default:
545 }
546
547 return 0;
548 }
549
551 {
552 int i;
556
559 if (header[i] == '\n') {
560 header[i + 1] = 0;
561 break;
562 }
563 }
568 else if (i == MAX_FRAME_HEADER)
570
573
576
578 if (packet_size < 0)
579 return packet_size;
580
582 if (ret < 0)
584 else if (ret != packet_size)
586
588 return 0;
589 }
590
592 {
593 /* check file header */
596 else
597 return 0;
598 }
599
600 #if CONFIG_YUV4MPEGPIPE_DEMUXER
602 .
name =
"yuv4mpegpipe",
607 .extensions = "y4m",
608 };
609 #endif