FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
yuv4mpeg.c
Go to the documentation of this file.
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 #include "avformat.h"
22 #include "internal.h"
23 #include "libavutil/pixdesc.h"
24 
25 #define Y4M_MAGIC "YUV4MPEG2"
26 #define Y4M_FRAME_MAGIC "FRAME"
27 #define Y4M_LINE_MAX 256
28 
32 };
33 
34 #if CONFIG_YUV4MPEGPIPE_MUXER
35 static int yuv4_generate_header(AVFormatContext *s, char* buf)
36 {
37  AVStream *st;
38  int width, height;
39  int raten, rated, aspectn, aspectd, n;
40  char inter;
41  const char *colorspace = "";
42 
43  st = s->streams[0];
44  width = st->codec->width;
45  height = st->codec->height;
46 
47  av_reduce(&raten, &rated, st->codec->time_base.den,
48  st->codec->time_base.num, (1UL << 31) - 1);
49 
50  aspectn = st->sample_aspect_ratio.num;
51  aspectd = st->sample_aspect_ratio.den;
52 
53  if (aspectn == 0 && aspectd == 1)
54  aspectd = 0; // 0:0 means unknown
55 
56  inter = 'p'; /* progressive is the default */
58  inter = st->codec->coded_frame->top_field_first ? 't' : 'b';
59 
60  switch (st->codec->pix_fmt) {
61  case AV_PIX_FMT_GRAY8:
62  colorspace = " Cmono";
63  break;
64  case AV_PIX_FMT_GRAY16:
65  colorspace = " Cmono16";
66  break;
67  case AV_PIX_FMT_YUV411P:
68  colorspace = " C411 XYSCSS=411";
69  break;
70  case AV_PIX_FMT_YUV420P:
71  switch (st->codec->chroma_sample_location) {
72  case AVCHROMA_LOC_TOPLEFT: colorspace = " C420paldv XYSCSS=420PALDV"; break;
73  case AVCHROMA_LOC_LEFT: colorspace = " C420mpeg2 XYSCSS=420MPEG2"; break;
74  default: colorspace = " C420jpeg XYSCSS=420JPEG"; break;
75  }
76  break;
77  case AV_PIX_FMT_YUV422P:
78  colorspace = " C422 XYSCSS=422";
79  break;
80  case AV_PIX_FMT_YUV444P:
81  colorspace = " C444 XYSCSS=444";
82  break;
84  colorspace = " C420p9 XYSCSS=420P9";
85  break;
87  colorspace = " C422p9 XYSCSS=422P9";
88  break;
90  colorspace = " C444p9 XYSCSS=444P9";
91  break;
93  colorspace = " C420p10 XYSCSS=420P10";
94  break;
96  colorspace = " C422p10 XYSCSS=422P10";
97  break;
99  colorspace = " C444p10 XYSCSS=444P10";
100  break;
102  colorspace = " C420p12 XYSCSS=420P12";
103  break;
105  colorspace = " C422p12 XYSCSS=422P12";
106  break;
108  colorspace = " C444p12 XYSCSS=444P12";
109  break;
111  colorspace = " C420p14 XYSCSS=420P14";
112  break;
114  colorspace = " C422p14 XYSCSS=422P14";
115  break;
117  colorspace = " C444p14 XYSCSS=444P14";
118  break;
120  colorspace = " C420p16 XYSCSS=420P16";
121  break;
123  colorspace = " C422p16 XYSCSS=422P16";
124  break;
126  colorspace = " C444p16 XYSCSS=444P16";
127  break;
128  }
129 
130  /* construct stream header, if this is the first frame */
131  n = snprintf(buf, Y4M_LINE_MAX, "%s W%d H%d F%d:%d I%c A%d:%d%s\n",
132  Y4M_MAGIC, width, height, raten, rated, inter,
133  aspectn, aspectd, colorspace);
134 
135  return n;
136 }
137 
138 static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
139 {
140  AVStream *st = s->streams[pkt->stream_index];
141  AVIOContext *pb = s->pb;
142  AVPicture *picture, picture_tmp;
143  int* first_pkt = s->priv_data;
144  int width, height, h_chroma_shift, v_chroma_shift;
145  int i;
146  char buf2[Y4M_LINE_MAX + 1];
147  char buf1[20];
148  uint8_t *ptr, *ptr1, *ptr2;
149 
150  memcpy(&picture_tmp, pkt->data, sizeof(AVPicture));
151  picture = &picture_tmp;
152 
153  /* for the first packet we have to output the header as well */
154  if (*first_pkt) {
155  *first_pkt = 0;
156  if (yuv4_generate_header(s, buf2) < 0) {
157  av_log(s, AV_LOG_ERROR,
158  "Error. YUV4MPEG stream header write failed.\n");
159  return AVERROR(EIO);
160  } else {
161  avio_write(pb, buf2, strlen(buf2));
162  }
163  }
164 
165  /* construct frame header */
166 
167  snprintf(buf1, sizeof(buf1), "%s\n", Y4M_FRAME_MAGIC);
168  avio_write(pb, buf1, strlen(buf1));
169 
170  width = st->codec->width;
171  height = st->codec->height;
172 
173  ptr = picture->data[0];
174 
175  switch (st->codec->pix_fmt) {
176  case AV_PIX_FMT_GRAY8:
177  case AV_PIX_FMT_YUV411P:
178  case AV_PIX_FMT_YUV420P:
179  case AV_PIX_FMT_YUV422P:
180  case AV_PIX_FMT_YUV444P:
181  break;
182  case AV_PIX_FMT_GRAY16:
183  case AV_PIX_FMT_YUV420P9:
184  case AV_PIX_FMT_YUV422P9:
185  case AV_PIX_FMT_YUV444P9:
198  width *= 2;
199  break;
200  default:
201  av_log(s, AV_LOG_ERROR, "The pixel format '%s' is not supported.\n",
203  return AVERROR(EINVAL);
204  }
205 
206  for (i = 0; i < height; i++) {
207  avio_write(pb, ptr, width);
208  ptr += picture->linesize[0];
209  }
210 
211  if (st->codec->pix_fmt != AV_PIX_FMT_GRAY8 &&
212  st->codec->pix_fmt != AV_PIX_FMT_GRAY16) {
213  // Adjust for smaller Cb and Cr planes
214  avcodec_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift,
215  &v_chroma_shift);
216  width >>= h_chroma_shift;
217  height >>= v_chroma_shift;
218 
219  ptr1 = picture->data[1];
220  ptr2 = picture->data[2];
221  for (i = 0; i < height; i++) { /* Cb */
222  avio_write(pb, ptr1, width);
223  ptr1 += picture->linesize[1];
224  }
225  for (i = 0; i < height; i++) { /* Cr */
226  avio_write(pb, ptr2, width);
227  ptr2 += picture->linesize[2];
228  }
229  }
230 
231  avio_flush(pb);
232  return 0;
233 }
234 
235 static int yuv4_write_header(AVFormatContext *s)
236 {
237  int *first_pkt = s->priv_data;
238 
239  if (s->nb_streams != 1)
240  return AVERROR(EIO);
241 
242  if (s->streams[0]->codec->codec_id != AV_CODEC_ID_RAWVIDEO) {
243  av_log(s, AV_LOG_ERROR, "ERROR: Only rawvideo supported.\n");
244  return AVERROR_INVALIDDATA;
245  }
246 
247  switch (s->streams[0]->codec->pix_fmt) {
248  case AV_PIX_FMT_YUV411P:
249  av_log(s, AV_LOG_WARNING, "Warning: generating rarely used 4:1:1 YUV "
250  "stream, some mjpegtools might not work.\n");
251  break;
252  case AV_PIX_FMT_GRAY8:
253  case AV_PIX_FMT_GRAY16:
254  case AV_PIX_FMT_YUV420P:
255  case AV_PIX_FMT_YUV422P:
256  case AV_PIX_FMT_YUV444P:
257  break;
258  case AV_PIX_FMT_YUV420P9:
259  case AV_PIX_FMT_YUV422P9:
260  case AV_PIX_FMT_YUV444P9:
274  av_log(s, AV_LOG_ERROR, "'%s' is not a official yuv4mpegpipe pixel format. "
275  "Use '-strict -1' to encode to this pixel format.\n",
277  return AVERROR(EINVAL);
278  }
279  av_log(s, AV_LOG_WARNING, "Warning: generating non standard YUV stream. "
280  "Mjpegtools will not work.\n");
281  break;
282  default:
283  av_log(s, AV_LOG_ERROR, "ERROR: yuv4mpeg can only handle "
284  "yuv444p, yuv422p, yuv420p, yuv411p and gray8 pixel formats. "
285  "And using 'strict -1' also yuv444p9, yuv422p9, yuv420p9, "
286  "yuv444p10, yuv422p10, yuv420p10, "
287  "yuv444p12, yuv422p12, yuv420p12, "
288  "yuv444p14, yuv422p14, yuv420p14, "
289  "yuv444p16, yuv422p16, yuv420p16 "
290  "and gray16 pixel formats. "
291  "Use -pix_fmt to select one.\n");
292  return AVERROR(EIO);
293  }
294 
295  *first_pkt = 1;
296  return 0;
297 }
298 
299 AVOutputFormat ff_yuv4mpegpipe_muxer = {
300  .name = "yuv4mpegpipe",
301  .long_name = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe"),
302  .extensions = "y4m",
303  .priv_data_size = sizeof(int),
304  .audio_codec = AV_CODEC_ID_NONE,
305  .video_codec = AV_CODEC_ID_RAWVIDEO,
306  .write_header = yuv4_write_header,
307  .write_packet = yuv4_write_packet,
309 };
310 #endif
311 
312 /* Header size increased to allow room for optional flags */
313 #define MAX_YUV4_HEADER 80
314 #define MAX_FRAME_HEADER 80
315 
317 {
318  char header[MAX_YUV4_HEADER + 10]; // Include headroom for
319  // the longest option
320  char *tokstart, *tokend, *header_end;
321  int i;
322  AVIOContext *pb = s->pb;
323  int width = -1, height = -1, raten = 0,
324  rated = 0, aspectn = 0, aspectd = 0;
326  enum AVChromaLocation chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED;
327  AVStream *st;
328  struct frame_attributes *s1 = s->priv_data;
329 
330  for (i = 0; i < MAX_YUV4_HEADER; i++) {
331  header[i] = avio_r8(pb);
332  if (header[i] == '\n') {
333  header[i + 1] = 0x20; // Add a space after last option.
334  // Makes parsing "444" vs "444alpha" easier.
335  header[i + 2] = 0;
336  break;
337  }
338  }
339  if (i == MAX_YUV4_HEADER)
340  return -1;
341  if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC)))
342  return -1;
343 
344  s1->interlaced_frame = 0;
345  s1->top_field_first = 0;
346  header_end = &header[i + 1]; // Include space
347  for (tokstart = &header[strlen(Y4M_MAGIC) + 1];
348  tokstart < header_end; tokstart++) {
349  if (*tokstart == 0x20)
350  continue;
351  switch (*tokstart++) {
352  case 'W': // Width. Required.
353  width = strtol(tokstart, &tokend, 10);
354  tokstart = tokend;
355  break;
356  case 'H': // Height. Required.
357  height = strtol(tokstart, &tokend, 10);
358  tokstart = tokend;
359  break;
360  case 'C': // Color space
361  if (strncmp("420jpeg", tokstart, 7) == 0) {
362  pix_fmt = AV_PIX_FMT_YUV420P;
363  chroma_sample_location = AVCHROMA_LOC_CENTER;
364  } else if (strncmp("420mpeg2", tokstart, 8) == 0) {
365  pix_fmt = AV_PIX_FMT_YUV420P;
366  chroma_sample_location = AVCHROMA_LOC_LEFT;
367  } else if (strncmp("420paldv", tokstart, 8) == 0) {
368  pix_fmt = AV_PIX_FMT_YUV420P;
369  chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
370  } else if (strncmp("420p16", tokstart, 6) == 0) {
371  pix_fmt = AV_PIX_FMT_YUV420P16;
372  } else if (strncmp("422p16", tokstart, 6) == 0) {
373  pix_fmt = AV_PIX_FMT_YUV422P16;
374  } else if (strncmp("444p16", tokstart, 6) == 0) {
375  pix_fmt = AV_PIX_FMT_YUV444P16;
376  } else if (strncmp("420p14", tokstart, 6) == 0) {
377  pix_fmt = AV_PIX_FMT_YUV420P14;
378  } else if (strncmp("422p14", tokstart, 6) == 0) {
379  pix_fmt = AV_PIX_FMT_YUV422P14;
380  } else if (strncmp("444p14", tokstart, 6) == 0) {
381  pix_fmt = AV_PIX_FMT_YUV444P14;
382  } else if (strncmp("420p12", tokstart, 6) == 0) {
383  pix_fmt = AV_PIX_FMT_YUV420P12;
384  } else if (strncmp("422p12", tokstart, 6) == 0) {
385  pix_fmt = AV_PIX_FMT_YUV422P12;
386  } else if (strncmp("444p12", tokstart, 6) == 0) {
387  pix_fmt = AV_PIX_FMT_YUV444P12;
388  } else if (strncmp("420p10", tokstart, 6) == 0) {
389  pix_fmt = AV_PIX_FMT_YUV420P10;
390  } else if (strncmp("422p10", tokstart, 6) == 0) {
391  pix_fmt = AV_PIX_FMT_YUV422P10;
392  } else if (strncmp("444p10", tokstart, 6) == 0) {
393  pix_fmt = AV_PIX_FMT_YUV444P10;
394  } else if (strncmp("420p9", tokstart, 5) == 0) {
395  pix_fmt = AV_PIX_FMT_YUV420P9;
396  } else if (strncmp("422p9", tokstart, 5) == 0) {
397  pix_fmt = AV_PIX_FMT_YUV422P9;
398  } else if (strncmp("444p9", tokstart, 5) == 0) {
399  pix_fmt = AV_PIX_FMT_YUV444P9;
400  } else if (strncmp("420", tokstart, 3) == 0) {
401  pix_fmt = AV_PIX_FMT_YUV420P;
402  chroma_sample_location = AVCHROMA_LOC_CENTER;
403  } else if (strncmp("411", tokstart, 3) == 0) {
404  pix_fmt = AV_PIX_FMT_YUV411P;
405  } else if (strncmp("422", tokstart, 3) == 0) {
406  pix_fmt = AV_PIX_FMT_YUV422P;
407  } else if (strncmp("444alpha", tokstart, 8) == 0 ) {
408  av_log(s, AV_LOG_ERROR, "Cannot handle 4:4:4:4 "
409  "YUV4MPEG stream.\n");
410  return -1;
411  } else if (strncmp("444", tokstart, 3) == 0) {
412  pix_fmt = AV_PIX_FMT_YUV444P;
413  } else if (strncmp("mono16", tokstart, 6) == 0) {
414  pix_fmt = AV_PIX_FMT_GRAY16;
415  } else if (strncmp("mono", tokstart, 4) == 0) {
416  pix_fmt = AV_PIX_FMT_GRAY8;
417  } else {
418  av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains an unknown "
419  "pixel format.\n");
420  return -1;
421  }
422  while (tokstart < header_end && *tokstart != 0x20)
423  tokstart++;
424  break;
425  case 'I': // Interlace type
426  switch (*tokstart++){
427  case '?':
428  break;
429  case 'p':
430  s1->interlaced_frame = 0;
431  break;
432  case 't':
433  s1->interlaced_frame = 1;
434  s1->top_field_first = 1;
435  break;
436  case 'b':
437  s1->interlaced_frame = 1;
438  s1->top_field_first = 0;
439  break;
440  case 'm':
441  av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed "
442  "interlaced and non-interlaced frames.\n");
443  return -1;
444  default:
445  av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
446  return -1;
447  }
448  break;
449  case 'F': // Frame rate
450  sscanf(tokstart, "%d:%d", &raten, &rated); // 0:0 if unknown
451  while (tokstart < header_end && *tokstart != 0x20)
452  tokstart++;
453  break;
454  case 'A': // Pixel aspect
455  sscanf(tokstart, "%d:%d", &aspectn, &aspectd); // 0:0 if unknown
456  while (tokstart < header_end && *tokstart != 0x20)
457  tokstart++;
458  break;
459  case 'X': // Vendor extensions
460  if (strncmp("YSCSS=", tokstart, 6) == 0) {
461  // Older nonstandard pixel format representation
462  tokstart += 6;
463  if (strncmp("420JPEG", tokstart, 7) == 0)
464  alt_pix_fmt = AV_PIX_FMT_YUV420P;
465  else if (strncmp("420MPEG2", tokstart, 8) == 0)
466  alt_pix_fmt = AV_PIX_FMT_YUV420P;
467  else if (strncmp("420PALDV", tokstart, 8) == 0)
468  alt_pix_fmt = AV_PIX_FMT_YUV420P;
469  else if (strncmp("420P9", tokstart, 5) == 0)
470  alt_pix_fmt = AV_PIX_FMT_YUV420P9;
471  else if (strncmp("422P9", tokstart, 5) == 0)
472  alt_pix_fmt = AV_PIX_FMT_YUV422P9;
473  else if (strncmp("444P9", tokstart, 5) == 0)
474  alt_pix_fmt = AV_PIX_FMT_YUV444P9;
475  else if (strncmp("420P10", tokstart, 6) == 0)
476  alt_pix_fmt = AV_PIX_FMT_YUV420P10;
477  else if (strncmp("422P10", tokstart, 6) == 0)
478  alt_pix_fmt = AV_PIX_FMT_YUV422P10;
479  else if (strncmp("444P10", tokstart, 6) == 0)
480  alt_pix_fmt = AV_PIX_FMT_YUV444P10;
481  else if (strncmp("420P12", tokstart, 6) == 0)
482  alt_pix_fmt = AV_PIX_FMT_YUV420P12;
483  else if (strncmp("422P12", tokstart, 6) == 0)
484  alt_pix_fmt = AV_PIX_FMT_YUV422P12;
485  else if (strncmp("444P12", tokstart, 6) == 0)
486  alt_pix_fmt = AV_PIX_FMT_YUV444P12;
487  else if (strncmp("420P14", tokstart, 6) == 0)
488  alt_pix_fmt = AV_PIX_FMT_YUV420P14;
489  else if (strncmp("422P14", tokstart, 6) == 0)
490  alt_pix_fmt = AV_PIX_FMT_YUV422P14;
491  else if (strncmp("444P14", tokstart, 6) == 0)
492  alt_pix_fmt = AV_PIX_FMT_YUV444P14;
493  else if (strncmp("420P16", tokstart, 6) == 0)
494  alt_pix_fmt = AV_PIX_FMT_YUV420P16;
495  else if (strncmp("422P16", tokstart, 6) == 0)
496  alt_pix_fmt = AV_PIX_FMT_YUV422P16;
497  else if (strncmp("444P16", tokstart, 6) == 0)
498  alt_pix_fmt = AV_PIX_FMT_YUV444P16;
499  else if (strncmp("411", tokstart, 3) == 0)
500  alt_pix_fmt = AV_PIX_FMT_YUV411P;
501  else if (strncmp("422", tokstart, 3) == 0)
502  alt_pix_fmt = AV_PIX_FMT_YUV422P;
503  else if (strncmp("444", tokstart, 3) == 0)
504  alt_pix_fmt = AV_PIX_FMT_YUV444P;
505  }
506  while (tokstart < header_end && *tokstart != 0x20)
507  tokstart++;
508  break;
509  }
510  }
511 
512  if (width == -1 || height == -1) {
513  av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
514  return -1;
515  }
516 
517  if (pix_fmt == AV_PIX_FMT_NONE) {
518  if (alt_pix_fmt == AV_PIX_FMT_NONE)
519  pix_fmt = AV_PIX_FMT_YUV420P;
520  else
521  pix_fmt = alt_pix_fmt;
522  }
523 
524  if (raten <= 0 || rated <= 0) {
525  // Frame rate unknown
526  raten = 25;
527  rated = 1;
528  }
529 
530  if (aspectn == 0 && aspectd == 0) {
531  // Pixel aspect unknown
532  aspectd = 1;
533  }
534 
535  st = avformat_new_stream(s, NULL);
536  if (!st)
537  return AVERROR(ENOMEM);
538  st->codec->width = width;
539  st->codec->height = height;
540  av_reduce(&raten, &rated, raten, rated, (1UL << 31) - 1);
541  avpriv_set_pts_info(st, 64, rated, raten);
542  st->codec->pix_fmt = pix_fmt;
545  st->sample_aspect_ratio = (AVRational){ aspectn, aspectd };
546  st->codec->chroma_sample_location = chroma_sample_location;
547 
548  return 0;
549 }
550 
552 {
553  int i;
554  char header[MAX_FRAME_HEADER+1];
555  int packet_size, width, height, ret;
556  AVStream *st = s->streams[0];
557  struct frame_attributes *s1 = s->priv_data;
558 
559  for (i = 0; i < MAX_FRAME_HEADER; i++) {
560  header[i] = avio_r8(s->pb);
561  if (header[i] == '\n') {
562  header[i + 1] = 0;
563  break;
564  }
565  }
566  if (s->pb->error)
567  return s->pb->error;
568  else if (s->pb->eof_reached)
569  return AVERROR_EOF;
570  else if (i == MAX_FRAME_HEADER)
571  return AVERROR_INVALIDDATA;
572 
573  if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC)))
574  return AVERROR_INVALIDDATA;
575 
576  width = st->codec->width;
577  height = st->codec->height;
578 
579  packet_size = avpicture_get_size(st->codec->pix_fmt, width, height);
580  if (packet_size < 0)
581  return packet_size;
582 
583  ret = av_get_packet(s->pb, pkt, packet_size);
584  if (ret < 0)
585  return ret;
586  else if (ret != packet_size)
587  return s->pb->eof_reached ? AVERROR_EOF : AVERROR(EIO);
588 
589  if (st->codec->coded_frame) {
592  }
593 
594  pkt->stream_index = 0;
595  return 0;
596 }
597 
598 static int yuv4_probe(AVProbeData *pd)
599 {
600  /* check file header */
601  if (strncmp(pd->buf, Y4M_MAGIC, sizeof(Y4M_MAGIC) - 1) == 0)
602  return AVPROBE_SCORE_MAX;
603  else
604  return 0;
605 }
606 
607 #if CONFIG_YUV4MPEGPIPE_DEMUXER
608 AVInputFormat ff_yuv4mpegpipe_demuxer = {
609  .name = "yuv4mpegpipe",
610  .long_name = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe"),
611  .priv_data_size = sizeof(struct frame_attributes),
613  .read_header = yuv4_read_header,
614  .read_packet = yuv4_read_packet,
615  .extensions = "y4m",
616 };
617 #endif