Mercurial > libavformat.hg
annotate yuv4mpeg.c @ 5200:cd884511ec8b libavformat
Make packet interleaving in the muxer not scan through the whole
buffer when simply appending at the end works.
Much faster if one stream ends prematurely.
Fixes issue1379.
author | michael |
---|---|
date | Wed, 16 Sep 2009 00:59:15 +0000 |
parents | a88b31642727 |
children | 536e5527c1e0 |
rev | line source |
---|---|
18 | 1 /* |
2 * YUV4MPEG format | |
4251
77e0c7511d41
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
4206
diff
changeset
|
3 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard |
18 | 4 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
18 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
18 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
18 | 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 | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
887
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
18 | 20 */ |
21 #include "avformat.h" | |
22 | |
23 #define Y4M_MAGIC "YUV4MPEG2" | |
24 #define Y4M_FRAME_MAGIC "FRAME" | |
25 #define Y4M_LINE_MAX 256 | |
26 | |
934
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
27 struct frame_attributes { |
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
28 int interlaced_frame; |
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
29 int top_field_first; |
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
30 }; |
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
31 |
4206 | 32 #if CONFIG_YUV4MPEGPIPE_MUXER |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
33 static int yuv4_generate_header(AVFormatContext *s, char* buf) |
18 | 34 { |
35 AVStream *st; | |
36 int width, height; | |
288 | 37 int raten, rated, aspectn, aspectd, n; |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
38 char inter; |
1123
6992dd78ff68
Add (mostly) const to variable and parameter declaration, where a char* was
diego
parents:
935
diff
changeset
|
39 const char *colorspace = ""; |
18 | 40 |
41 st = s->streams[0]; | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
42 width = st->codec->width; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
43 height = st->codec->height; |
85
25062c9b1f86
per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents:
65
diff
changeset
|
44 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
45 av_reduce(&raten, &rated, st->codec->time_base.den, st->codec->time_base.num, (1UL<<31)-1); |
885 | 46 |
3759
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3559
diff
changeset
|
47 aspectn = st->sample_aspect_ratio.num; |
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3559
diff
changeset
|
48 aspectd = st->sample_aspect_ratio.den; |
885 | 49 |
634 | 50 if ( aspectn == 0 && aspectd == 1 ) aspectd = 0; // 0:0 means unknown |
51 | |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
52 inter = 'p'; /* progressive is the default */ |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
53 if (st->codec->coded_frame && st->codec->coded_frame->interlaced_frame) { |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
54 inter = st->codec->coded_frame->top_field_first ? 't' : 'b'; |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
55 } |
18 | 56 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
57 switch(st->codec->pix_fmt) { |
648
340f1911cd54
add luma only support to yuv4mpeg patch by (Roine Gustafsson <roine users.sourceforge net>)
michael
parents:
634
diff
changeset
|
58 case PIX_FMT_GRAY8: |
340f1911cd54
add luma only support to yuv4mpeg patch by (Roine Gustafsson <roine users.sourceforge net>)
michael
parents:
634
diff
changeset
|
59 colorspace = " Cmono"; |
340f1911cd54
add luma only support to yuv4mpeg patch by (Roine Gustafsson <roine users.sourceforge net>)
michael
parents:
634
diff
changeset
|
60 break; |
634 | 61 case PIX_FMT_YUV411P: |
62 colorspace = " C411 XYSCSS=411"; | |
63 break; | |
64 case PIX_FMT_YUV420P: | |
4923
a88b31642727
Use chroma_sample_location in reading/writing yuv4mpeg
conrad
parents:
4251
diff
changeset
|
65 colorspace = (st->codec->chroma_sample_location == AVCHROMA_LOC_TOPLEFT)?" C420paldv XYSCSS=420PALDV": |
a88b31642727
Use chroma_sample_location in reading/writing yuv4mpeg
conrad
parents:
4251
diff
changeset
|
66 (st->codec->chroma_sample_location == AVCHROMA_LOC_LEFT) ?" C420mpeg2 XYSCSS=420MPEG2": |
a88b31642727
Use chroma_sample_location in reading/writing yuv4mpeg
conrad
parents:
4251
diff
changeset
|
67 " C420jpeg XYSCSS=420JPEG"; |
634 | 68 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 | |
18 | 77 /* construct stream header, if this is the first frame */ |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
78 n = snprintf(buf, Y4M_LINE_MAX, "%s W%d H%d F%d:%d I%c A%d:%d%s\n", |
18 | 79 Y4M_MAGIC, |
80 width, | |
81 height, | |
82 raten, rated, | |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
83 inter, |
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
84 aspectn, aspectd, |
634 | 85 colorspace); |
885 | 86 |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
87 return n; |
18 | 88 } |
89 | |
468 | 90 static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt) |
18 | 91 { |
468 | 92 AVStream *st = s->streams[pkt->stream_index]; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
93 ByteIOContext *pb = s->pb; |
18 | 94 AVPicture *picture; |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
95 int* first_pkt = s->priv_data; |
634 | 96 int width, height, h_chroma_shift, v_chroma_shift; |
18 | 97 int i, m; |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
98 char buf2[Y4M_LINE_MAX+1]; |
18 | 99 char buf1[20]; |
65 | 100 uint8_t *ptr, *ptr1, *ptr2; |
18 | 101 |
468 | 102 picture = (AVPicture *)pkt->data; |
18 | 103 |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
104 /* for the first packet we have to output the header as well */ |
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
105 if (*first_pkt) { |
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
106 *first_pkt = 0; |
887 | 107 if (yuv4_generate_header(s, buf2) < 0) { |
108 av_log(s, AV_LOG_ERROR, "Error. YUV4MPEG stream header write failed.\n"); | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2210
diff
changeset
|
109 return AVERROR(EIO); |
887 | 110 } else { |
111 put_buffer(pb, buf2, strlen(buf2)); | |
112 } | |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
113 } |
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
114 |
18 | 115 /* construct frame header */ |
885 | 116 |
256
2efd6fe95fc6
yuv4mpeg.c extra space patch by ("Steven M. Schultz" <sms at 2BSD dot COM>)
michaelni
parents:
241
diff
changeset
|
117 m = snprintf(buf1, sizeof(buf1), "%s\n", Y4M_FRAME_MAGIC); |
18 | 118 put_buffer(pb, buf1, strlen(buf1)); |
119 | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
120 width = st->codec->width; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
121 height = st->codec->height; |
885 | 122 |
18 | 123 ptr = picture->data[0]; |
124 for(i=0;i<height;i++) { | |
125 put_buffer(pb, ptr, width); | |
126 ptr += picture->linesize[0]; | |
127 } | |
128 | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
129 if (st->codec->pix_fmt != PIX_FMT_GRAY8){ |
634 | 130 // Adjust for smaller Cb and Cr planes |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
131 avcodec_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift, &v_chroma_shift); |
634 | 132 width >>= h_chroma_shift; |
133 height >>= v_chroma_shift; | |
134 | |
18 | 135 ptr1 = picture->data[1]; |
136 ptr2 = picture->data[2]; | |
887 | 137 for(i=0;i<height;i++) { /* Cb */ |
18 | 138 put_buffer(pb, ptr1, width); |
139 ptr1 += picture->linesize[1]; | |
140 } | |
887 | 141 for(i=0;i<height;i++) { /* Cr */ |
18 | 142 put_buffer(pb, ptr2, width); |
143 ptr2 += picture->linesize[2]; | |
144 } | |
648
340f1911cd54
add luma only support to yuv4mpeg patch by (Roine Gustafsson <roine users.sourceforge net>)
michael
parents:
634
diff
changeset
|
145 } |
18 | 146 put_flush_packet(pb); |
147 return 0; | |
148 } | |
149 | |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
150 static int yuv4_write_header(AVFormatContext *s) |
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
151 { |
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
152 int* first_pkt = s->priv_data; |
885 | 153 |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
154 if (s->nb_streams != 1) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2210
diff
changeset
|
155 return AVERROR(EIO); |
885 | 156 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
157 if (s->streams[0]->codec->pix_fmt == PIX_FMT_YUV411P) { |
634 | 158 av_log(s, AV_LOG_ERROR, "Warning: generating rarely used 4:1:1 YUV stream, some mjpegtools might not work.\n"); |
885 | 159 } |
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) && | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
163 (s->streams[0]->codec->pix_fmt != PIX_FMT_YUV444P)) { |
648
340f1911cd54
add luma only support to yuv4mpeg patch by (Roine Gustafsson <roine users.sourceforge net>)
michael
parents:
634
diff
changeset
|
164 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"); |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2210
diff
changeset
|
165 return AVERROR(EIO); |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
166 } |
885 | 167 |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
168 *first_pkt = 1; |
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
169 return 0; |
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
170 } |
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
171 |
1167 | 172 AVOutputFormat yuv4mpegpipe_muxer = { |
18 | 173 "yuv4mpegpipe", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3402
diff
changeset
|
174 NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"), |
18 | 175 "", |
739
db0a5e0f4db5
Adds read probe to y4m, and changes the extension to .y4m patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
738
diff
changeset
|
176 "y4m", |
284
c77ce17451a1
* providing MPEG codecs with a generic fields in AVFrame to use.
romansh
parents:
277
diff
changeset
|
177 sizeof(int), |
18 | 178 CODEC_ID_NONE, |
179 CODEC_ID_RAWVIDEO, | |
180 yuv4_write_header, | |
181 yuv4_write_packet, | |
182 .flags = AVFMT_RAWPICTURE, | |
183 }; | |
1169 | 184 #endif |
18 | 185 |
207
7865656658dc
stdin patch by (Charles Yates <charles dot yates at pandora dot be>)
michaelni
parents:
184
diff
changeset
|
186 /* Header size increased to allow room for optional flags */ |
7865656658dc
stdin patch by (Charles Yates <charles dot yates at pandora dot be>)
michaelni
parents:
184
diff
changeset
|
187 #define MAX_YUV4_HEADER 80 |
634 | 188 #define MAX_FRAME_HEADER 80 |
18 | 189 |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
190 static int yuv4_read_header(AVFormatContext *s, AVFormatParameters *ap) |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
191 { |
634 | 192 char header[MAX_YUV4_HEADER+10]; // Include headroom for the longest option |
193 char *tokstart,*tokend,*header_end; | |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
194 int i; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
195 ByteIOContext *pb = s->pb; |
934
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
196 int width=-1, height=-1, raten=0, rated=0, aspectn=0, aspectd=0; |
738
dad78387544a
Update yuv4mpeg to use PIX_FMT_NONE patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
648
diff
changeset
|
197 enum PixelFormat pix_fmt=PIX_FMT_NONE,alt_pix_fmt=PIX_FMT_NONE; |
4923
a88b31642727
Use chroma_sample_location in reading/writing yuv4mpeg
conrad
parents:
4251
diff
changeset
|
198 enum AVChromaLocation chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED; |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
199 AVStream *st; |
934
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
200 struct frame_attributes *s1 = s->priv_data; |
885 | 201 |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
202 for (i=0; i<MAX_YUV4_HEADER; i++) { |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
203 header[i] = get_byte(pb); |
887 | 204 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 } | |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
209 } |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
210 if (i == MAX_YUV4_HEADER) return -1; |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
211 if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC))) return -1; |
634 | 212 |
934
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
213 s1->interlaced_frame = 0; |
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
214 s1->top_field_first = 0; |
634 | 215 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 | |
4923
a88b31642727
Use chroma_sample_location in reading/writing yuv4mpeg
conrad
parents:
4251
diff
changeset
|
228 if (strncmp("420jpeg",tokstart,7)==0) { |
634 | 229 pix_fmt = PIX_FMT_YUV420P; |
4923
a88b31642727
Use chroma_sample_location in reading/writing yuv4mpeg
conrad
parents:
4251
diff
changeset
|
230 chroma_sample_location = AVCHROMA_LOC_CENTER; |
a88b31642727
Use chroma_sample_location in reading/writing yuv4mpeg
conrad
parents:
4251
diff
changeset
|
231 } else if (strncmp("420mpeg2",tokstart,8)==0) { |
634 | 232 pix_fmt = PIX_FMT_YUV420P; |
4923
a88b31642727
Use chroma_sample_location in reading/writing yuv4mpeg
conrad
parents:
4251
diff
changeset
|
233 chroma_sample_location = AVCHROMA_LOC_LEFT; |
a88b31642727
Use chroma_sample_location in reading/writing yuv4mpeg
conrad
parents:
4251
diff
changeset
|
234 } else if (strncmp("420paldv", tokstart, 8)==0) { |
634 | 235 pix_fmt = PIX_FMT_YUV420P; |
4923
a88b31642727
Use chroma_sample_location in reading/writing yuv4mpeg
conrad
parents:
4251
diff
changeset
|
236 chroma_sample_location = AVCHROMA_LOC_TOPLEFT; |
a88b31642727
Use chroma_sample_location in reading/writing yuv4mpeg
conrad
parents:
4251
diff
changeset
|
237 } else if (strncmp("411", tokstart, 3)==0) |
634 | 238 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) { | |
648
340f1911cd54
add luma only support to yuv4mpeg patch by (Roine Gustafsson <roine users.sourceforge net>)
michael
parents:
634
diff
changeset
|
247 pix_fmt = PIX_FMT_GRAY8; |
634 | 248 } 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': | |
934
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
259 s1->interlaced_frame=0; |
634 | 260 break; |
261 case 't': | |
934
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
262 s1->interlaced_frame=1; |
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
263 s1->top_field_first=1; |
634 | 264 break; |
265 case 'b': | |
934
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
266 s1->interlaced_frame=1; |
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
267 s1->top_field_first=0; |
634 | 268 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 } | |
885 | 305 } |
634 | 306 |
307 if ((width == -1) || (height == -1)) { | |
308 av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n"); | |
885 | 309 return -1; |
634 | 310 } |
885 | 311 |
738
dad78387544a
Update yuv4mpeg to use PIX_FMT_NONE patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
648
diff
changeset
|
312 if (pix_fmt == PIX_FMT_NONE) { |
dad78387544a
Update yuv4mpeg to use PIX_FMT_NONE patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
648
diff
changeset
|
313 if (alt_pix_fmt == PIX_FMT_NONE) |
634 | 314 pix_fmt = PIX_FMT_YUV420P; |
315 else | |
316 pix_fmt = alt_pix_fmt; | |
317 } | |
318 | |
319 if (raten == 0 && rated == 0) { | |
320 // 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 } | |
885 | 329 |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
330 st = av_new_stream(s, 0); |
3386 | 331 if(!st) |
3402 | 332 return AVERROR(ENOMEM); |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
333 st->codec->width = width; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
334 st->codec->height = height; |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
335 av_reduce(&raten, &rated, raten, rated, (1UL<<31)-1); |
743 | 336 av_set_pts_info(st, 64, rated, raten); |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
337 st->codec->pix_fmt = pix_fmt; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
338 st->codec->codec_type = CODEC_TYPE_VIDEO; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
339 st->codec->codec_id = CODEC_ID_RAWVIDEO; |
3759
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3559
diff
changeset
|
340 st->sample_aspect_ratio= (AVRational){aspectn, aspectd}; |
4923
a88b31642727
Use chroma_sample_location in reading/writing yuv4mpeg
conrad
parents:
4251
diff
changeset
|
341 st->codec->chroma_sample_location = chroma_sample_location; |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
342 |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
343 return 0; |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
344 } |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
345 |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
346 static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt) |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
347 { |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
348 int i; |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
349 char header[MAX_FRAME_HEADER+1]; |
838 | 350 int packet_size, width, height; |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
351 AVStream *st = s->streams[0]; |
934
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
352 struct frame_attributes *s1 = s->priv_data; |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
353 |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
354 for (i=0; i<MAX_FRAME_HEADER; i++) { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
355 header[i] = get_byte(s->pb); |
887 | 356 if (header[i] == '\n') { |
357 header[i+1] = 0; | |
358 break; | |
359 } | |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
360 } |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
361 if (i == MAX_FRAME_HEADER) return -1; |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
362 if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC))) return -1; |
885 | 363 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
364 width = st->codec->width; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
365 height = st->codec->height; |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
366 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
367 packet_size = avpicture_get_size(st->codec->pix_fmt, width, height); |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
368 if (packet_size < 0) |
537 | 369 return -1; |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
370 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2274
diff
changeset
|
371 if (av_get_packet(s->pb, pkt, packet_size) != packet_size) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2210
diff
changeset
|
372 return AVERROR(EIO); |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
373 |
934
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
374 if (s->streams[0]->codec->coded_frame) { |
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
375 s->streams[0]->codec->coded_frame->interlaced_frame = s1->interlaced_frame; |
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
376 s->streams[0]->codec->coded_frame->top_field_first = s1->top_field_first; |
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
377 } |
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
378 |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
379 pkt->stream_index = 0; |
775 | 380 return 0; |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
381 } |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
382 |
739
db0a5e0f4db5
Adds read probe to y4m, and changes the extension to .y4m patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
738
diff
changeset
|
383 static int yuv4_probe(AVProbeData *pd) |
db0a5e0f4db5
Adds read probe to y4m, and changes the extension to .y4m patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
738
diff
changeset
|
384 { |
db0a5e0f4db5
Adds read probe to y4m, and changes the extension to .y4m patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
738
diff
changeset
|
385 /* check file header */ |
db0a5e0f4db5
Adds read probe to y4m, and changes the extension to .y4m patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
738
diff
changeset
|
386 if (strncmp(pd->buf, Y4M_MAGIC, sizeof(Y4M_MAGIC)-1)==0) |
db0a5e0f4db5
Adds read probe to y4m, and changes the extension to .y4m patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
738
diff
changeset
|
387 return AVPROBE_SCORE_MAX; |
db0a5e0f4db5
Adds read probe to y4m, and changes the extension to .y4m patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
738
diff
changeset
|
388 else |
db0a5e0f4db5
Adds read probe to y4m, and changes the extension to .y4m patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
738
diff
changeset
|
389 return 0; |
db0a5e0f4db5
Adds read probe to y4m, and changes the extension to .y4m patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
738
diff
changeset
|
390 } |
db0a5e0f4db5
Adds read probe to y4m, and changes the extension to .y4m patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
738
diff
changeset
|
391 |
4206 | 392 #if CONFIG_YUV4MPEGPIPE_DEMUXER |
1167 | 393 AVInputFormat yuv4mpegpipe_demuxer = { |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
394 "yuv4mpegpipe", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3402
diff
changeset
|
395 NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"), |
934
8973dbae81e8
Correctly set the interlaced_frame and top_field_first fields.
diego
parents:
896
diff
changeset
|
396 sizeof(struct frame_attributes), |
739
db0a5e0f4db5
Adds read probe to y4m, and changes the extension to .y4m patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
738
diff
changeset
|
397 yuv4_probe, |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
398 yuv4_read_header, |
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
399 yuv4_read_packet, |
739
db0a5e0f4db5
Adds read probe to y4m, and changes the extension to .y4m patch by (Roine Gustafsson <roine users sourceforge net)
michael
parents:
738
diff
changeset
|
400 .extensions = "y4m" |
184
2438e76dde67
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
michaelni
parents:
178
diff
changeset
|
401 }; |
1169 | 402 #endif |