ffmpeg / libavformat / yuv4mpeg.c @ 56a10009
History | View | Annotate | Download (12.8 KB)
1 | 0b9fb89d | Fabrice Bellard | /*
|
---|---|---|---|
2 | * YUV4MPEG format
|
||
3 | 406792e7 | Diego Biurrun | * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
|
4 | 0b9fb89d | Fabrice Bellard | *
|
5 | 2912e87a | Mans Rullgard | * This file is part of Libav.
|
6 | b78e7197 | Diego Biurrun | *
|
7 | 2912e87a | Mans Rullgard | * Libav is free software; you can redistribute it and/or
|
8 | 0b9fb89d | Fabrice Bellard | * modify it under the terms of the GNU Lesser General Public
|
9 | * License as published by the Free Software Foundation; either
|
||
10 | b78e7197 | Diego Biurrun | * version 2.1 of the License, or (at your option) any later version.
|
11 | 0b9fb89d | Fabrice Bellard | *
|
12 | 2912e87a | Mans Rullgard | * Libav is distributed in the hope that it will be useful,
|
13 | 0b9fb89d | Fabrice Bellard | * 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 | 2912e87a | Mans Rullgard | * License along with Libav; if not, write to the Free Software
|
19 | 5509bffa | Diego Biurrun | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
20 | 0b9fb89d | Fabrice Bellard | */
|
21 | #include "avformat.h" |
||
22 | |||
23 | #define Y4M_MAGIC "YUV4MPEG2" |
||
24 | #define Y4M_FRAME_MAGIC "FRAME" |
||
25 | #define Y4M_LINE_MAX 256 |
||
26 | |||
27 | ad97e414 | Luca Abeni | struct frame_attributes {
|
28 | int interlaced_frame;
|
||
29 | int top_field_first;
|
||
30 | }; |
||
31 | |||
32 | b250f9c6 | Aurelien Jacobs | #if CONFIG_YUV4MPEGPIPE_MUXER
|
33 | 2744ca9a | Roman Shaposhnik | static int yuv4_generate_header(AVFormatContext *s, char* buf) |
34 | 0b9fb89d | Fabrice Bellard | { |
35 | AVStream *st; |
||
36 | int width, height;
|
||
37 | 5ff85f1d | Michael Niedermayer | int raten, rated, aspectn, aspectd, n;
|
38 | 2744ca9a | Roman Shaposhnik | char inter;
|
39 | a97c1e93 | Stefan Huehner | const char *colorspace = ""; |
40 | 0b9fb89d | Fabrice Bellard | |
41 | st = s->streams[0];
|
||
42 | 01f4895c | Michael Niedermayer | width = st->codec->width; |
43 | height = st->codec->height; |
||
44 | 14bea432 | Michael Niedermayer | |
45 | 01f4895c | Michael Niedermayer | av_reduce(&raten, &rated, st->codec->time_base.den, st->codec->time_base.num, (1UL<<31)-1); |
46 | 115329f1 | Diego Biurrun | |
47 | 59729451 | Aurelien Jacobs | aspectn = st->sample_aspect_ratio.num; |
48 | aspectd = st->sample_aspect_ratio.den; |
||
49 | 115329f1 | Diego Biurrun | |
50 | 2d745414 | Roine Gustafsson | if ( aspectn == 0 && aspectd == 1 ) aspectd = 0; // 0:0 means unknown |
51 | |||
52 | 2744ca9a | Roman Shaposhnik | inter = 'p'; /* progressive is the default */ |
53 | 01f4895c | Michael Niedermayer | if (st->codec->coded_frame && st->codec->coded_frame->interlaced_frame) {
|
54 | inter = st->codec->coded_frame->top_field_first ? 't' : 'b'; |
||
55 | 2744ca9a | Roman Shaposhnik | } |
56 | 0b9fb89d | Fabrice Bellard | |
57 | 01f4895c | Michael Niedermayer | switch(st->codec->pix_fmt) {
|
58 | f96b17c5 | Roine Gustafsson | case PIX_FMT_GRAY8:
|
59 | colorspace = " Cmono";
|
||
60 | break;
|
||
61 | 2d745414 | Roine Gustafsson | case PIX_FMT_YUV411P:
|
62 | colorspace = " C411 XYSCSS=411";
|
||
63 | break;
|
||
64 | case PIX_FMT_YUV420P:
|
||
65 | 56bb72dc | David Conrad | colorspace = (st->codec->chroma_sample_location == AVCHROMA_LOC_TOPLEFT)?" C420paldv XYSCSS=420PALDV":
|
66 | (st->codec->chroma_sample_location == AVCHROMA_LOC_LEFT) ?" C420mpeg2 XYSCSS=420MPEG2":
|
||
67 | " C420jpeg XYSCSS=420JPEG";
|
||
68 | 2d745414 | Roine Gustafsson | break;
|
69 | case PIX_FMT_YUV422P:
|
||
70 | colorspace = " C422 XYSCSS=422";
|
||
71 | break;
|
||
72 | case PIX_FMT_YUV444P:
|
||
73 | colorspace = " C444 XYSCSS=444";
|
||
74 | break;
|
||
75 | } |
||
76 | |||
77 | 0b9fb89d | Fabrice Bellard | /* construct stream header, if this is the first frame */
|
78 | 2744ca9a | Roman Shaposhnik | n = snprintf(buf, Y4M_LINE_MAX, "%s W%d H%d F%d:%d I%c A%d:%d%s\n",
|
79 | 0b9fb89d | Fabrice Bellard | Y4M_MAGIC, |
80 | width, |
||
81 | height, |
||
82 | raten, rated, |
||
83 | 2744ca9a | Roman Shaposhnik | inter, |
84 | aspectn, aspectd, |
||
85 | 2d745414 | Roine Gustafsson | colorspace); |
86 | 115329f1 | Diego Biurrun | |
87 | 2744ca9a | Roman Shaposhnik | return n;
|
88 | 0b9fb89d | Fabrice Bellard | } |
89 | |||
90 | e928649b | Michael Niedermayer | static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt) |
91 | 0b9fb89d | Fabrice Bellard | { |
92 | e928649b | Michael Niedermayer | AVStream *st = s->streams[pkt->stream_index]; |
93 | ae628ec1 | Anton Khirnov | AVIOContext *pb = s->pb; |
94 | 0b9fb89d | Fabrice Bellard | AVPicture *picture; |
95 | 2744ca9a | Roman Shaposhnik | int* first_pkt = s->priv_data;
|
96 | 2d745414 | Roine Gustafsson | int width, height, h_chroma_shift, v_chroma_shift;
|
97 | 0b9fb89d | Fabrice Bellard | int i, m;
|
98 | 2744ca9a | Roman Shaposhnik | char buf2[Y4M_LINE_MAX+1]; |
99 | 0b9fb89d | Fabrice Bellard | char buf1[20]; |
100 | 0c1a9eda | Zdenek Kabelac | uint8_t *ptr, *ptr1, *ptr2; |
101 | 0b9fb89d | Fabrice Bellard | |
102 | e928649b | Michael Niedermayer | picture = (AVPicture *)pkt->data; |
103 | 0b9fb89d | Fabrice Bellard | |
104 | 2744ca9a | Roman Shaposhnik | /* for the first packet we have to output the header as well */
|
105 | if (*first_pkt) {
|
||
106 | *first_pkt = 0;
|
||
107 | bb270c08 | Diego Biurrun | if (yuv4_generate_header(s, buf2) < 0) { |
108 | av_log(s, AV_LOG_ERROR, "Error. YUV4MPEG stream header write failed.\n");
|
||
109 | 6f3e0b21 | Panagiotis Issaris | return AVERROR(EIO);
|
110 | bb270c08 | Diego Biurrun | } else {
|
111 | 77eb5504 | Anton Khirnov | avio_write(pb, buf2, strlen(buf2)); |
112 | bb270c08 | Diego Biurrun | } |
113 | 2744ca9a | Roman Shaposhnik | } |
114 | |||
115 | 0b9fb89d | Fabrice Bellard | /* construct frame header */
|
116 | 115329f1 | Diego Biurrun | |
117 | a63d4933 | Steven M. Schultz | m = snprintf(buf1, sizeof(buf1), "%s\n", Y4M_FRAME_MAGIC); |
118 | 77eb5504 | Anton Khirnov | avio_write(pb, buf1, strlen(buf1)); |
119 | 0b9fb89d | Fabrice Bellard | |
120 | 01f4895c | Michael Niedermayer | width = st->codec->width; |
121 | height = st->codec->height; |
||
122 | 115329f1 | Diego Biurrun | |
123 | 0b9fb89d | Fabrice Bellard | ptr = picture->data[0];
|
124 | for(i=0;i<height;i++) { |
||
125 | 77eb5504 | Anton Khirnov | avio_write(pb, ptr, width); |
126 | 0b9fb89d | Fabrice Bellard | ptr += picture->linesize[0];
|
127 | } |
||
128 | |||
129 | 01f4895c | Michael Niedermayer | if (st->codec->pix_fmt != PIX_FMT_GRAY8){
|
130 | 2d745414 | Roine Gustafsson | // Adjust for smaller Cb and Cr planes
|
131 | 01f4895c | Michael Niedermayer | avcodec_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift, &v_chroma_shift); |
132 | 2d745414 | Roine Gustafsson | width >>= h_chroma_shift; |
133 | height >>= v_chroma_shift; |
||
134 | |||
135 | 0b9fb89d | Fabrice Bellard | ptr1 = picture->data[1];
|
136 | ptr2 = picture->data[2];
|
||
137 | bb270c08 | Diego Biurrun | for(i=0;i<height;i++) { /* Cb */ |
138 | 77eb5504 | Anton Khirnov | avio_write(pb, ptr1, width); |
139 | 0b9fb89d | Fabrice Bellard | ptr1 += picture->linesize[1];
|
140 | } |
||
141 | bb270c08 | Diego Biurrun | for(i=0;i<height;i++) { /* Cr */ |
142 | 77eb5504 | Anton Khirnov | avio_write(pb, ptr2, width); |
143 | 0b9fb89d | Fabrice Bellard | ptr2 += picture->linesize[2];
|
144 | } |
||
145 | f96b17c5 | Roine Gustafsson | } |
146 | b7f2fdde | Anton Khirnov | avio_flush(pb); |
147 | 0b9fb89d | Fabrice Bellard | return 0; |
148 | } |
||
149 | |||
150 | 2744ca9a | Roman Shaposhnik | static int yuv4_write_header(AVFormatContext *s) |
151 | { |
||
152 | int* first_pkt = s->priv_data;
|
||
153 | 115329f1 | Diego Biurrun | |
154 | 2744ca9a | Roman Shaposhnik | if (s->nb_streams != 1) |
155 | 6f3e0b21 | Panagiotis Issaris | return AVERROR(EIO);
|
156 | 115329f1 | Diego Biurrun | |
157 | 01f4895c | Michael Niedermayer | if (s->streams[0]->codec->pix_fmt == PIX_FMT_YUV411P) { |
158 | 2d745414 | Roine Gustafsson | av_log(s, AV_LOG_ERROR, "Warning: generating rarely used 4:1:1 YUV stream, some mjpegtools might not work.\n");
|
159 | 115329f1 | Diego Biurrun | } |
160 | else if ((s->streams[0]->codec->pix_fmt != PIX_FMT_YUV420P) && |
||
161 | (s->streams[0]->codec->pix_fmt != PIX_FMT_YUV422P) &&
|
||
162 | (s->streams[0]->codec->pix_fmt != PIX_FMT_GRAY8) &&
|
||
163 | 01f4895c | Michael Niedermayer | (s->streams[0]->codec->pix_fmt != PIX_FMT_YUV444P)) {
|
164 | f96b17c5 | Roine Gustafsson | av_log(s, AV_LOG_ERROR, "ERROR: yuv4mpeg only handles yuv444p, yuv422p, yuv420p, yuv411p and gray pixel formats. Use -pix_fmt to select one.\n");
|
165 | 6f3e0b21 | Panagiotis Issaris | return AVERROR(EIO);
|
166 | 2744ca9a | Roman Shaposhnik | } |
167 | 115329f1 | Diego Biurrun | |
168 | 2744ca9a | Roman Shaposhnik | *first_pkt = 1;
|
169 | return 0; |
||
170 | } |
||
171 | |||
172 | c6610a21 | Diego Elio Pettenò | AVOutputFormat ff_yuv4mpegpipe_muxer = { |
173 | 0b9fb89d | Fabrice Bellard | "yuv4mpegpipe",
|
174 | bde15e74 | Stefano Sabatini | NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"),
|
175 | 0b9fb89d | Fabrice Bellard | "",
|
176 | 8cf71ead | Roine Gustafsson | "y4m",
|
177 | 2744ca9a | Roman Shaposhnik | sizeof(int), |
178 | 0b9fb89d | Fabrice Bellard | CODEC_ID_NONE, |
179 | CODEC_ID_RAWVIDEO, |
||
180 | yuv4_write_header, |
||
181 | yuv4_write_packet, |
||
182 | .flags = AVFMT_RAWPICTURE, |
||
183 | }; |
||
184 | ff70e601 | Måns Rullgård | #endif
|
185 | 0b9fb89d | Fabrice Bellard | |
186 | d9a916e2 | Charles Yates | /* Header size increased to allow room for optional flags */
|
187 | #define MAX_YUV4_HEADER 80 |
||
188 | 2d745414 | Roine Gustafsson | #define MAX_FRAME_HEADER 80 |
189 | 2864dfd5 | D Richard Felker III | |
190 | static int yuv4_read_header(AVFormatContext *s, AVFormatParameters *ap) |
||
191 | { |
||
192 | 2d745414 | Roine Gustafsson | char header[MAX_YUV4_HEADER+10]; // Include headroom for the longest option |
193 | char *tokstart,*tokend,*header_end;
|
||
194 | 2864dfd5 | D Richard Felker III | int i;
|
195 | ae628ec1 | Anton Khirnov | AVIOContext *pb = s->pb; |
196 | ad97e414 | Luca Abeni | int width=-1, height=-1, raten=0, rated=0, aspectn=0, aspectd=0; |
197 | 93b2b333 | Roine Gustafsson | enum PixelFormat pix_fmt=PIX_FMT_NONE,alt_pix_fmt=PIX_FMT_NONE;
|
198 | 56bb72dc | David Conrad | enum AVChromaLocation chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED;
|
199 | 2864dfd5 | D Richard Felker III | AVStream *st; |
200 | ad97e414 | Luca Abeni | struct frame_attributes *s1 = s->priv_data;
|
201 | 115329f1 | Diego Biurrun | |
202 | 2864dfd5 | D Richard Felker III | for (i=0; i<MAX_YUV4_HEADER; i++) { |
203 | b7effd4e | Anton Khirnov | header[i] = avio_r8(pb); |
204 | bb270c08 | Diego Biurrun | if (header[i] == '\n') { |
205 | header[i+1] = 0x20; // Add a space after last option. Makes parsing "444" vs "444alpha" easier. |
||
206 | header[i+2] = 0; |
||
207 | break;
|
||
208 | } |
||
209 | 2864dfd5 | D Richard Felker III | } |
210 | if (i == MAX_YUV4_HEADER) return -1; |
||
211 | if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC))) return -1; |
||
212 | 2d745414 | Roine Gustafsson | |
213 | ad97e414 | Luca Abeni | s1->interlaced_frame = 0;
|
214 | s1->top_field_first = 0;
|
||
215 | 2d745414 | Roine Gustafsson | header_end = &header[i+1]; // Include space |
216 | for(tokstart = &header[strlen(Y4M_MAGIC) + 1]; tokstart < header_end; tokstart++) { |
||
217 | if (*tokstart==0x20) continue; |
||
218 | switch (*tokstart++) {
|
||
219 | case 'W': // Width. Required. |
||
220 | width = strtol(tokstart, &tokend, 10);
|
||
221 | tokstart=tokend; |
||
222 | break;
|
||
223 | case 'H': // Height. Required. |
||
224 | height = strtol(tokstart, &tokend, 10);
|
||
225 | tokstart=tokend; |
||
226 | break;
|
||
227 | case 'C': // Color space |
||
228 | 56bb72dc | David Conrad | if (strncmp("420jpeg",tokstart,7)==0) { |
229 | 2d745414 | Roine Gustafsson | pix_fmt = PIX_FMT_YUV420P; |
230 | 56bb72dc | David Conrad | chroma_sample_location = AVCHROMA_LOC_CENTER; |
231 | } else if (strncmp("420mpeg2",tokstart,8)==0) { |
||
232 | 2d745414 | Roine Gustafsson | pix_fmt = PIX_FMT_YUV420P; |
233 | 56bb72dc | David Conrad | chroma_sample_location = AVCHROMA_LOC_LEFT; |
234 | } else if (strncmp("420paldv", tokstart, 8)==0) { |
||
235 | 2d745414 | Roine Gustafsson | pix_fmt = PIX_FMT_YUV420P; |
236 | 56bb72dc | David Conrad | chroma_sample_location = AVCHROMA_LOC_TOPLEFT; |
237 | } else if (strncmp("411", tokstart, 3)==0) |
||
238 | 2d745414 | Roine Gustafsson | pix_fmt = PIX_FMT_YUV411P; |
239 | else if (strncmp("422", tokstart, 3)==0) |
||
240 | pix_fmt = PIX_FMT_YUV422P; |
||
241 | else if (strncmp("444alpha", tokstart, 8)==0) { |
||
242 | av_log(s, AV_LOG_ERROR, "Cannot handle 4:4:4:4 YUV4MPEG stream.\n");
|
||
243 | return -1; |
||
244 | } else if (strncmp("444", tokstart, 3)==0) |
||
245 | pix_fmt = PIX_FMT_YUV444P; |
||
246 | else if (strncmp("mono",tokstart, 4)==0) { |
||
247 | f96b17c5 | Roine Gustafsson | pix_fmt = PIX_FMT_GRAY8; |
248 | 2d745414 | Roine Gustafsson | } else {
|
249 | av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains an unknown pixel format.\n");
|
||
250 | return -1; |
||
251 | } |
||
252 | while(tokstart<header_end&&*tokstart!=0x20) tokstart++; |
||
253 | break;
|
||
254 | case 'I': // Interlace type |
||
255 | switch (*tokstart++){
|
||
256 | case '?': |
||
257 | break;
|
||
258 | case 'p': |
||
259 | ad97e414 | Luca Abeni | s1->interlaced_frame=0;
|
260 | 2d745414 | Roine Gustafsson | break;
|
261 | case 't': |
||
262 | ad97e414 | Luca Abeni | s1->interlaced_frame=1;
|
263 | s1->top_field_first=1;
|
||
264 | 2d745414 | Roine Gustafsson | break;
|
265 | case 'b': |
||
266 | ad97e414 | Luca Abeni | s1->interlaced_frame=1;
|
267 | s1->top_field_first=0;
|
||
268 | 2d745414 | Roine Gustafsson | break;
|
269 | case 'm': |
||
270 | av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed interlaced and non-interlaced frames.\n");
|
||
271 | return -1; |
||
272 | default:
|
||
273 | av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
|
||
274 | return -1; |
||
275 | } |
||
276 | break;
|
||
277 | case 'F': // Frame rate |
||
278 | sscanf(tokstart,"%d:%d",&raten,&rated); // 0:0 if unknown |
||
279 | while(tokstart<header_end&&*tokstart!=0x20) tokstart++; |
||
280 | break;
|
||
281 | case 'A': // Pixel aspect |
||
282 | sscanf(tokstart,"%d:%d",&aspectn,&aspectd); // 0:0 if unknown |
||
283 | while(tokstart<header_end&&*tokstart!=0x20) tokstart++; |
||
284 | break;
|
||
285 | case 'X': // Vendor extensions |
||
286 | if (strncmp("YSCSS=",tokstart,6)==0) { |
||
287 | // Older nonstandard pixel format representation
|
||
288 | tokstart+=6;
|
||
289 | if (strncmp("420JPEG",tokstart,7)==0) |
||
290 | alt_pix_fmt=PIX_FMT_YUV420P; |
||
291 | else if (strncmp("420MPEG2",tokstart,8)==0) |
||
292 | alt_pix_fmt=PIX_FMT_YUV420P; |
||
293 | else if (strncmp("420PALDV",tokstart,8)==0) |
||
294 | alt_pix_fmt=PIX_FMT_YUV420P; |
||
295 | else if (strncmp("411",tokstart,3)==0) |
||
296 | alt_pix_fmt=PIX_FMT_YUV411P; |
||
297 | else if (strncmp("422",tokstart,3)==0) |
||
298 | alt_pix_fmt=PIX_FMT_YUV422P; |
||
299 | else if (strncmp("444",tokstart,3)==0) |
||
300 | alt_pix_fmt=PIX_FMT_YUV444P; |
||
301 | } |
||
302 | while(tokstart<header_end&&*tokstart!=0x20) tokstart++; |
||
303 | break;
|
||
304 | } |
||
305 | 115329f1 | Diego Biurrun | } |
306 | 2d745414 | Roine Gustafsson | |
307 | if ((width == -1) || (height == -1)) { |
||
308 | av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
|
||
309 | 115329f1 | Diego Biurrun | return -1; |
310 | 2d745414 | Roine Gustafsson | } |
311 | 115329f1 | Diego Biurrun | |
312 | 93b2b333 | Roine Gustafsson | if (pix_fmt == PIX_FMT_NONE) {
|
313 | if (alt_pix_fmt == PIX_FMT_NONE)
|
||
314 | 2d745414 | Roine Gustafsson | pix_fmt = PIX_FMT_YUV420P; |
315 | else
|
||
316 | pix_fmt = alt_pix_fmt; |
||
317 | } |
||
318 | |||
319 | 7f8ffc4e | Daniel Kang | if (raten <= 0 || rated <= 0) { |
320 | 2d745414 | Roine Gustafsson | // Frame rate unknown
|
321 | raten = 25;
|
||
322 | rated = 1;
|
||
323 | } |
||
324 | |||
325 | if (aspectn == 0 && aspectd == 0) { |
||
326 | // Pixel aspect unknown
|
||
327 | aspectd = 1;
|
||
328 | } |
||
329 | 115329f1 | Diego Biurrun | |
330 | 2864dfd5 | D Richard Felker III | st = av_new_stream(s, 0);
|
331 | 884d5385 | Michael Niedermayer | if(!st)
|
332 | 8b9c4ad2 | Michael Niedermayer | return AVERROR(ENOMEM);
|
333 | 01f4895c | Michael Niedermayer | st->codec->width = width; |
334 | st->codec->height = height; |
||
335 | 2864dfd5 | D Richard Felker III | av_reduce(&raten, &rated, raten, rated, (1UL<<31)-1); |
336 | c0df9d75 | Michael Niedermayer | av_set_pts_info(st, 64, rated, raten);
|
337 | 01f4895c | Michael Niedermayer | st->codec->pix_fmt = pix_fmt; |
338 | 72415b2a | Stefano Sabatini | st->codec->codec_type = AVMEDIA_TYPE_VIDEO; |
339 | 01f4895c | Michael Niedermayer | st->codec->codec_id = CODEC_ID_RAWVIDEO; |
340 | 59729451 | Aurelien Jacobs | st->sample_aspect_ratio= (AVRational){aspectn, aspectd}; |
341 | 56bb72dc | David Conrad | st->codec->chroma_sample_location = chroma_sample_location; |
342 | 2864dfd5 | D Richard Felker III | |
343 | return 0; |
||
344 | } |
||
345 | |||
346 | static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt) |
||
347 | { |
||
348 | int i;
|
||
349 | char header[MAX_FRAME_HEADER+1]; |
||
350 | bf4e3bd2 | Måns Rullgård | int packet_size, width, height;
|
351 | 2864dfd5 | D Richard Felker III | AVStream *st = s->streams[0];
|
352 | ad97e414 | Luca Abeni | struct frame_attributes *s1 = s->priv_data;
|
353 | 2864dfd5 | D Richard Felker III | |
354 | for (i=0; i<MAX_FRAME_HEADER; i++) { |
||
355 | b7effd4e | Anton Khirnov | header[i] = avio_r8(s->pb); |
356 | bb270c08 | Diego Biurrun | if (header[i] == '\n') { |
357 | header[i+1] = 0; |
||
358 | break;
|
||
359 | } |
||
360 | 2864dfd5 | D Richard Felker III | } |
361 | if (i == MAX_FRAME_HEADER) return -1; |
||
362 | if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC))) return -1; |
||
363 | 115329f1 | Diego Biurrun | |
364 | 01f4895c | Michael Niedermayer | width = st->codec->width; |
365 | height = st->codec->height; |
||
366 | 2864dfd5 | D Richard Felker III | |
367 | 01f4895c | Michael Niedermayer | packet_size = avpicture_get_size(st->codec->pix_fmt, width, height); |
368 | 2864dfd5 | D Richard Felker III | if (packet_size < 0) |
369 | 71c32f19 | Michael Niedermayer | return -1; |
370 | 2864dfd5 | D Richard Felker III | |
371 | 899681cd | Björn Axelsson | if (av_get_packet(s->pb, pkt, packet_size) != packet_size)
|
372 | 6f3e0b21 | Panagiotis Issaris | return AVERROR(EIO);
|
373 | 2864dfd5 | D Richard Felker III | |
374 | ad97e414 | Luca Abeni | if (s->streams[0]->codec->coded_frame) { |
375 | s->streams[0]->codec->coded_frame->interlaced_frame = s1->interlaced_frame;
|
||
376 | s->streams[0]->codec->coded_frame->top_field_first = s1->top_field_first;
|
||
377 | } |
||
378 | |||
379 | 2864dfd5 | D Richard Felker III | pkt->stream_index = 0;
|
380 | 2692067a | Michael Niedermayer | return 0; |
381 | 2864dfd5 | D Richard Felker III | } |
382 | |||
383 | 8cf71ead | Roine Gustafsson | static int yuv4_probe(AVProbeData *pd) |
384 | { |
||
385 | /* check file header */
|
||
386 | if (strncmp(pd->buf, Y4M_MAGIC, sizeof(Y4M_MAGIC)-1)==0) |
||
387 | return AVPROBE_SCORE_MAX;
|
||
388 | else
|
||
389 | return 0; |
||
390 | } |
||
391 | |||
392 | b250f9c6 | Aurelien Jacobs | #if CONFIG_YUV4MPEGPIPE_DEMUXER
|
393 | c6610a21 | Diego Elio Pettenò | AVInputFormat ff_yuv4mpegpipe_demuxer = { |
394 | 2864dfd5 | D Richard Felker III | "yuv4mpegpipe",
|
395 | bde15e74 | Stefano Sabatini | NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"),
|
396 | ad97e414 | Luca Abeni | sizeof(struct frame_attributes), |
397 | 8cf71ead | Roine Gustafsson | yuv4_probe, |
398 | 2864dfd5 | D Richard Felker III | yuv4_read_header, |
399 | yuv4_read_packet, |
||
400 | 8cf71ead | Roine Gustafsson | .extensions = "y4m"
|
401 | 2864dfd5 | D Richard Felker III | }; |
402 | ff70e601 | Måns Rullgård | #endif |