Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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.  
  22. #include "libavutil/pixdesc.h"
  23. #include "avformat.h"
  24. #include "internal.h"
  25.  
  26. #define Y4M_MAGIC "YUV4MPEG2"
  27. #define Y4M_FRAME_MAGIC "FRAME"
  28. #define Y4M_LINE_MAX 256
  29.  
  30. #if CONFIG_YUV4MPEGPIPE_MUXER
  31. static int yuv4_generate_header(AVFormatContext *s, char* buf)
  32. {
  33.     AVStream *st;
  34.     int width, height;
  35.     int raten, rated, aspectn, aspectd, n;
  36.     char inter;
  37.     const char *colorspace = "";
  38.  
  39.     st     = s->streams[0];
  40.     width  = st->codec->width;
  41.     height = st->codec->height;
  42.  
  43.     av_reduce(&raten, &rated, st->codec->time_base.den,
  44.               st->codec->time_base.num, (1UL << 31) - 1);
  45.  
  46.     aspectn = st->sample_aspect_ratio.num;
  47.     aspectd = st->sample_aspect_ratio.den;
  48.  
  49.     if (aspectn == 0 && aspectd == 1)
  50.         aspectd = 0;  // 0:0 means unknown
  51.  
  52.     inter = 'p'; /* progressive is the default */
  53.     if (st->codec->coded_frame && st->codec->coded_frame->interlaced_frame)
  54.         inter = st->codec->coded_frame->top_field_first ? 't' : 'b';
  55.     if (st->codec->field_order == AV_FIELD_PROGRESSIVE) {
  56.         inter = 'p';
  57.     } else if (st->codec->field_order == AV_FIELD_TB || st->codec->field_order == AV_FIELD_TT) {
  58.         inter = 't';
  59.     } else if (st->codec->field_order == AV_FIELD_BT || st->codec->field_order == AV_FIELD_BB) {
  60.         inter = 'b';
  61.     }
  62.  
  63.     switch (st->codec->pix_fmt) {
  64.     case AV_PIX_FMT_GRAY8:
  65.         colorspace = " Cmono";
  66.         break;
  67.     case AV_PIX_FMT_GRAY16:
  68.         colorspace = " Cmono16";
  69.         break;
  70.     case AV_PIX_FMT_YUV411P:
  71.         colorspace = " C411 XYSCSS=411";
  72.         break;
  73.     case AV_PIX_FMT_YUV420P:
  74.         switch (st->codec->chroma_sample_location) {
  75.         case AVCHROMA_LOC_TOPLEFT: colorspace = " C420paldv XYSCSS=420PALDV"; break;
  76.         case AVCHROMA_LOC_LEFT:    colorspace = " C420mpeg2 XYSCSS=420MPEG2"; break;
  77.         default:                   colorspace = " C420jpeg XYSCSS=420JPEG";   break;
  78.         }
  79.         break;
  80.     case AV_PIX_FMT_YUV422P:
  81.         colorspace = " C422 XYSCSS=422";
  82.         break;
  83.     case AV_PIX_FMT_YUV444P:
  84.         colorspace = " C444 XYSCSS=444";
  85.         break;
  86.     case AV_PIX_FMT_YUV420P9:
  87.         colorspace = " C420p9 XYSCSS=420P9";
  88.         break;
  89.     case AV_PIX_FMT_YUV422P9:
  90.         colorspace = " C422p9 XYSCSS=422P9";
  91.         break;
  92.     case AV_PIX_FMT_YUV444P9:
  93.         colorspace = " C444p9 XYSCSS=444P9";
  94.         break;
  95.     case AV_PIX_FMT_YUV420P10:
  96.         colorspace = " C420p10 XYSCSS=420P10";
  97.         break;
  98.     case AV_PIX_FMT_YUV422P10:
  99.         colorspace = " C422p10 XYSCSS=422P10";
  100.         break;
  101.     case AV_PIX_FMT_YUV444P10:
  102.         colorspace = " C444p10 XYSCSS=444P10";
  103.         break;
  104.     case AV_PIX_FMT_YUV420P12:
  105.         colorspace = " C420p12 XYSCSS=420P12";
  106.         break;
  107.     case AV_PIX_FMT_YUV422P12:
  108.         colorspace = " C422p12 XYSCSS=422P12";
  109.         break;
  110.     case AV_PIX_FMT_YUV444P12:
  111.         colorspace = " C444p12 XYSCSS=444P12";
  112.         break;
  113.     case AV_PIX_FMT_YUV420P14:
  114.         colorspace = " C420p14 XYSCSS=420P14";
  115.         break;
  116.     case AV_PIX_FMT_YUV422P14:
  117.         colorspace = " C422p14 XYSCSS=422P14";
  118.         break;
  119.     case AV_PIX_FMT_YUV444P14:
  120.         colorspace = " C444p14 XYSCSS=444P14";
  121.         break;
  122.     case AV_PIX_FMT_YUV420P16:
  123.         colorspace = " C420p16 XYSCSS=420P16";
  124.         break;
  125.     case AV_PIX_FMT_YUV422P16:
  126.         colorspace = " C422p16 XYSCSS=422P16";
  127.         break;
  128.     case AV_PIX_FMT_YUV444P16:
  129.         colorspace = " C444p16 XYSCSS=444P16";
  130.         break;
  131.     }
  132.  
  133.     /* construct stream header, if this is the first frame */
  134.     n = snprintf(buf, Y4M_LINE_MAX, "%s W%d H%d F%d:%d I%c A%d:%d%s\n",
  135.                  Y4M_MAGIC, width, height, raten, rated, inter,
  136.                  aspectn, aspectd, colorspace);
  137.  
  138.     return n;
  139. }
  140.  
  141. static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
  142. {
  143.     AVStream *st = s->streams[pkt->stream_index];
  144.     AVIOContext *pb = s->pb;
  145.     AVPicture *picture, picture_tmp;
  146.     int* first_pkt = s->priv_data;
  147.     int width, height, h_chroma_shift, v_chroma_shift;
  148.     int i;
  149.     char buf2[Y4M_LINE_MAX + 1];
  150.     char buf1[20];
  151.     uint8_t *ptr, *ptr1, *ptr2;
  152.  
  153.     memcpy(&picture_tmp, pkt->data, sizeof(AVPicture));
  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) {
  160.             av_log(s, AV_LOG_ERROR,
  161.                    "Error. YUV4MPEG stream header write failed.\n");
  162.             return AVERROR(EIO);
  163.         } else {
  164.             avio_write(pb, buf2, strlen(buf2));
  165.         }
  166.     }
  167.  
  168.     /* construct frame header */
  169.  
  170.     snprintf(buf1, sizeof(buf1), "%s\n", Y4M_FRAME_MAGIC);
  171.     avio_write(pb, buf1, strlen(buf1));
  172.  
  173.     width  = st->codec->width;
  174.     height = st->codec->height;
  175.  
  176.     ptr = picture->data[0];
  177.  
  178.     switch (st->codec->pix_fmt) {
  179.     case AV_PIX_FMT_GRAY8:
  180.     case AV_PIX_FMT_YUV411P:
  181.     case AV_PIX_FMT_YUV420P:
  182.     case AV_PIX_FMT_YUV422P:
  183.     case AV_PIX_FMT_YUV444P:
  184.         break;
  185.     case AV_PIX_FMT_GRAY16:
  186.     case AV_PIX_FMT_YUV420P9:
  187.     case AV_PIX_FMT_YUV422P9:
  188.     case AV_PIX_FMT_YUV444P9:
  189.     case AV_PIX_FMT_YUV420P10:
  190.     case AV_PIX_FMT_YUV422P10:
  191.     case AV_PIX_FMT_YUV444P10:
  192.     case AV_PIX_FMT_YUV420P12:
  193.     case AV_PIX_FMT_YUV422P12:
  194.     case AV_PIX_FMT_YUV444P12:
  195.     case AV_PIX_FMT_YUV420P14:
  196.     case AV_PIX_FMT_YUV422P14:
  197.     case AV_PIX_FMT_YUV444P14:
  198.     case AV_PIX_FMT_YUV420P16:
  199.     case AV_PIX_FMT_YUV422P16:
  200.     case AV_PIX_FMT_YUV444P16:
  201.         width *= 2;
  202.         break;
  203.     default:
  204.         av_log(s, AV_LOG_ERROR, "The pixel format '%s' is not supported.\n",
  205.                av_get_pix_fmt_name(st->codec->pix_fmt));
  206.         return AVERROR(EINVAL);
  207.     }
  208.  
  209.     for (i = 0; i < height; i++) {
  210.         avio_write(pb, ptr, width);
  211.         ptr += picture->linesize[0];
  212.     }
  213.  
  214.     if (st->codec->pix_fmt != AV_PIX_FMT_GRAY8 &&
  215.         st->codec->pix_fmt != AV_PIX_FMT_GRAY16) {
  216.         // Adjust for smaller Cb and Cr planes
  217.         av_pix_fmt_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift,
  218.                                          &v_chroma_shift);
  219.         width  = FF_CEIL_RSHIFT(width,  h_chroma_shift);
  220.         height = FF_CEIL_RSHIFT(height, v_chroma_shift);
  221.  
  222.         ptr1 = picture->data[1];
  223.         ptr2 = picture->data[2];
  224.         for (i = 0; i < height; i++) {     /* Cb */
  225.             avio_write(pb, ptr1, width);
  226.             ptr1 += picture->linesize[1];
  227.         }
  228.         for (i = 0; i < height; i++) {     /* Cr */
  229.             avio_write(pb, ptr2, width);
  230.             ptr2 += picture->linesize[2];
  231.         }
  232.     }
  233.  
  234.     return 0;
  235. }
  236.  
  237. static int yuv4_write_header(AVFormatContext *s)
  238. {
  239.     int *first_pkt = s->priv_data;
  240.  
  241.     if (s->nb_streams != 1)
  242.         return AVERROR(EIO);
  243.  
  244.     if (s->streams[0]->codec->codec_id != AV_CODEC_ID_RAWVIDEO) {
  245.         av_log(s, AV_LOG_ERROR, "ERROR: Only rawvideo supported.\n");
  246.         return AVERROR_INVALIDDATA;
  247.     }
  248.  
  249.     switch (s->streams[0]->codec->pix_fmt) {
  250.     case AV_PIX_FMT_YUV411P:
  251.         av_log(s, AV_LOG_WARNING, "Warning: generating rarely used 4:1:1 YUV "
  252.                "stream, some mjpegtools might not work.\n");
  253.         break;
  254.     case AV_PIX_FMT_GRAY8:
  255.     case AV_PIX_FMT_GRAY16:
  256.     case AV_PIX_FMT_YUV420P:
  257.     case AV_PIX_FMT_YUV422P:
  258.     case AV_PIX_FMT_YUV444P:
  259.         break;
  260.     case AV_PIX_FMT_YUV420P9:
  261.     case AV_PIX_FMT_YUV422P9:
  262.     case AV_PIX_FMT_YUV444P9:
  263.     case AV_PIX_FMT_YUV420P10:
  264.     case AV_PIX_FMT_YUV422P10:
  265.     case AV_PIX_FMT_YUV444P10:
  266.     case AV_PIX_FMT_YUV420P12:
  267.     case AV_PIX_FMT_YUV422P12:
  268.     case AV_PIX_FMT_YUV444P12:
  269.     case AV_PIX_FMT_YUV420P14:
  270.     case AV_PIX_FMT_YUV422P14:
  271.     case AV_PIX_FMT_YUV444P14:
  272.     case AV_PIX_FMT_YUV420P16:
  273.     case AV_PIX_FMT_YUV422P16:
  274.     case AV_PIX_FMT_YUV444P16:
  275.         if (s->streams[0]->codec->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
  276.             av_log(s, AV_LOG_ERROR, "'%s' is not a official yuv4mpegpipe pixel format. "
  277.                    "Use '-strict -1' to encode to this pixel format.\n",
  278.                    av_get_pix_fmt_name(s->streams[0]->codec->pix_fmt));
  279.             return AVERROR(EINVAL);
  280.         }
  281.         av_log(s, AV_LOG_WARNING, "Warning: generating non standard YUV stream. "
  282.                "Mjpegtools will not work.\n");
  283.         break;
  284.     default:
  285.         av_log(s, AV_LOG_ERROR, "ERROR: yuv4mpeg can only handle "
  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");
  294.         return AVERROR(EIO);
  295.     }
  296.  
  297.     *first_pkt = 1;
  298.     return 0;
  299. }
  300.  
  301. AVOutputFormat ff_yuv4mpegpipe_muxer = {
  302.     .name              = "yuv4mpegpipe",
  303.     .long_name         = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe"),
  304.     .extensions        = "y4m",
  305.     .priv_data_size    = sizeof(int),
  306.     .audio_codec       = AV_CODEC_ID_NONE,
  307.     .video_codec       = AV_CODEC_ID_RAWVIDEO,
  308.     .write_header      = yuv4_write_header,
  309.     .write_packet      = yuv4_write_packet,
  310.     .flags             = AVFMT_RAWPICTURE,
  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.  
  318. static int yuv4_read_header(AVFormatContext *s)
  319. {
  320.     char header[MAX_YUV4_HEADER + 10];  // Include headroom for
  321.                                         // the longest option
  322.     char *tokstart, *tokend, *header_end, interlaced = '?';
  323.     int i;
  324.     AVIOContext *pb = s->pb;
  325.     int width = -1, height  = -1, raten   = 0,
  326.         rated =  0, aspectn =  0, aspectd = 0;
  327.     enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE, alt_pix_fmt = AV_PIX_FMT_NONE;
  328.     enum AVChromaLocation chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED;
  329.     AVStream *st;
  330.  
  331.     for (i = 0; i < MAX_YUV4_HEADER; i++) {
  332.         header[i] = avio_r8(pb);
  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;
  342.     if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC)))
  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) {
  361.                 pix_fmt = AV_PIX_FMT_YUV420P;
  362.                 chroma_sample_location = AVCHROMA_LOC_CENTER;
  363.             } else if (strncmp("420mpeg2", tokstart, 8) == 0) {
  364.                 pix_fmt = AV_PIX_FMT_YUV420P;
  365.                 chroma_sample_location = AVCHROMA_LOC_LEFT;
  366.             } else if (strncmp("420paldv", tokstart, 8) == 0) {
  367.                 pix_fmt = AV_PIX_FMT_YUV420P;
  368.                 chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
  369.             } else if (strncmp("420p16", tokstart, 6) == 0) {
  370.                 pix_fmt = AV_PIX_FMT_YUV420P16;
  371.             } else if (strncmp("422p16", tokstart, 6) == 0) {
  372.                 pix_fmt = AV_PIX_FMT_YUV422P16;
  373.             } else if (strncmp("444p16", tokstart, 6) == 0) {
  374.                 pix_fmt = AV_PIX_FMT_YUV444P16;
  375.             } else if (strncmp("420p14", tokstart, 6) == 0) {
  376.                 pix_fmt = AV_PIX_FMT_YUV420P14;
  377.             } else if (strncmp("422p14", tokstart, 6) == 0) {
  378.                 pix_fmt = AV_PIX_FMT_YUV422P14;
  379.             } else if (strncmp("444p14", tokstart, 6) == 0) {
  380.                 pix_fmt = AV_PIX_FMT_YUV444P14;
  381.             } else if (strncmp("420p12", tokstart, 6) == 0) {
  382.                 pix_fmt = AV_PIX_FMT_YUV420P12;
  383.             } else if (strncmp("422p12", tokstart, 6) == 0) {
  384.                 pix_fmt = AV_PIX_FMT_YUV422P12;
  385.             } else if (strncmp("444p12", tokstart, 6) == 0) {
  386.                 pix_fmt = AV_PIX_FMT_YUV444P12;
  387.             } else if (strncmp("420p10", tokstart, 6) == 0) {
  388.                 pix_fmt = AV_PIX_FMT_YUV420P10;
  389.             } else if (strncmp("422p10", tokstart, 6) == 0) {
  390.                 pix_fmt = AV_PIX_FMT_YUV422P10;
  391.             } else if (strncmp("444p10", tokstart, 6) == 0) {
  392.                 pix_fmt = AV_PIX_FMT_YUV444P10;
  393.             } else if (strncmp("420p9", tokstart, 5) == 0) {
  394.                 pix_fmt = AV_PIX_FMT_YUV420P9;
  395.             } else if (strncmp("422p9", tokstart, 5) == 0) {
  396.                 pix_fmt = AV_PIX_FMT_YUV422P9;
  397.             } else if (strncmp("444p9", tokstart, 5) == 0) {
  398.                 pix_fmt = AV_PIX_FMT_YUV444P9;
  399.             } else if (strncmp("420", tokstart, 3) == 0) {
  400.                 pix_fmt = AV_PIX_FMT_YUV420P;
  401.                 chroma_sample_location = AVCHROMA_LOC_CENTER;
  402.             } else if (strncmp("411", tokstart, 3) == 0) {
  403.                 pix_fmt = AV_PIX_FMT_YUV411P;
  404.             } else if (strncmp("422", tokstart, 3) == 0) {
  405.                 pix_fmt = AV_PIX_FMT_YUV422P;
  406.             } else if (strncmp("444alpha", tokstart, 8) == 0 ) {
  407.                 av_log(s, AV_LOG_ERROR, "Cannot handle 4:4:4:4 "
  408.                        "YUV4MPEG stream.\n");
  409.                 return -1;
  410.             } else if (strncmp("444", tokstart, 3) == 0) {
  411.                 pix_fmt = AV_PIX_FMT_YUV444P;
  412.             } else if (strncmp("mono16", tokstart, 6) == 0) {
  413.                 pix_fmt = AV_PIX_FMT_GRAY16;
  414.             } else if (strncmp("mono", tokstart, 4) == 0) {
  415.                 pix_fmt = AV_PIX_FMT_GRAY8;
  416.             } else {
  417.                 av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains an unknown "
  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)
  442.                     alt_pix_fmt = AV_PIX_FMT_YUV420P;
  443.                 else if (strncmp("420MPEG2", tokstart, 8) == 0)
  444.                     alt_pix_fmt = AV_PIX_FMT_YUV420P;
  445.                 else if (strncmp("420PALDV", tokstart, 8) == 0)
  446.                     alt_pix_fmt = AV_PIX_FMT_YUV420P;
  447.                 else if (strncmp("420P9", tokstart, 5) == 0)
  448.                     alt_pix_fmt = AV_PIX_FMT_YUV420P9;
  449.                 else if (strncmp("422P9", tokstart, 5) == 0)
  450.                     alt_pix_fmt = AV_PIX_FMT_YUV422P9;
  451.                 else if (strncmp("444P9", tokstart, 5) == 0)
  452.                     alt_pix_fmt = AV_PIX_FMT_YUV444P9;
  453.                 else if (strncmp("420P10", tokstart, 6) == 0)
  454.                     alt_pix_fmt = AV_PIX_FMT_YUV420P10;
  455.                 else if (strncmp("422P10", tokstart, 6) == 0)
  456.                     alt_pix_fmt = AV_PIX_FMT_YUV422P10;
  457.                 else if (strncmp("444P10", tokstart, 6) == 0)
  458.                     alt_pix_fmt = AV_PIX_FMT_YUV444P10;
  459.                 else if (strncmp("420P12", tokstart, 6) == 0)
  460.                     alt_pix_fmt = AV_PIX_FMT_YUV420P12;
  461.                 else if (strncmp("422P12", tokstart, 6) == 0)
  462.                     alt_pix_fmt = AV_PIX_FMT_YUV422P12;
  463.                 else if (strncmp("444P12", tokstart, 6) == 0)
  464.                     alt_pix_fmt = AV_PIX_FMT_YUV444P12;
  465.                 else if (strncmp("420P14", tokstart, 6) == 0)
  466.                     alt_pix_fmt = AV_PIX_FMT_YUV420P14;
  467.                 else if (strncmp("422P14", tokstart, 6) == 0)
  468.                     alt_pix_fmt = AV_PIX_FMT_YUV422P14;
  469.                 else if (strncmp("444P14", tokstart, 6) == 0)
  470.                     alt_pix_fmt = AV_PIX_FMT_YUV444P14;
  471.                 else if (strncmp("420P16", tokstart, 6) == 0)
  472.                     alt_pix_fmt = AV_PIX_FMT_YUV420P16;
  473.                 else if (strncmp("422P16", tokstart, 6) == 0)
  474.                     alt_pix_fmt = AV_PIX_FMT_YUV422P16;
  475.                 else if (strncmp("444P16", tokstart, 6) == 0)
  476.                     alt_pix_fmt = AV_PIX_FMT_YUV444P16;
  477.                 else if (strncmp("411", tokstart, 3) == 0)
  478.                     alt_pix_fmt = AV_PIX_FMT_YUV411P;
  479.                 else if (strncmp("422", tokstart, 3) == 0)
  480.                     alt_pix_fmt = AV_PIX_FMT_YUV422P;
  481.                 else if (strncmp("444", tokstart, 3) == 0)
  482.                     alt_pix_fmt = AV_PIX_FMT_YUV444P;
  483.             }
  484.             while (tokstart < header_end && *tokstart != 0x20)
  485.                 tokstart++;
  486.             break;
  487.         }
  488.     }
  489.  
  490.     if (width == -1 || height == -1) {
  491.         av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
  492.         return -1;
  493.     }
  494.  
  495.     if (pix_fmt == AV_PIX_FMT_NONE) {
  496.         if (alt_pix_fmt == AV_PIX_FMT_NONE)
  497.             pix_fmt = AV_PIX_FMT_YUV420P;
  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.  
  513.     st = avformat_new_stream(s, NULL);
  514.     if (!st)
  515.         return AVERROR(ENOMEM);
  516.     st->codec->width  = width;
  517.     st->codec->height = height;
  518.     av_reduce(&raten, &rated, raten, rated, (1UL << 31) - 1);
  519.     avpriv_set_pts_info(st, 64, rated, raten);
  520.     st->codec->pix_fmt                = pix_fmt;
  521.     st->codec->codec_type             = AVMEDIA_TYPE_VIDEO;
  522.     st->codec->codec_id               = AV_CODEC_ID_RAWVIDEO;
  523.     st->sample_aspect_ratio           = (AVRational){ aspectn, aspectd };
  524.     st->codec->chroma_sample_location = chroma_sample_location;
  525.  
  526.     switch (interlaced){
  527.     case 'p':
  528.         st->codec->field_order = AV_FIELD_PROGRESSIVE;
  529.         break;
  530.     case 't':
  531.         st->codec->field_order = AV_FIELD_TB;
  532.         break;
  533.     case 'b':
  534.         st->codec->field_order = AV_FIELD_BT;
  535.         break;
  536.     case 'm':
  537.         av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed "
  538.                "interlaced and non-interlaced frames.\n");
  539.     case '?':
  540.         st->codec->field_order = AV_FIELD_UNKNOWN;
  541.         break;
  542.     default:
  543.         av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
  544.         return AVERROR(EINVAL);
  545.     }
  546.  
  547.     return 0;
  548. }
  549.  
  550. static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt)
  551. {
  552.     int i;
  553.     char header[MAX_FRAME_HEADER+1];
  554.     int packet_size, width, height, ret;
  555.     AVStream *st = s->streams[0];
  556.  
  557.     for (i = 0; i < MAX_FRAME_HEADER; i++) {
  558.         header[i] = avio_r8(s->pb);
  559.         if (header[i] == '\n') {
  560.             header[i + 1] = 0;
  561.             break;
  562.         }
  563.     }
  564.     if (s->pb->error)
  565.         return s->pb->error;
  566.     else if (s->pb->eof_reached)
  567.         return AVERROR_EOF;
  568.     else if (i == MAX_FRAME_HEADER)
  569.         return AVERROR_INVALIDDATA;
  570.  
  571.     if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC)))
  572.         return AVERROR_INVALIDDATA;
  573.  
  574.     width  = st->codec->width;
  575.     height = st->codec->height;
  576.  
  577.     packet_size = avpicture_get_size(st->codec->pix_fmt, width, height);
  578.     if (packet_size < 0)
  579.         return packet_size;
  580.  
  581.     ret = av_get_packet(s->pb, pkt, packet_size);
  582.     if (ret < 0)
  583.         return ret;
  584.     else if (ret != packet_size)
  585.         return s->pb->eof_reached ? AVERROR_EOF : AVERROR(EIO);
  586.  
  587.     pkt->stream_index = 0;
  588.     return 0;
  589. }
  590.  
  591. static int yuv4_probe(AVProbeData *pd)
  592. {
  593.     /* check file header */
  594.     if (strncmp(pd->buf, Y4M_MAGIC, sizeof(Y4M_MAGIC) - 1) == 0)
  595.         return AVPROBE_SCORE_MAX;
  596.     else
  597.         return 0;
  598. }
  599.  
  600. #if CONFIG_YUV4MPEGPIPE_DEMUXER
  601. AVInputFormat ff_yuv4mpegpipe_demuxer = {
  602.     .name           = "yuv4mpegpipe",
  603.     .long_name      = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe"),
  604.     .read_probe     = yuv4_probe,
  605.     .read_header    = yuv4_read_header,
  606.     .read_packet    = yuv4_read_packet,
  607.     .extensions     = "y4m",
  608. };
  609. #endif
  610.