FFmpeg
Loading...
Searching...
No Matches
yuv4mpegdec.c
Go to the documentation of this file.
1/*
2 * YUV4MPEG demuxer
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/avstring.h"
23#include "libavutil/imgutils.h"
24
25#include "avformat.h"
26#include "demux.h"
27#include "internal.h"
28#include "yuv4mpeg.h"
29
30/* Header size increased to allow room for optional flags */
31#define MAX_YUV4_HEADER 128
32#define MAX_FRAME_HEADER 80
33
35{
36 char header[MAX_YUV4_HEADER + 10]; // Include headroom for
37 // the longest option
38 char *tokstart, *tokend, *header_end;
39 AVIOContext *pb = s->pb;
40 int width = -1, height = -1, raten = 0,
41 rated = 0, aspectn = 0, aspectd = 0;
43 enum AVChromaLocation chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED;
44 enum AVFieldOrder field_order = AV_FIELD_UNKNOWN;
46 AVStream *st;
47 int64_t data_offset;
48
49 for (int i = 0;;) {
50 header[i] = avio_r8(pb);
51 if (header[i] == '\n') {
52 header[i + 1] = 0x20; // Add a space after last option.
53 // Makes parsing "444" vs "444alpha" easier.
54 header[i + 2] = 0;
55 header_end = &header[i + 1]; // Include space
56 break;
57 }
58 if (++i == MAX_YUV4_HEADER) {
59 av_log(s, AV_LOG_ERROR, "Header too large.\n");
60 return AVERROR(EINVAL);
61 }
62 }
63 if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC))) {
64 av_log(s, AV_LOG_ERROR, "Invalid magic number for yuv4mpeg.\n");
65 return AVERROR(EINVAL);
66 }
67
68 for (tokstart = &header[strlen(Y4M_MAGIC) + 1];
69 tokstart < header_end; tokstart++) {
70 if (*tokstart == 0x20)
71 continue;
72 switch (*tokstart++) {
73 case 'W': // Width. Required.
74 width = strtol(tokstart, &tokend, 10);
75 tokstart = tokend;
76 break;
77 case 'H': // Height. Required.
78 height = strtol(tokstart, &tokend, 10);
79 tokstart = tokend;
80 break;
81 case 'C': // Color space
82 {
83 static const struct {
84#define MAX_PIX_FMT_LENGTH 8
85 char name[MAX_PIX_FMT_LENGTH + 1];
86#undef MAX_PIX_FMT_LENGTH
88 enum AVChromaLocation chroma_loc;
89 } pix_fmt_array[] = {
118 };
119 size_t i;
120 for (i = 0; i < FF_ARRAY_ELEMS(pix_fmt_array); i++) {
121 if (av_strstart(tokstart, pix_fmt_array[i].name, NULL)) {
122 pix_fmt = pix_fmt_array[i].pix_fmt;
123 if (pix_fmt_array[i].chroma_loc != AVCHROMA_LOC_UNSPECIFIED)
124 chroma_sample_location = pix_fmt_array[i].chroma_loc;
125 break;
126 }
127 }
128 if (i == FF_ARRAY_ELEMS(pix_fmt_array)) {
129 av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains an unknown "
130 "pixel format.\n");
131 return AVERROR_INVALIDDATA;
132 }
133 while (tokstart < header_end && *tokstart != 0x20)
134 tokstart++;
135 break;
136 }
137 case 'I': // Interlace type
138 switch (*tokstart++){
139 case '?':
140 field_order = AV_FIELD_UNKNOWN;
141 break;
142 case 'p':
143 field_order = AV_FIELD_PROGRESSIVE;
144 break;
145 case 't':
146 field_order = AV_FIELD_TT;
147 break;
148 case 'b':
149 field_order = AV_FIELD_BB;
150 break;
151 case 'm':
152 av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed "
153 "interlaced and non-interlaced frames.\n");
154 return AVERROR(ENOTSUP);
155 default:
156 av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
157 return AVERROR(EINVAL);
158 }
159 break;
160 case 'F': // Frame rate
161 sscanf(tokstart, "%d:%d", &raten, &rated); // 0:0 if unknown
162 while (tokstart < header_end && *tokstart != 0x20)
163 tokstart++;
164 break;
165 case 'A': // Pixel aspect
166 sscanf(tokstart, "%d:%d", &aspectn, &aspectd); // 0:0 if unknown
167 while (tokstart < header_end && *tokstart != 0x20)
168 tokstart++;
169 break;
170 case 'X': // Vendor extensions
171 if (strncmp("YSCSS=", tokstart, 6) == 0) {
172 static const struct {
173#define MAX_PIX_FMT_LENGTH 8
174 char name[MAX_PIX_FMT_LENGTH + 1];
175#undef MAX_PIX_FMT_LENGTH
177 } pix_fmt_array[] = {
178 { "420JPEG", AV_PIX_FMT_YUV420P },
179 { "420MPEG2", AV_PIX_FMT_YUV420P },
180 { "420PALDV", AV_PIX_FMT_YUV420P },
181 { "420P9", AV_PIX_FMT_YUV420P9 },
182 { "422P9", AV_PIX_FMT_YUV422P9 },
183 { "444P9", AV_PIX_FMT_YUV444P9 },
184 { "420P10", AV_PIX_FMT_YUV420P10 },
185 { "444P10", AV_PIX_FMT_YUV444P10 },
186 { "420P12", AV_PIX_FMT_YUV420P12 },
187 { "422P12", AV_PIX_FMT_YUV422P12 },
188 { "444P12", AV_PIX_FMT_YUV444P12 },
189 { "420P14", AV_PIX_FMT_YUV420P14 },
190 { "422P14", AV_PIX_FMT_YUV422P14 },
191 { "444P14", AV_PIX_FMT_YUV444P14 },
192 { "420P16", AV_PIX_FMT_YUV420P16 },
193 { "422P16", AV_PIX_FMT_YUV422P16 },
194 { "444P16", AV_PIX_FMT_YUV444P16 },
195 { "411", AV_PIX_FMT_YUV411P },
196 { "422", AV_PIX_FMT_YUV422P },
197 { "444", AV_PIX_FMT_YUV444P },
198 };
199 // Older nonstandard pixel format representation
200 tokstart += 6;
201 for (size_t i = 0; i < FF_ARRAY_ELEMS(pix_fmt_array); i++)
202 if (av_strstart(tokstart, pix_fmt_array[i].name, NULL)) {
203 alt_pix_fmt = pix_fmt_array[i].pix_fmt;
204 break;
205 }
206 } else if (strncmp("COLORRANGE=", tokstart, 11) == 0) {
207 tokstart += 11;
208 if (strncmp("FULL",tokstart, 4) == 0)
210 else if (strncmp("LIMITED", tokstart, 7) == 0)
212 }
213 while (tokstart < header_end && *tokstart != 0x20)
214 tokstart++;
215 break;
216 }
217 }
218
219 if (width == -1 || height == -1) {
220 av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
221 return AVERROR_INVALIDDATA;
222 }
223
224 if (pix_fmt == AV_PIX_FMT_NONE) {
225 if (alt_pix_fmt == AV_PIX_FMT_NONE)
227 else
228 pix_fmt = alt_pix_fmt;
229 }
230
231 if (raten <= 0 || rated <= 0) {
232 // Frame rate unknown
233 raten = 25;
234 rated = 1;
235 }
236
237 if (aspectn == 0 && aspectd == 0) {
238 // Pixel aspect unknown
239 aspectd = 1;
240 }
241
243 if (!st)
244 return AVERROR(ENOMEM);
245 st->codecpar->width = width;
246 st->codecpar->height = height;
247 av_reduce(&raten, &rated, raten, rated, (1UL << 31) - 1);
248 avpriv_set_pts_info(st, 64, rated, raten);
250 st->codecpar->format = pix_fmt;
253 st->sample_aspect_ratio = (AVRational){ aspectn, aspectd };
254 st->codecpar->chroma_location = chroma_sample_location;
256 st->codecpar->field_order = field_order;
258 if ((int) s->packet_size < 0)
259 return s->packet_size;
260 ffformatcontext(s)->data_offset = data_offset = avio_tell(pb);
261
262 st->duration = (avio_size(pb) - data_offset) / s->packet_size;
263
264 return 0;
265}
266
268{
269 int i;
270 char header[MAX_FRAME_HEADER+1];
271 int ret;
272 int64_t off = avio_tell(s->pb);
273
274 for (i = 0; i < MAX_FRAME_HEADER; i++) {
275 header[i] = avio_r8(s->pb);
276 if (header[i] == '\n') {
277 header[i + 1] = 0;
278 break;
279 }
280 }
281 if (s->pb->error)
282 return s->pb->error;
283 else if (s->pb->eof_reached)
284 return AVERROR_EOF;
285 else if (i == MAX_FRAME_HEADER)
286 return AVERROR_INVALIDDATA;
287
288 if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC)))
289 return AVERROR_INVALIDDATA;
290
291 ret = av_get_packet(s->pb, pkt, s->packet_size - Y4M_FRAME_MAGIC_LEN);
292 if (ret < 0)
293 return ret;
294 else if (ret != s->packet_size - Y4M_FRAME_MAGIC_LEN) {
295 return s->pb->eof_reached ? AVERROR_EOF : AVERROR_INVALIDDATA;
296 }
297 pkt->stream_index = 0;
298 pkt->pts = (off - ffformatcontext(s)->data_offset) / s->packet_size;
299 pkt->duration = 1;
300 return 0;
301}
302
303static int yuv4_read_seek(AVFormatContext *s, int stream_index,
304 int64_t pts, int flags)
305{
306 int64_t pos;
307
309 pts = FFMAX(0, pts - 1);
310 if (pts < 0)
311 return -1;
312 pos = pts * s->packet_size;
313
314 if (avio_seek(s->pb, pos + ffformatcontext(s)->data_offset, SEEK_SET) < 0)
315 return -1;
316 return 0;
317}
318
319static int yuv4_probe(const AVProbeData *pd)
320{
321 /* check file header */
322 if (strncmp(pd->buf, Y4M_MAGIC, sizeof(Y4M_MAGIC) - 1) == 0)
323 return AVPROBE_SCORE_MAX;
324 else
325 return 0;
326}
327
329 .p.name = "yuv4mpegpipe",
330 .p.long_name = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe"),
331 .p.extensions = "y4m",
332 .read_probe = yuv4_probe,
333 .read_header = yuv4_read_header,
334 .read_packet = yuv4_read_packet,
335 .read_seek = yuv4_read_seek,
336};
const FFInputFormat ff_yuv4mpegpipe_demuxer
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:834
Main libavformat public API header.
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:483
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition utils.c:98
#define AVSEEK_FLAG_BACKWARD
seek backward
Definition avformat.h:2616
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition aviobuf.c:236
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition aviobuf.c:326
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:494
int avio_r8(AVIOContext *s)
Definition aviobuf.c:606
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
AVFieldOrder
Definition defs.h:211
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition defs.h:214
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition defs.h:215
@ AV_FIELD_UNKNOWN
Definition defs.h:212
@ AV_FIELD_PROGRESSIVE
Definition defs.h:213
static AVPacket * pkt
static enum AVPixelFormat pix_fmt
@ AV_CODEC_ID_RAWVIDEO
Definition codec_id.h:63
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition rational.h:159
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
Return the size in bytes of the amount of data required to store an image with the given parameters.
Definition imgutils.c:466
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
misc image utilities
static av_always_inline FFFormatContext * ffformatcontext(AVFormatContext *s)
Definition internal.h:130
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
#define FFMAX(a, b)
Definition macros.h:47
#define AV_PIX_FMT_YUV420P16
Definition pixfmt.h:556
#define AV_PIX_FMT_YUV444P12
Definition pixfmt.h:552
#define AV_PIX_FMT_YUV444P9
Definition pixfmt.h:544
AVChromaLocation
Location of chroma samples.
Definition pixfmt.h:802
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition pixfmt.h:806
@ AVCHROMA_LOC_LEFT
MPEG-2/4 4:2:0, H.264 default for 4:2:0.
Definition pixfmt.h:804
@ AVCHROMA_LOC_CENTER
MPEG-1 4:2:0, JPEG 4:2:0, H.263 4:2:0.
Definition pixfmt.h:805
@ AVCHROMA_LOC_UNSPECIFIED
Definition pixfmt.h:803
#define AV_PIX_FMT_YUV420P10
Definition pixfmt.h:545
#define AV_PIX_FMT_GRAY9
Definition pixfmt.h:524
#define AV_PIX_FMT_YUV422P9
Definition pixfmt.h:543
AVColorRange
Visual content value range.
Definition pixfmt.h:748
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_UNSPECIFIED
Definition pixfmt.h:749
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
#define AV_PIX_FMT_YUV420P12
Definition pixfmt.h:549
#define AV_PIX_FMT_YUV422P12
Definition pixfmt.h:550
#define AV_PIX_FMT_YUV422P10
Definition pixfmt.h:546
#define AV_PIX_FMT_GRAY12
Definition pixfmt.h:526
#define AV_PIX_FMT_YUV420P9
Definition pixfmt.h:542
#define AV_PIX_FMT_YUV420P14
Definition pixfmt.h:553
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition pixfmt.h:81
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition pixfmt.h:80
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition pixfmt.h:174
#define AV_PIX_FMT_YUV422P14
Definition pixfmt.h:554
#define AV_PIX_FMT_GRAY10
Definition pixfmt.h:525
#define AV_PIX_FMT_YUV422P16
Definition pixfmt.h:557
#define AV_PIX_FMT_GRAY16
Definition pixfmt.h:528
#define AV_PIX_FMT_YUV444P14
Definition pixfmt.h:555
#define AV_PIX_FMT_YUV444P16
Definition pixfmt.h:558
#define AV_PIX_FMT_YUV444P10
Definition pixfmt.h:548
const char * name
Definition qsvenc.c:142
static const uint8_t header[24]
Definition sdr2.c:68
#define FF_ARRAY_ELEMS(a)
unsigned int pos
Definition spdifenc.c:431
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition codec_par.h:182
int height
The height of the video frame in pixels.
Definition codec_par.h:150
int width
The width of the video frame in pixels.
Definition codec_par.h:143
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
enum AVChromaLocation chroma_location
Definition codec_par.h:193
enum AVColorRange color_range
Additional colorspace characteristics.
Definition codec_par.h:189
Format I/O context.
Definition avformat.h:1333
Bytestream IO Context.
Definition avio.h:160
This structure stores compressed data.
Definition packet.h:580
This structure contains the data a format has to probe a file.
Definition avformat.h:471
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition avformat.h:473
Rational number (pair of numerator and denominator).
Definition rational.h:58
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition avformat.h:844
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition avformat.h:825
AVRational avg_frame_rate
Average framerate.
Definition avformat.h:855
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avformat.h:805
int64_t data_offset
offset of the first packet
Definition internal.h:89
#define av_log(a,...)
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
static int64_t pts
color_range
#define Y4M_FRAME_MAGIC
Definition yuv4mpeg.h:25
#define Y4M_FRAME_MAGIC_LEN
Definition yuv4mpeg.h:26
#define Y4M_MAGIC
Definition yuv4mpeg.h:24
static int yuv4_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags)
static int yuv4_read_header(AVFormatContext *s)
Definition yuv4mpegdec.c:34
static int yuv4_probe(const AVProbeData *pd)
static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt)
#define MAX_PIX_FMT_LENGTH
#define MAX_YUV4_HEADER
Definition yuv4mpegdec.c:31
#define MAX_FRAME_HEADER
Definition yuv4mpegdec.c:32