Imported Upstream version 6.1
[platform/upstream/ffmpeg.git] / 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/frame.h"
23 #include "libavutil/pixdesc.h"
24 #include "avformat.h"
25 #include "internal.h"
26 #include "mux.h"
27 #include "yuv4mpeg.h"
28
29 static int yuv4_write_header(AVFormatContext *s)
30 {
31     AVStream *st;
32     AVIOContext *pb = s->pb;
33     int width, height;
34     int raten, rated, aspectn, aspectd, ret;
35     char inter;
36     const char *colorspace = "";
37     const char *colorrange = "";
38     int field_order;
39
40     st     = s->streams[0];
41     width  = st->codecpar->width;
42     height = st->codecpar->height;
43     field_order = st->codecpar->field_order;
44
45     // TODO: should be avg_frame_rate
46     av_reduce(&raten, &rated, st->time_base.den,
47               st->time_base.num, (1UL << 31) - 1);
48
49     aspectn = st->sample_aspect_ratio.num;
50     aspectd = st->sample_aspect_ratio.den;
51
52     if (aspectn == 0 && aspectd == 1)
53         aspectd = 0;  // 0:0 means unknown
54
55     switch(st->codecpar->color_range) {
56     case AVCOL_RANGE_MPEG:
57         colorrange = " XCOLORRANGE=LIMITED";
58         break;
59     case AVCOL_RANGE_JPEG:
60         colorrange = " XCOLORRANGE=FULL";
61         break;
62     default:
63         break;
64     }
65
66     switch (field_order) {
67     case AV_FIELD_TB:
68     case AV_FIELD_TT: inter = 't'; break;
69     case AV_FIELD_BT:
70     case AV_FIELD_BB: inter = 'b'; break;
71     default:          inter = 'p'; break;
72     }
73
74     switch (st->codecpar->format) {
75     case AV_PIX_FMT_GRAY8:
76         colorspace = " Cmono";
77         break;
78     case AV_PIX_FMT_GRAY9:
79         colorspace = " Cmono9";
80         break;
81     case AV_PIX_FMT_GRAY10:
82         colorspace = " Cmono10";
83         break;
84     case AV_PIX_FMT_GRAY12:
85         colorspace = " Cmono12";
86         break;
87     case AV_PIX_FMT_GRAY16:
88         colorspace = " Cmono16";
89         break;
90     case AV_PIX_FMT_YUV411P:
91         colorspace = " C411 XYSCSS=411";
92         break;
93     case AV_PIX_FMT_YUVJ420P:
94         colorspace = " C420jpeg XYSCSS=420JPEG";
95         colorrange = " XCOLORRANGE=FULL";
96         break;
97     case AV_PIX_FMT_YUVJ422P:
98         colorspace = " C422 XYSCSS=422";
99         colorrange = " XCOLORRANGE=FULL";
100         break;
101     case AV_PIX_FMT_YUVJ444P:
102         colorspace = " C444 XYSCSS=444";
103         colorrange = " XCOLORRANGE=FULL";
104         break;
105     case AV_PIX_FMT_YUV420P:
106         switch (st->codecpar->chroma_location) {
107         case AVCHROMA_LOC_TOPLEFT: colorspace = " C420paldv XYSCSS=420PALDV"; break;
108         case AVCHROMA_LOC_LEFT:    colorspace = " C420mpeg2 XYSCSS=420MPEG2"; break;
109         default:                   colorspace = " C420jpeg XYSCSS=420JPEG";   break;
110         }
111         break;
112     case AV_PIX_FMT_YUV422P:
113         colorspace = " C422 XYSCSS=422";
114         break;
115     case AV_PIX_FMT_YUV444P:
116         colorspace = " C444 XYSCSS=444";
117         break;
118     case AV_PIX_FMT_YUVA444P:
119         colorspace = " C444alpha XYSCSS=444";
120         break;
121     case AV_PIX_FMT_YUV420P9:
122         colorspace = " C420p9 XYSCSS=420P9";
123         break;
124     case AV_PIX_FMT_YUV422P9:
125         colorspace = " C422p9 XYSCSS=422P9";
126         break;
127     case AV_PIX_FMT_YUV444P9:
128         colorspace = " C444p9 XYSCSS=444P9";
129         break;
130     case AV_PIX_FMT_YUV420P10:
131         colorspace = " C420p10 XYSCSS=420P10";
132         break;
133     case AV_PIX_FMT_YUV422P10:
134         colorspace = " C422p10 XYSCSS=422P10";
135         break;
136     case AV_PIX_FMT_YUV444P10:
137         colorspace = " C444p10 XYSCSS=444P10";
138         break;
139     case AV_PIX_FMT_YUV420P12:
140         colorspace = " C420p12 XYSCSS=420P12";
141         break;
142     case AV_PIX_FMT_YUV422P12:
143         colorspace = " C422p12 XYSCSS=422P12";
144         break;
145     case AV_PIX_FMT_YUV444P12:
146         colorspace = " C444p12 XYSCSS=444P12";
147         break;
148     case AV_PIX_FMT_YUV420P14:
149         colorspace = " C420p14 XYSCSS=420P14";
150         break;
151     case AV_PIX_FMT_YUV422P14:
152         colorspace = " C422p14 XYSCSS=422P14";
153         break;
154     case AV_PIX_FMT_YUV444P14:
155         colorspace = " C444p14 XYSCSS=444P14";
156         break;
157     case AV_PIX_FMT_YUV420P16:
158         colorspace = " C420p16 XYSCSS=420P16";
159         break;
160     case AV_PIX_FMT_YUV422P16:
161         colorspace = " C422p16 XYSCSS=422P16";
162         break;
163     case AV_PIX_FMT_YUV444P16:
164         colorspace = " C444p16 XYSCSS=444P16";
165         break;
166     }
167
168     ret = avio_printf(pb, Y4M_MAGIC " W%d H%d F%d:%d I%c A%d:%d%s%s\n",
169                       width, height, raten, rated, inter,
170                       aspectn, aspectd, colorspace, colorrange);
171     if (ret < 0) {
172         av_log(s, AV_LOG_ERROR,
173                "Error. YUV4MPEG stream header write failed.\n");
174         return ret;
175     }
176
177     return 0;
178 }
179
180
181 static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
182 {
183     AVStream *st = s->streams[pkt->stream_index];
184     AVIOContext *pb = s->pb;
185     const AVFrame *frame = (const AVFrame *)pkt->data;
186     int width, height;
187     const AVPixFmtDescriptor *desc;
188
189     /* construct frame header */
190
191     avio_printf(s->pb, Y4M_FRAME_MAGIC "\n");
192
193     if (st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO) {
194         avio_write(pb, pkt->data, pkt->size);
195         return 0;
196     }
197
198     width  = st->codecpar->width;
199     height = st->codecpar->height;
200     desc   = av_pix_fmt_desc_get(st->codecpar->format);
201
202     /* The following code presumes all planes to be non-interleaved. */
203     for (int k = 0; k < desc->nb_components; k++) {
204         int plane_height = height, plane_width = width;
205         const uint8_t *ptr = frame->data[k];
206
207         if (desc->nb_components >= 3 && (k == 1 || k == 2)) { /* chroma? */
208             plane_width  = AV_CEIL_RSHIFT(plane_width,  desc->log2_chroma_w);
209             plane_height = AV_CEIL_RSHIFT(plane_height, desc->log2_chroma_h);
210         }
211         plane_width *= desc->comp[k].step;
212
213         for (int i = 0; i < plane_height; i++) {
214             avio_write(pb, ptr, plane_width);
215             ptr += frame->linesize[k];
216         }
217     }
218
219     return 0;
220 }
221
222 static int yuv4_init(AVFormatContext *s)
223 {
224     if (s->nb_streams != 1)
225         return AVERROR(EIO);
226
227     if (s->streams[0]->codecpar->codec_id != AV_CODEC_ID_WRAPPED_AVFRAME &&
228         s->streams[0]->codecpar->codec_id != AV_CODEC_ID_RAWVIDEO) {
229         av_log(s, AV_LOG_ERROR, "ERROR: Codec not supported.\n");
230         return AVERROR_INVALIDDATA;
231     }
232
233     switch (s->streams[0]->codecpar->format) {
234     case AV_PIX_FMT_YUV411P:
235         av_log(s, AV_LOG_WARNING, "Warning: generating rarely used 4:1:1 YUV "
236                "stream, some mjpegtools might not work.\n");
237         break;
238     case AV_PIX_FMT_GRAY8:
239     case AV_PIX_FMT_YUV420P:
240     case AV_PIX_FMT_YUV422P:
241     case AV_PIX_FMT_YUV444P:
242     // TODO: remove YUVJ pixel formats when they are completely removed from the codebase.
243     case AV_PIX_FMT_YUVJ420P:
244     case AV_PIX_FMT_YUVJ422P:
245     case AV_PIX_FMT_YUVJ444P:
246         break;
247     case AV_PIX_FMT_GRAY9:
248     case AV_PIX_FMT_GRAY10:
249     case AV_PIX_FMT_GRAY12:
250     case AV_PIX_FMT_GRAY16:
251     case AV_PIX_FMT_YUV420P9:
252     case AV_PIX_FMT_YUV422P9:
253     case AV_PIX_FMT_YUV444P9:
254     case AV_PIX_FMT_YUV420P10:
255     case AV_PIX_FMT_YUV422P10:
256     case AV_PIX_FMT_YUV444P10:
257     case AV_PIX_FMT_YUV420P12:
258     case AV_PIX_FMT_YUV422P12:
259     case AV_PIX_FMT_YUV444P12:
260     case AV_PIX_FMT_YUV420P14:
261     case AV_PIX_FMT_YUV422P14:
262     case AV_PIX_FMT_YUV444P14:
263     case AV_PIX_FMT_YUV420P16:
264     case AV_PIX_FMT_YUV422P16:
265     case AV_PIX_FMT_YUV444P16:
266     case AV_PIX_FMT_YUVA444P:
267         if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
268             av_log(s, AV_LOG_ERROR, "'%s' is not an official yuv4mpegpipe pixel format. "
269                    "Use '-strict -1' to encode to this pixel format.\n",
270                    av_get_pix_fmt_name(s->streams[0]->codecpar->format));
271             return AVERROR(EINVAL);
272         }
273         av_log(s, AV_LOG_WARNING, "Warning: generating non standard YUV stream. "
274                "Mjpegtools will not work.\n");
275         break;
276     default:
277         av_log(s, AV_LOG_ERROR, "ERROR: yuv4mpeg can only handle "
278                "yuv444p, yuv422p, yuv420p, yuv411p and gray8 pixel formats. "
279                "And using 'strict -1' also yuv444p9, yuv422p9, yuv420p9, "
280                "yuv444p10, yuv422p10, yuv420p10, "
281                "yuv444p12, yuv422p12, yuv420p12, "
282                "yuv444p14, yuv422p14, yuv420p14, "
283                "yuv444p16, yuv422p16, yuv420p16, "
284                "yuva444p, "
285                "gray9, gray10, gray12 "
286                "and gray16 pixel formats. "
287                "Use -pix_fmt to select one.\n");
288         return AVERROR(EIO);
289     }
290
291     return 0;
292 }
293
294 const FFOutputFormat ff_yuv4mpegpipe_muxer = {
295     .p.name            = "yuv4mpegpipe",
296     .p.long_name       = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe"),
297     .p.extensions      = "y4m",
298     .p.audio_codec     = AV_CODEC_ID_NONE,
299     .p.video_codec     = AV_CODEC_ID_WRAPPED_AVFRAME,
300     .init              = yuv4_init,
301     .write_header      = yuv4_write_header,
302     .write_packet      = yuv4_write_packet,
303 };