3 * Copyright (c) 2001 Fabrice Bellard
5 * This file is part of FFmpeg.
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.
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.
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
22 #include "config_components.h"
24 #include "libavutil/imgutils.h"
25 #include "libavutil/parseutils.h"
26 #include "libavutil/pixdesc.h"
27 #include "libavutil/opt.h"
32 typedef struct RawVideoDemuxerContext
{
33 const AVClass
*class; /**< Class for private options. */
34 int width
, height
; /**< Integers describing video size, set by a private option. */
35 char *pixel_format
; /**< Set by a private option. */
36 AVRational framerate
; /**< AVRational describing framerate, set by a private option. */
37 } RawVideoDemuxerContext
;
39 // v210 frame width is padded to multiples of 48
40 #define GET_PACKET_SIZE(w, h) (((w + 47) / 48) * 48 * h * 8 / 3)
42 static int rawvideo_read_header(AVFormatContext
*ctx
)
44 RawVideoDemuxerContext
*s
= ctx
->priv_data
;
45 enum AVPixelFormat pix_fmt
;
50 st
= avformat_new_stream(ctx
, NULL
);
52 return AVERROR(ENOMEM
);
54 st
->codecpar
->codec_type
= AVMEDIA_TYPE_VIDEO
;
56 st
->codecpar
->codec_id
= ffifmt(ctx
->iformat
)->raw_codec_id
;
58 if ((ffifmt(ctx
->iformat
)->raw_codec_id
!= AV_CODEC_ID_V210
) &&
59 (ffifmt(ctx
->iformat
)->raw_codec_id
!= AV_CODEC_ID_V210X
)) {
60 if ((pix_fmt
= av_get_pix_fmt(s
->pixel_format
)) == AV_PIX_FMT_NONE
) {
61 av_log(ctx
, AV_LOG_ERROR
, "No such pixel format: %s.\n",
63 return AVERROR(EINVAL
);
67 avpriv_set_pts_info(st
, 64, s
->framerate
.den
, s
->framerate
.num
);
69 ret
= av_image_check_size(s
->width
, s
->height
, 0, ctx
);
73 st
->codecpar
->width
= s
->width
;
74 st
->codecpar
->height
= s
->height
;
76 if (ffifmt(ctx
->iformat
)->raw_codec_id
== AV_CODEC_ID_BITPACKED
) {
77 unsigned int pgroup
; /* size of the pixel group in bytes */
79 const AVPixFmtDescriptor
*desc
;
82 desc
= av_pix_fmt_desc_get(pix_fmt
);
83 st
->codecpar
->bits_per_coded_sample
= av_get_bits_per_pixel(desc
);
84 if (pix_fmt
== AV_PIX_FMT_YUV422P10
) {
85 tag
= MKTAG('U', 'Y', 'V', 'Y');
88 } else if (pix_fmt
== AV_PIX_FMT_UYVY422
) {
89 tag
= MKTAG('U', 'Y', 'V', 'Y');
92 st
->codecpar
->codec_id
= AV_CODEC_ID_RAWVIDEO
;
94 av_log(ctx
, AV_LOG_ERROR
, "unsupported format: %s for bitpacked.\n",
96 return AVERROR(EINVAL
);
98 st
->codecpar
->codec_tag
= tag
;
99 packet_size
= s
->width
* s
->height
* pgroup
/ xinc
;
100 } else if ((ffifmt(ctx
->iformat
)->raw_codec_id
== AV_CODEC_ID_V210
) ||
101 (ffifmt(ctx
->iformat
)->raw_codec_id
== AV_CODEC_ID_V210X
)) {
102 pix_fmt
= ffifmt(ctx
->iformat
)->raw_codec_id
== AV_CODEC_ID_V210
?
103 AV_PIX_FMT_YUV422P10
: AV_PIX_FMT_YUV422P16
;
105 packet_size
= GET_PACKET_SIZE(s
->width
, s
->height
);
107 packet_size
= av_image_get_buffer_size(pix_fmt
, s
->width
, s
->height
, 1);
111 if (packet_size
== 0)
112 return AVERROR(EINVAL
);
114 st
->codecpar
->format
= pix_fmt
;
115 ctx
->packet_size
= packet_size
;
116 st
->codecpar
->bit_rate
= av_rescale_q(ctx
->packet_size
,
117 (AVRational
){8,1}, st
->time_base
);
123 static int rawvideo_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
127 ret
= av_get_packet(s
->pb
, pkt
, s
->packet_size
);
128 pkt
->pts
= pkt
->dts
= pkt
->pos
/ s
->packet_size
;
130 pkt
->stream_index
= 0;
136 #define OFFSET(x) offsetof(RawVideoDemuxerContext, x)
137 #define DEC AV_OPT_FLAG_DECODING_PARAM
138 static const AVOption rawvideo_options
[] = {
139 /* pixel_format is not used by the v210 demuxers. */
140 { "pixel_format", "set pixel format", OFFSET(pixel_format
), AV_OPT_TYPE_STRING
, {.str
= "yuv420p"}, 0, 0, DEC
},
141 { "video_size", "set frame size", OFFSET(width
), AV_OPT_TYPE_IMAGE_SIZE
, {.str
= NULL
}, 0, 0, DEC
},
142 { "framerate", "set frame rate", OFFSET(framerate
), AV_OPT_TYPE_VIDEO_RATE
, {.str
= "25"}, 0, INT_MAX
, DEC
},
146 static const AVClass rawvideo_demuxer_class
= {
147 .class_name
= "rawvideo demuxer",
148 .item_name
= av_default_item_name
,
149 .option
= rawvideo_options
,
150 .version
= LIBAVUTIL_VERSION_INT
,
153 const FFInputFormat ff_rawvideo_demuxer
= {
154 .p
.name
= "rawvideo",
155 .p
.long_name
= NULL_IF_CONFIG_SMALL("raw video"),
156 .p
.flags
= AVFMT_GENERIC_INDEX
,
157 .p
.extensions
= "yuv,cif,qcif,rgb",
158 .p
.priv_class
= &rawvideo_demuxer_class
,
159 .priv_data_size
= sizeof(RawVideoDemuxerContext
),
160 .read_header
= rawvideo_read_header
,
161 .read_packet
= rawvideo_read_packet
,
162 .raw_codec_id
= AV_CODEC_ID_RAWVIDEO
,
165 static const AVClass bitpacked_demuxer_class
= {
166 .class_name
= "bitpacked demuxer",
167 .item_name
= av_default_item_name
,
168 .option
= rawvideo_options
,
169 .version
= LIBAVUTIL_VERSION_INT
,
172 #if CONFIG_BITPACKED_DEMUXER
173 const FFInputFormat ff_bitpacked_demuxer
= {
174 .p
.name
= "bitpacked",
175 .p
.long_name
= NULL_IF_CONFIG_SMALL("Bitpacked"),
176 .p
.flags
= AVFMT_GENERIC_INDEX
,
177 .p
.extensions
= "bitpacked",
178 .p
.priv_class
= &bitpacked_demuxer_class
,
179 .priv_data_size
= sizeof(RawVideoDemuxerContext
),
180 .read_header
= rawvideo_read_header
,
181 .read_packet
= rawvideo_read_packet
,
182 .raw_codec_id
= AV_CODEC_ID_BITPACKED
,
184 #endif // CONFIG_BITPACKED_DEMUXER
186 static const AVClass v210_demuxer_class
= {
187 .class_name
= "v210(x) demuxer",
188 .item_name
= av_default_item_name
,
189 .option
= rawvideo_options
+ 1,
190 .version
= LIBAVUTIL_VERSION_INT
,
193 #if CONFIG_V210_DEMUXER
194 const FFInputFormat ff_v210_demuxer
= {
196 .p
.long_name
= NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
197 .p
.flags
= AVFMT_GENERIC_INDEX
,
198 .p
.extensions
= "v210",
199 .p
.priv_class
= &v210_demuxer_class
,
200 .priv_data_size
= sizeof(RawVideoDemuxerContext
),
201 .read_header
= rawvideo_read_header
,
202 .read_packet
= rawvideo_read_packet
,
203 .raw_codec_id
= AV_CODEC_ID_V210
,
205 #endif // CONFIG_V210_DEMUXER
207 #if CONFIG_V210X_DEMUXER
208 const FFInputFormat ff_v210x_demuxer
= {
210 .p
.long_name
= NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
211 .p
.flags
= AVFMT_GENERIC_INDEX
,
212 .p
.extensions
= "yuv10",
213 .p
.priv_class
= &v210_demuxer_class
,
214 .priv_data_size
= sizeof(RawVideoDemuxerContext
),
215 .read_header
= rawvideo_read_header
,
216 .read_packet
= rawvideo_read_packet
,
217 .raw_codec_id
= AV_CODEC_ID_V210X
,
219 #endif // CONFIG_V210X_DEMUXER