]> git.sesse.net Git - ffmpeg/blob - libavformat/yuv4mpegenc.c
Merge commit '9485cce6d55baf547e92ef1f54cad117f2a38287'
[ffmpeg] / libavformat / yuv4mpegenc.c
1 /*
2  * YUV4MPEG muxer
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 #include "yuv4mpeg.h"
26
27 #define Y4M_LINE_MAX 256
28
29 static int yuv4_generate_header(AVFormatContext *s, char* buf)
30 {
31     AVStream *st;
32     int width, height;
33     int raten, rated, aspectn, aspectd, n;
34     char inter;
35     const char *colorspace = "";
36     const char *colorrange = "";
37     int field_order;
38
39     st     = s->streams[0];
40     width  = st->codecpar->width;
41     height = st->codecpar->height;
42     field_order = st->codecpar->field_order;
43
44     // TODO: should be avg_frame_rate
45     av_reduce(&raten, &rated, st->time_base.den,
46               st->time_base.num, (1UL << 31) - 1);
47
48     aspectn = st->sample_aspect_ratio.num;
49     aspectd = st->sample_aspect_ratio.den;
50
51     if (aspectn == 0 && aspectd == 1)
52         aspectd = 0;  // 0:0 means unknown
53
54 #if FF_API_LAVF_AVCTX
55     FF_DISABLE_DEPRECATION_WARNINGS
56     if (field_order != st->codec->field_order && st->codec->field_order != AV_FIELD_UNKNOWN)
57         field_order = st->codec->field_order;
58     FF_ENABLE_DEPRECATION_WARNINGS
59 #endif
60
61     switch(st->codecpar->color_range) {
62     case AVCOL_RANGE_MPEG:
63         colorrange = " XCOLORRANGE=LIMITED";
64         break;
65     case AVCOL_RANGE_JPEG:
66         colorrange = " XCOLORRANGE=FULL";
67         break;
68     default:
69         break;
70     }
71
72     switch (field_order) {
73     case AV_FIELD_TB:
74     case AV_FIELD_TT: inter = 't'; break;
75     case AV_FIELD_BT:
76     case AV_FIELD_BB: inter = 'b'; break;
77     default:          inter = 'p'; break;
78     }
79
80     switch (st->codecpar->format) {
81     case AV_PIX_FMT_GRAY8:
82         colorspace = " Cmono";
83         break;
84     case AV_PIX_FMT_GRAY9:
85         colorspace = " Cmono9";
86         break;
87     case AV_PIX_FMT_GRAY10:
88         colorspace = " Cmono10";
89         break;
90     case AV_PIX_FMT_GRAY12:
91         colorspace = " Cmono12";
92         break;
93     case AV_PIX_FMT_GRAY16:
94         colorspace = " Cmono16";
95         break;
96     case AV_PIX_FMT_YUV411P:
97         colorspace = " C411 XYSCSS=411";
98         break;
99     case AV_PIX_FMT_YUVJ420P:
100         colorspace = " C420jpeg XYSCSS=420JPEG";
101         colorrange = " XCOLORRANGE=FULL";
102         break;
103     case AV_PIX_FMT_YUVJ422P:
104         colorspace = " C422 XYSCSS=422";
105         colorrange = " XCOLORRANGE=FULL";
106         break;
107     case AV_PIX_FMT_YUVJ444P:
108         colorspace = " C444 XYSCSS=444";
109         colorrange = " XCOLORRANGE=FULL";
110         break;
111     case AV_PIX_FMT_YUV420P:
112         switch (st->codecpar->chroma_location) {
113         case AVCHROMA_LOC_TOPLEFT: colorspace = " C420paldv XYSCSS=420PALDV"; break;
114         case AVCHROMA_LOC_LEFT:    colorspace = " C420mpeg2 XYSCSS=420MPEG2"; break;
115         default:                   colorspace = " C420jpeg XYSCSS=420JPEG";   break;
116         }
117         break;
118     case AV_PIX_FMT_YUV422P:
119         colorspace = " C422 XYSCSS=422";
120         break;
121     case AV_PIX_FMT_YUV444P:
122         colorspace = " C444 XYSCSS=444";
123         break;
124     case AV_PIX_FMT_YUV420P9:
125         colorspace = " C420p9 XYSCSS=420P9";
126         break;
127     case AV_PIX_FMT_YUV422P9:
128         colorspace = " C422p9 XYSCSS=422P9";
129         break;
130     case AV_PIX_FMT_YUV444P9:
131         colorspace = " C444p9 XYSCSS=444P9";
132         break;
133     case AV_PIX_FMT_YUV420P10:
134         colorspace = " C420p10 XYSCSS=420P10";
135         break;
136     case AV_PIX_FMT_YUV422P10:
137         colorspace = " C422p10 XYSCSS=422P10";
138         break;
139     case AV_PIX_FMT_YUV444P10:
140         colorspace = " C444p10 XYSCSS=444P10";
141         break;
142     case AV_PIX_FMT_YUV420P12:
143         colorspace = " C420p12 XYSCSS=420P12";
144         break;
145     case AV_PIX_FMT_YUV422P12:
146         colorspace = " C422p12 XYSCSS=422P12";
147         break;
148     case AV_PIX_FMT_YUV444P12:
149         colorspace = " C444p12 XYSCSS=444P12";
150         break;
151     case AV_PIX_FMT_YUV420P14:
152         colorspace = " C420p14 XYSCSS=420P14";
153         break;
154     case AV_PIX_FMT_YUV422P14:
155         colorspace = " C422p14 XYSCSS=422P14";
156         break;
157     case AV_PIX_FMT_YUV444P14:
158         colorspace = " C444p14 XYSCSS=444P14";
159         break;
160     case AV_PIX_FMT_YUV420P16:
161         colorspace = " C420p16 XYSCSS=420P16";
162         break;
163     case AV_PIX_FMT_YUV422P16:
164         colorspace = " C422p16 XYSCSS=422P16";
165         break;
166     case AV_PIX_FMT_YUV444P16:
167         colorspace = " C444p16 XYSCSS=444P16";
168         break;
169     }
170
171     /* construct stream header, if this is the first frame */
172     n = snprintf(buf, Y4M_LINE_MAX, "%s W%d H%d F%d:%d I%c A%d:%d%s%s\n",
173                  Y4M_MAGIC, width, height, raten, rated, inter,
174                  aspectn, aspectd, colorspace, colorrange);
175
176     return n;
177 }
178
179
180 static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
181 {
182     AVStream *st = s->streams[pkt->stream_index];
183     AVIOContext *pb = s->pb;
184     AVFrame *frame;
185     int* first_pkt = s->priv_data;
186     int width, height, h_chroma_shift, v_chroma_shift;
187     int i;
188     char buf2[Y4M_LINE_MAX + 1];
189     uint8_t *ptr, *ptr1, *ptr2;
190
191     frame = (AVFrame *)pkt->data;
192
193     /* for the first packet we have to output the header as well */
194     if (*first_pkt) {
195         *first_pkt = 0;
196         if (yuv4_generate_header(s, buf2) < 0) {
197             av_log(s, AV_LOG_ERROR,
198                    "Error. YUV4MPEG stream header write failed.\n");
199             return AVERROR(EIO);
200         } else {
201             avio_write(pb, buf2, strlen(buf2));
202         }
203     }
204
205     /* construct frame header */
206
207     avio_printf(s->pb, "%s\n", Y4M_FRAME_MAGIC);
208
209     width  = st->codecpar->width;
210     height = st->codecpar->height;
211
212     ptr = frame->data[0];
213
214     switch (st->codecpar->format) {
215     case AV_PIX_FMT_GRAY8:
216     case AV_PIX_FMT_YUV411P:
217     case AV_PIX_FMT_YUV420P:
218     case AV_PIX_FMT_YUV422P:
219     case AV_PIX_FMT_YUV444P:
220     // TODO: remove YUVJ pixel formats when they are completely removed from the codebase.
221     case AV_PIX_FMT_YUVJ420P:
222     case AV_PIX_FMT_YUVJ422P:
223     case AV_PIX_FMT_YUVJ444P:
224         break;
225     case AV_PIX_FMT_GRAY9:
226     case AV_PIX_FMT_GRAY10:
227     case AV_PIX_FMT_GRAY12:
228     case AV_PIX_FMT_GRAY16:
229     case AV_PIX_FMT_YUV420P9:
230     case AV_PIX_FMT_YUV422P9:
231     case AV_PIX_FMT_YUV444P9:
232     case AV_PIX_FMT_YUV420P10:
233     case AV_PIX_FMT_YUV422P10:
234     case AV_PIX_FMT_YUV444P10:
235     case AV_PIX_FMT_YUV420P12:
236     case AV_PIX_FMT_YUV422P12:
237     case AV_PIX_FMT_YUV444P12:
238     case AV_PIX_FMT_YUV420P14:
239     case AV_PIX_FMT_YUV422P14:
240     case AV_PIX_FMT_YUV444P14:
241     case AV_PIX_FMT_YUV420P16:
242     case AV_PIX_FMT_YUV422P16:
243     case AV_PIX_FMT_YUV444P16:
244         width *= 2;
245         break;
246     default:
247         av_log(s, AV_LOG_ERROR, "The pixel format '%s' is not supported.\n",
248                av_get_pix_fmt_name(st->codecpar->format));
249         return AVERROR(EINVAL);
250     }
251
252     for (i = 0; i < height; i++) {
253         avio_write(pb, ptr, width);
254         ptr += frame->linesize[0];
255     }
256
257     if (st->codecpar->format != AV_PIX_FMT_GRAY8 && st->codecpar->format != AV_PIX_FMT_GRAY9 &&
258         st->codecpar->format != AV_PIX_FMT_GRAY10 && st->codecpar->format != AV_PIX_FMT_GRAY12 &&
259         st->codecpar->format != AV_PIX_FMT_GRAY16) {
260         // Adjust for smaller Cb and Cr planes
261         av_pix_fmt_get_chroma_sub_sample(st->codecpar->format, &h_chroma_shift,
262                                          &v_chroma_shift);
263         // Shift right, rounding up
264         width  = AV_CEIL_RSHIFT(width,  h_chroma_shift);
265         height = AV_CEIL_RSHIFT(height, v_chroma_shift);
266
267         ptr1 = frame->data[1];
268         ptr2 = frame->data[2];
269         for (i = 0; i < height; i++) {     /* Cb */
270             avio_write(pb, ptr1, width);
271             ptr1 += frame->linesize[1];
272         }
273         for (i = 0; i < height; i++) {     /* Cr */
274             avio_write(pb, ptr2, width);
275             ptr2 += frame->linesize[2];
276         }
277     }
278
279     return 0;
280 }
281
282 static int yuv4_write_header(AVFormatContext *s)
283 {
284     int *first_pkt = s->priv_data;
285
286     if (s->nb_streams != 1)
287         return AVERROR(EIO);
288
289     if (s->streams[0]->codecpar->codec_id != AV_CODEC_ID_WRAPPED_AVFRAME) {
290         av_log(s, AV_LOG_ERROR, "ERROR: Codec not supported.\n");
291         return AVERROR_INVALIDDATA;
292     }
293
294     switch (s->streams[0]->codecpar->format) {
295     case AV_PIX_FMT_YUV411P:
296         av_log(s, AV_LOG_WARNING, "Warning: generating rarely used 4:1:1 YUV "
297                "stream, some mjpegtools might not work.\n");
298         break;
299     case AV_PIX_FMT_GRAY8:
300     case AV_PIX_FMT_YUV420P:
301     case AV_PIX_FMT_YUV422P:
302     case AV_PIX_FMT_YUV444P:
303     // TODO: remove YUVJ pixel formats when they are completely removed from the codebase.
304     case AV_PIX_FMT_YUVJ420P:
305     case AV_PIX_FMT_YUVJ422P:
306     case AV_PIX_FMT_YUVJ444P:
307         break;
308     case AV_PIX_FMT_GRAY9:
309     case AV_PIX_FMT_GRAY10:
310     case AV_PIX_FMT_GRAY12:
311     case AV_PIX_FMT_GRAY16:
312     case AV_PIX_FMT_YUV420P9:
313     case AV_PIX_FMT_YUV422P9:
314     case AV_PIX_FMT_YUV444P9:
315     case AV_PIX_FMT_YUV420P10:
316     case AV_PIX_FMT_YUV422P10:
317     case AV_PIX_FMT_YUV444P10:
318     case AV_PIX_FMT_YUV420P12:
319     case AV_PIX_FMT_YUV422P12:
320     case AV_PIX_FMT_YUV444P12:
321     case AV_PIX_FMT_YUV420P14:
322     case AV_PIX_FMT_YUV422P14:
323     case AV_PIX_FMT_YUV444P14:
324     case AV_PIX_FMT_YUV420P16:
325     case AV_PIX_FMT_YUV422P16:
326     case AV_PIX_FMT_YUV444P16:
327         if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
328             av_log(s, AV_LOG_ERROR, "'%s' is not an official yuv4mpegpipe pixel format. "
329                    "Use '-strict -1' to encode to this pixel format.\n",
330                    av_get_pix_fmt_name(s->streams[0]->codecpar->format));
331             return AVERROR(EINVAL);
332         }
333         av_log(s, AV_LOG_WARNING, "Warning: generating non standard YUV stream. "
334                "Mjpegtools will not work.\n");
335         break;
336     default:
337         av_log(s, AV_LOG_ERROR, "ERROR: yuv4mpeg can only handle "
338                "yuv444p, yuv422p, yuv420p, yuv411p and gray8 pixel formats. "
339                "And using 'strict -1' also yuv444p9, yuv422p9, yuv420p9, "
340                "yuv444p10, yuv422p10, yuv420p10, "
341                "yuv444p12, yuv422p12, yuv420p12, "
342                "yuv444p14, yuv422p14, yuv420p14, "
343                "yuv444p16, yuv422p16, yuv420p16, "
344                "gray9, gray10, gray12 "
345                "and gray16 pixel formats. "
346                "Use -pix_fmt to select one.\n");
347         return AVERROR(EIO);
348     }
349
350     *first_pkt = 1;
351     return 0;
352 }
353
354 AVOutputFormat ff_yuv4mpegpipe_muxer = {
355     .name              = "yuv4mpegpipe",
356     .long_name         = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe"),
357     .extensions        = "y4m",
358     .priv_data_size    = sizeof(int),
359     .audio_codec       = AV_CODEC_ID_NONE,
360     .video_codec       = AV_CODEC_ID_WRAPPED_AVFRAME,
361     .write_header      = yuv4_write_header,
362     .write_packet      = yuv4_write_packet,
363 };