00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/parseutils.h"
00023 #include "libavutil/pixdesc.h"
00024 #include "libavutil/opt.h"
00025 #include "internal.h"
00026 #include "avformat.h"
00027
00028 typedef struct RawVideoDemuxerContext {
00029 const AVClass *class;
00030 char *video_size;
00031 char *pixel_format;
00032 char *framerate;
00033 } RawVideoDemuxerContext;
00034
00035
00036 static int rawvideo_read_header(AVFormatContext *ctx)
00037 {
00038 RawVideoDemuxerContext *s = ctx->priv_data;
00039 int width = 0, height = 0, ret = 0;
00040 enum AVPixelFormat pix_fmt;
00041 AVRational framerate;
00042 AVStream *st;
00043
00044 st = avformat_new_stream(ctx, NULL);
00045 if (!st)
00046 return AVERROR(ENOMEM);
00047
00048 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00049
00050 st->codec->codec_id = ctx->iformat->raw_codec_id;
00051
00052 if (s->video_size &&
00053 (ret = av_parse_video_size(&width, &height, s->video_size)) < 0) {
00054 av_log(ctx, AV_LOG_ERROR, "Couldn't parse video size.\n");
00055 return ret;
00056 }
00057
00058 if ((pix_fmt = av_get_pix_fmt(s->pixel_format)) == AV_PIX_FMT_NONE) {
00059 av_log(ctx, AV_LOG_ERROR, "No such pixel format: %s.\n",
00060 s->pixel_format);
00061 return AVERROR(EINVAL);
00062 }
00063
00064 if ((ret = av_parse_video_rate(&framerate, s->framerate)) < 0) {
00065 av_log(ctx, AV_LOG_ERROR, "Could not parse framerate: %s.\n",
00066 s->framerate);
00067 return ret;
00068 }
00069
00070 avpriv_set_pts_info(st, 64, framerate.den, framerate.num);
00071
00072 st->codec->width = width;
00073 st->codec->height = height;
00074 st->codec->pix_fmt = pix_fmt;
00075 st->codec->bit_rate = av_rescale_q(avpicture_get_size(st->codec->pix_fmt, width, height),
00076 (AVRational){8,1}, st->time_base);
00077
00078 return 0;
00079 }
00080
00081
00082 static int rawvideo_read_packet(AVFormatContext *s, AVPacket *pkt)
00083 {
00084 int packet_size, ret, width, height;
00085 AVStream *st = s->streams[0];
00086
00087 width = st->codec->width;
00088 height = st->codec->height;
00089
00090 packet_size = avpicture_get_size(st->codec->pix_fmt, width, height);
00091 if (packet_size < 0)
00092 return -1;
00093
00094 ret = av_get_packet(s->pb, pkt, packet_size);
00095 pkt->pts = pkt->dts = pkt->pos / packet_size;
00096
00097 pkt->stream_index = 0;
00098 if (ret < 0)
00099 return ret;
00100 return 0;
00101 }
00102
00103 #define OFFSET(x) offsetof(RawVideoDemuxerContext, x)
00104 #define DEC AV_OPT_FLAG_DECODING_PARAM
00105 static const AVOption rawvideo_options[] = {
00106 { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
00107 { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = "yuv420p"}, 0, 0, DEC },
00108 { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
00109 { NULL },
00110 };
00111
00112 static const AVClass rawvideo_demuxer_class = {
00113 .class_name = "rawvideo demuxer",
00114 .item_name = av_default_item_name,
00115 .option = rawvideo_options,
00116 .version = LIBAVUTIL_VERSION_INT,
00117 };
00118
00119 AVInputFormat ff_rawvideo_demuxer = {
00120 .name = "rawvideo",
00121 .long_name = NULL_IF_CONFIG_SMALL("raw video"),
00122 .priv_data_size = sizeof(RawVideoDemuxerContext),
00123 .read_header = rawvideo_read_header,
00124 .read_packet = rawvideo_read_packet,
00125 .flags = AVFMT_GENERIC_INDEX,
00126 .extensions = "yuv,cif,qcif,rgb",
00127 .raw_codec_id = AV_CODEC_ID_RAWVIDEO,
00128 .priv_class = &rawvideo_demuxer_class,
00129 };