3 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #define Y4M_MAGIC "YUV4MPEG2"
22 #define Y4M_FRAME_MAGIC "FRAME"
23 #define Y4M_LINE_MAX 256
25 #ifdef CONFIG_ENCODERS
28 static struct { int n
; int d
;} SAR
[] = {{10, 11}, /* 4:3 NTSC */
29 {59, 54}, /* 4:3 PAL */
30 {40, 33}, /* 16:9 NTSC */
31 {118, 81}, /* 16:9 PAL */
32 { 1, 1}};/* should always be the last */
34 static int yuv4_generate_header(AVFormatContext
*s
, char* buf
)
38 int raten
, rated
, aspectn
, aspectd
, n
, i
;
42 width
= st
->codec
.width
;
43 height
= st
->codec
.height
;
45 av_reduce(&raten
, &rated
, st
->codec
.frame_rate
, st
->codec
.frame_rate_base
, (1UL<<31)-1);
47 for (i
=0; i
<sizeof(SAR
)/sizeof(SAR
[0])-1; i
++) {
48 if (ABS(st
->codec
.aspect_ratio
-
49 (float)SAR
[i
].n
/SAR
[i
].d
* (float)width
/height
) < 0.05)
55 inter
= 'p'; /* progressive is the default */
56 if (st
->codec
.coded_frame
&& st
->codec
.coded_frame
->interlaced_frame
) {
57 inter
= st
->codec
.coded_frame
->bottom_field_first ?
'b' : 't';
60 /* construct stream header, if this is the first frame */
61 n
= snprintf(buf
, Y4M_LINE_MAX
, "%s W%d H%d F%d:%d I%c A%d:%d%s\n",
68 (st
->codec
.pix_fmt
== PIX_FMT_YUV411P
) ?
" XYSCSS=411" : "");
73 static int yuv4_write_packet(AVFormatContext
*s
, int stream_index
,
74 const uint8_t *buf
, int size
, int64_t pts
)
76 AVStream
*st
= s
->streams
[stream_index
];
77 ByteIOContext
*pb
= &s
->pb
;
79 int* first_pkt
= s
->priv_data
;
82 char buf2
[Y4M_LINE_MAX
+1];
84 uint8_t *ptr
, *ptr1
, *ptr2
;
86 picture
= (AVPicture
*)buf
;
88 /* for the first packet we have to output the header as well */
91 if (yuv4_generate_header(s
, buf2
) < 0) {
92 fprintf(stderr
, "Error. YUV4MPEG stream header write failed.\n");
95 put_buffer(pb
, buf2
, strlen(buf2
));
99 /* construct frame header */
101 m
= snprintf(buf1
, sizeof(buf1
), "%s\n", Y4M_FRAME_MAGIC
);
102 put_buffer(pb
, buf1
, strlen(buf1
));
104 width
= st
->codec
.width
;
105 height
= st
->codec
.height
;
107 ptr
= picture
->data
[0];
108 for(i
=0;i
<height
;i
++) {
109 put_buffer(pb
, ptr
, width
);
110 ptr
+= picture
->linesize
[0];
115 ptr1
= picture
->data
[1];
116 ptr2
= picture
->data
[2];
117 for(i
=0;i
<height
;i
++) { /* Cb */
118 put_buffer(pb
, ptr1
, width
);
119 ptr1
+= picture
->linesize
[1];
121 for(i
=0;i
<height
;i
++) { /* Cr */
122 put_buffer(pb
, ptr2
, width
);
123 ptr2
+= picture
->linesize
[2];
125 put_flush_packet(pb
);
129 static int yuv4_write_header(AVFormatContext
*s
)
131 int* first_pkt
= s
->priv_data
;
133 if (s
->nb_streams
!= 1)
136 if (s
->streams
[0]->codec
.pix_fmt
== PIX_FMT_YUV411P
) {
137 fprintf(stderr
, "Warning: generating non-standard 4:1:1 YUV stream, some mjpegtools might not work.\n");
139 else if (s
->streams
[0]->codec
.pix_fmt
!= PIX_FMT_YUV420P
) {
140 fprintf(stderr
, "ERROR: yuv4mpeg only handles 4:2:0, 4:1:1 YUV data. Use -pix_fmt to select one.\n");
148 static int yuv4_write_trailer(AVFormatContext
*s
)
153 AVOutputFormat yuv4mpegpipe_oformat
= {
155 "YUV4MPEG pipe format",
164 .flags
= AVFMT_RAWPICTURE
,
166 #endif //CONFIG_ENCODERS
168 /* Header size increased to allow room for optional flags */
169 #define MAX_YUV4_HEADER 80
170 #define MAX_FRAME_HEADER 10
172 static int yuv4_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
174 char header
[MAX_YUV4_HEADER
+1];
176 ByteIOContext
*pb
= &s
->pb
;
177 int width
, height
, raten
, rated
, aspectn
, aspectd
;
181 for (i
=0; i
<MAX_YUV4_HEADER
; i
++) {
182 header
[i
] = get_byte(pb
);
183 if (header
[i
] == '\n') {
188 if (i
== MAX_YUV4_HEADER
) return -1;
189 if (strncmp(header
, Y4M_MAGIC
, strlen(Y4M_MAGIC
))) return -1;
190 sscanf(header
+strlen(Y4M_MAGIC
), " W%d H%d F%d:%d I%c A%d:%d",
191 &width
, &height
, &raten
, &rated
, &lacing
, &aspectn
, &aspectd
);
193 st
= av_new_stream(s
, 0);
195 st
->codec
.width
= width
;
196 st
->codec
.height
= height
;
197 av_reduce(&raten
, &rated
, raten
, rated
, (1UL<<31)-1);
198 st
->codec
.frame_rate
= raten
;
199 st
->codec
.frame_rate_base
= rated
;
200 st
->codec
.pix_fmt
= PIX_FMT_YUV420P
;
201 st
->codec
.codec_type
= CODEC_TYPE_VIDEO
;
202 st
->codec
.codec_id
= CODEC_ID_RAWVIDEO
;
207 static int yuv4_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
210 char header
[MAX_FRAME_HEADER
+1];
211 int packet_size
, ret
, width
, height
;
212 AVStream
*st
= s
->streams
[0];
214 for (i
=0; i
<MAX_FRAME_HEADER
; i
++) {
215 header
[i
] = get_byte(&s
->pb
);
216 if (header
[i
] == '\n') {
221 if (i
== MAX_FRAME_HEADER
) return -1;
222 if (strncmp(header
, Y4M_FRAME_MAGIC
, strlen(Y4M_FRAME_MAGIC
))) return -1;
224 width
= st
->codec
.width
;
225 height
= st
->codec
.height
;
227 packet_size
= avpicture_get_size(st
->codec
.pix_fmt
, width
, height
);
231 if (av_new_packet(pkt
, packet_size
) < 0)
234 pkt
->stream_index
= 0;
235 ret
= get_buffer(&s
->pb
, pkt
->data
, pkt
->size
);
236 if (ret
!= pkt
->size
) {
244 static int yuv4_read_close(AVFormatContext
*s
)
249 AVInputFormat yuv4mpegpipe_iformat
= {
251 "YUV4MPEG pipe format",
257 .extensions
= "yuv4mpeg"
260 int yuv4mpeg_init(void)
262 av_register_input_format(&yuv4mpegpipe_iformat
);
263 #ifdef CONFIG_ENCODERS
264 av_register_output_format(&yuv4mpegpipe_oformat
);
265 #endif //CONFIG_ENCODERS