X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fraw.c;h=41a65469158e61bc89edd42aa3f47384d37d64f2;hb=ac6a655b8a191a56dc194b548d8ba7bb16ea6abb;hp=a1dcf871c405aa5c76a74d4c40ac8a298e25c972;hpb=14bea432f16d7c66f9099e427819028b6b4c3bdc;p=ffmpeg diff --git a/libavformat/raw.c b/libavformat/raw.c index a1dcf871c40..41a65469158 100644 --- a/libavformat/raw.c +++ b/libavformat/raw.c @@ -1,6 +1,7 @@ /* * RAW encoder and decoder * Copyright (c) 2001 Fabrice Bellard. + * Copyright (c) 2005 Alex Beregszaszi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,16 +19,16 @@ */ #include "avformat.h" +#ifdef CONFIG_MUXERS /* simple formats */ static int raw_write_header(struct AVFormatContext *s) { return 0; } -static int raw_write_packet(struct AVFormatContext *s, int stream_index, - unsigned char *buf, int size, int force_pts) +static int raw_write_packet(struct AVFormatContext *s, AVPacket *pkt) { - put_buffer(&s->pb, buf, size); + put_buffer(&s->pb, pkt->data, pkt->size); put_flush_packet(&s->pb); return 0; } @@ -36,6 +37,7 @@ static int raw_write_trailer(struct AVFormatContext *s) { return 0; } +#endif //CONFIG_MUXERS /* raw input */ static int raw_read_header(AVFormatContext *s, AVFormatParameters *ap) @@ -49,22 +51,25 @@ static int raw_read_header(AVFormatContext *s, AVFormatParameters *ap) if (ap) { id = s->iformat->value; if (id == CODEC_ID_RAWVIDEO) { - st->codec.codec_type = CODEC_TYPE_VIDEO; + st->codec->codec_type = CODEC_TYPE_VIDEO; } else { - st->codec.codec_type = CODEC_TYPE_AUDIO; + st->codec->codec_type = CODEC_TYPE_AUDIO; } - st->codec.codec_id = id; + st->codec->codec_id = id; - switch(st->codec.codec_type) { + switch(st->codec->codec_type) { case CODEC_TYPE_AUDIO: - st->codec.sample_rate = ap->sample_rate; - st->codec.channels = ap->channels; + st->codec->sample_rate = ap->sample_rate; + st->codec->channels = ap->channels; + av_set_pts_info(st, 64, 1, st->codec->sample_rate); break; case CODEC_TYPE_VIDEO: - st->codec.frame_rate = ap->frame_rate; - st->codec.frame_rate_base = ap->frame_rate_base; - st->codec.width = ap->width; - st->codec.height = ap->height; + av_set_pts_info(st, 64, ap->time_base.num, ap->time_base.den); + st->codec->width = ap->width; + st->codec->height = ap->height; + st->codec->pix_fmt = ap->pix_fmt; + if(st->codec->pix_fmt == PIX_FMT_NONE) + st->codec->pix_fmt= PIX_FMT_YUV420P; break; default: return -1; @@ -84,17 +89,70 @@ static int raw_read_packet(AVFormatContext *s, AVPacket *pkt) size= RAW_PACKET_SIZE; + ret= av_get_packet(&s->pb, pkt, size); + + pkt->stream_index = 0; + if (ret <= 0) { + return AVERROR_IO; + } + /* note: we need to modify the packet size here to handle the last + packet */ + pkt->size = ret; + return ret; +} + +static int raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt) +{ + int ret, size; + + size = RAW_PACKET_SIZE; + if (av_new_packet(pkt, size) < 0) - return -EIO; + return AVERROR_IO; + + pkt->pos= url_ftell(&s->pb); + pkt->stream_index = 0; + ret = get_partial_buffer(&s->pb, pkt->data, size); + if (ret <= 0) { + av_free_packet(pkt); + return AVERROR_IO; + } + pkt->size = ret; + return ret; +} +// http://www.artificis.hu/files/texts/ingenient.txt +static int ingenient_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + int ret, size, w, h, unk1, unk2; + + if (get_le32(&s->pb) != MKTAG('M', 'J', 'P', 'G')) + return AVERROR_IO; // FIXME + + size = get_le32(&s->pb); + + w = get_le16(&s->pb); + h = get_le16(&s->pb); + + url_fskip(&s->pb, 8); // zero + size (padded?) + url_fskip(&s->pb, 2); + unk1 = get_le16(&s->pb); + unk2 = get_le16(&s->pb); + url_fskip(&s->pb, 22); // ascii timestamp + + av_log(NULL, AV_LOG_DEBUG, "Ingenient packet: size=%d, width=%d, height=%d, unk1=%d unk2=%d\n", + size, w, h, unk1, unk2); + + if (av_new_packet(pkt, size) < 0) + return AVERROR_IO; + + pkt->pos = url_ftell(&s->pb); pkt->stream_index = 0; ret = get_buffer(&s->pb, pkt->data, size); if (ret <= 0) { av_free_packet(pkt); - return -EIO; + return AVERROR_IO; } - /* note: we need to modify the packet size here to handle the last - packet */ pkt->size = ret; return ret; } @@ -104,8 +162,53 @@ static int raw_read_close(AVFormatContext *s) return 0; } -/* mp3 read */ -static int mp3_read_header(AVFormatContext *s, +int pcm_read_seek(AVFormatContext *s, + int stream_index, int64_t timestamp, int flags) +{ + AVStream *st; + int block_align, byte_rate; + int64_t pos; + + st = s->streams[0]; + switch(st->codec->codec_id) { + case CODEC_ID_PCM_S16LE: + case CODEC_ID_PCM_S16BE: + case CODEC_ID_PCM_U16LE: + case CODEC_ID_PCM_U16BE: + block_align = 2 * st->codec->channels; + byte_rate = block_align * st->codec->sample_rate; + break; + case CODEC_ID_PCM_S8: + case CODEC_ID_PCM_U8: + case CODEC_ID_PCM_MULAW: + case CODEC_ID_PCM_ALAW: + block_align = st->codec->channels; + byte_rate = block_align * st->codec->sample_rate; + break; + default: + block_align = st->codec->block_align; + byte_rate = st->codec->bit_rate / 8; + break; + } + + if (block_align <= 0 || byte_rate <= 0) + return -1; + + /* compute the position by aligning it to block_align */ + pos = av_rescale_rnd(timestamp * byte_rate, + st->time_base.num, + st->time_base.den * (int64_t)block_align, + (flags & AVSEEK_FLAG_BACKWARD) ? AV_ROUND_DOWN : AV_ROUND_UP); + pos *= block_align; + + /* recompute exact position */ + st->cur_dts = av_rescale(pos, st->time_base.den, byte_rate * (int64_t)st->time_base.num); + url_fseek(&s->pb, pos + s->data_offset, SEEK_SET); + return 0; +} + +/* ac3 read */ +static int ac3_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVStream *st; @@ -114,14 +217,30 @@ static int mp3_read_header(AVFormatContext *s, if (!st) return AVERROR_NOMEM; - st->codec.codec_type = CODEC_TYPE_AUDIO; - st->codec.codec_id = CODEC_ID_MP2; + st->codec->codec_type = CODEC_TYPE_AUDIO; + st->codec->codec_id = CODEC_ID_AC3; + st->need_parsing = 1; /* the parameters will be extracted from the compressed bitstream */ return 0; } -/* ac3 read */ -static int ac3_read_header(AVFormatContext *s, +static int shorten_read_header(AVFormatContext *s, + AVFormatParameters *ap) +{ + AVStream *st; + + st = av_new_stream(s, 0); + if (!st) + return AVERROR_NOMEM; + st->codec->codec_type = CODEC_TYPE_AUDIO; + st->codec->codec_id = CODEC_ID_SHORTEN; + st->need_parsing = 1; + /* the parameters will be extracted from the compressed bitstream */ + return 0; +} + +/* dts read */ +static int dts_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVStream *st; @@ -130,8 +249,9 @@ static int ac3_read_header(AVFormatContext *s, if (!st) return AVERROR_NOMEM; - st->codec.codec_type = CODEC_TYPE_AUDIO; - st->codec.codec_id = CODEC_ID_AC3; + st->codec->codec_type = CODEC_TYPE_AUDIO; + st->codec->codec_id = CODEC_ID_DTS; + st->need_parsing = 1; /* the parameters will be extracted from the compressed bitstream */ return 0; } @@ -146,19 +266,20 @@ static int video_read_header(AVFormatContext *s, if (!st) return AVERROR_NOMEM; - st->codec.codec_type = CODEC_TYPE_VIDEO; - st->codec.codec_id = s->iformat->value; + st->codec->codec_type = CODEC_TYPE_VIDEO; + st->codec->codec_id = s->iformat->value; + st->need_parsing = 1; + /* for mjpeg, specify frame rate */ /* for mpeg4 specify it too (most mpeg4 streams dont have the fixed_vop_rate set ...)*/ - if (st->codec.codec_id == CODEC_ID_MJPEG || st->codec.codec_id == CODEC_ID_MPEG4) { - if (ap) { - st->codec.frame_rate = ap->frame_rate; - st->codec.frame_rate_base = ap->frame_rate_base; - } else { - st->codec.frame_rate = 25; - st->codec.frame_rate_base = 1; - } + if (ap && ap->time_base.num) { + av_set_pts_info(st, 64, ap->time_base.num, ap->time_base.den); + } else if ( st->codec->codec_id == CODEC_ID_MJPEG || + st->codec->codec_id == CODEC_ID_MPEG4 || + st->codec->codec_id == CODEC_ID_H264) { + av_set_pts_info(st, 64, 1, 25); } + return 0; } @@ -193,42 +314,59 @@ static int mpegvideo_probe(AVProbeData *p) return 0; } -AVInputFormat mp3_iformat = { - "mp3", - "MPEG audio", +static int h263_probe(AVProbeData *p) +{ + int code; + const uint8_t *d; + + if (p->buf_size < 6) + return 0; + d = p->buf; + code = (d[0] << 14) | (d[1] << 6) | (d[2] >> 2); + if (code == 0x20) { + return 50; + } + return 0; +} + +static int h261_probe(AVProbeData *p) +{ + int code; + const uint8_t *d; + + if (p->buf_size < 6) + return 0; + d = p->buf; + code = (d[0] << 12) | (d[1] << 4) | (d[2] >> 4); + if (code == 0x10) { + return 50; + } + return 0; +} + +AVInputFormat shorten_iformat = { + "shn", + "raw shorten", 0, NULL, - mp3_read_header, - raw_read_packet, + shorten_read_header, + raw_read_partial_packet, raw_read_close, - .extensions = "mp2,mp3", /* XXX: use probe */ -}; - -AVOutputFormat mp2_oformat = { - "mp2", - "MPEG audio layer 2", - "audio/x-mpeg", - "mp2,mp3", - 0, - CODEC_ID_MP2, - 0, - raw_write_header, - raw_write_packet, - raw_write_trailer, + .extensions = "shn", }; - AVInputFormat ac3_iformat = { "ac3", "raw ac3", 0, NULL, ac3_read_header, - raw_read_packet, + raw_read_partial_packet, raw_read_close, .extensions = "ac3", }; +#ifdef CONFIG_MUXERS AVOutputFormat ac3_oformat = { "ac3", "raw ac3", @@ -241,7 +379,59 @@ AVOutputFormat ac3_oformat = { raw_write_packet, raw_write_trailer, }; +#endif //CONFIG_MUXERS + +AVInputFormat dts_iformat = { + "dts", + "raw dts", + 0, + NULL, + dts_read_header, + raw_read_partial_packet, + raw_read_close, + .extensions = "dts", +}; + +AVInputFormat h261_iformat = { + "h261", + "raw h261", + 0, + h261_probe, + video_read_header, + raw_read_partial_packet, + raw_read_close, + .extensions = "h261", + .value = CODEC_ID_H261, +}; + +#ifdef CONFIG_MUXERS +AVOutputFormat h261_oformat = { + "h261", + "raw h261", + "video/x-h261", + "h261", + 0, + 0, + CODEC_ID_H261, + raw_write_header, + raw_write_packet, + raw_write_trailer, +}; +#endif //CONFIG_MUXERS +AVInputFormat h263_iformat = { + "h263", + "raw h263", + 0, + h263_probe, + video_read_header, + raw_read_partial_packet, + raw_read_close, +// .extensions = "h263", //FIXME remove after writing mpeg4_probe + .value = CODEC_ID_H263, +}; + +#ifdef CONFIG_MUXERS AVOutputFormat h263_oformat = { "h263", "raw h263", @@ -254,6 +444,7 @@ AVOutputFormat h263_oformat = { raw_write_packet, raw_write_trailer, }; +#endif //CONFIG_MUXERS AVInputFormat m4v_iformat = { "m4v", @@ -261,12 +452,13 @@ AVInputFormat m4v_iformat = { 0, NULL /*mpegvideo_probe*/, video_read_header, - raw_read_packet, + raw_read_partial_packet, raw_read_close, .extensions = "m4v", //FIXME remove after writing mpeg4_probe .value = CODEC_ID_MPEG4, }; +#ifdef CONFIG_MUXERS AVOutputFormat m4v_oformat = { "m4v", "raw MPEG4 video format", @@ -279,6 +471,34 @@ AVOutputFormat m4v_oformat = { raw_write_packet, raw_write_trailer, }; +#endif //CONFIG_MUXERS + +AVInputFormat h264_iformat = { + "h264", + "raw H264 video format", + 0, + NULL /*mpegvideo_probe*/, + video_read_header, + raw_read_partial_packet, + raw_read_close, + .extensions = "h26l,h264,264", //FIXME remove after writing mpeg4_probe + .value = CODEC_ID_H264, +}; + +#ifdef CONFIG_MUXERS +AVOutputFormat h264_oformat = { + "h264", + "raw H264 video format", + NULL, + "h264", + 0, + CODEC_ID_NONE, + CODEC_ID_H264, + raw_write_header, + raw_write_packet, + raw_write_trailer, +}; +#endif //CONFIG_MUXERS AVInputFormat mpegvideo_iformat = { "mpegvideo", @@ -286,16 +506,17 @@ AVInputFormat mpegvideo_iformat = { 0, mpegvideo_probe, video_read_header, - raw_read_packet, + raw_read_partial_packet, raw_read_close, .value = CODEC_ID_MPEG1VIDEO, }; +#ifdef CONFIG_MUXERS AVOutputFormat mpeg1video_oformat = { "mpeg1video", "MPEG video", "video/x-mpeg", - "mpg,mpeg", + "mpg,mpeg,m1v", 0, 0, CODEC_ID_MPEG1VIDEO, @@ -303,6 +524,22 @@ AVOutputFormat mpeg1video_oformat = { raw_write_packet, raw_write_trailer, }; +#endif //CONFIG_MUXERS + +#ifdef CONFIG_MUXERS +AVOutputFormat mpeg2video_oformat = { + "mpeg2video", + "MPEG2 video", + NULL, + "m2v", + 0, + 0, + CODEC_ID_MPEG2VIDEO, + raw_write_header, + raw_write_packet, + raw_write_trailer, +}; +#endif //CONFIG_MUXERS AVInputFormat mjpeg_iformat = { "mjpeg", @@ -310,12 +547,25 @@ AVInputFormat mjpeg_iformat = { 0, NULL, video_read_header, - raw_read_packet, + raw_read_partial_packet, raw_read_close, .extensions = "mjpg,mjpeg", .value = CODEC_ID_MJPEG, }; +AVInputFormat ingenient_iformat = { + "ingenient", + "Ingenient MJPEG", + 0, + NULL, + video_read_header, + ingenient_read_packet, + raw_read_close, + .extensions = "cgi", // FIXME + .value = CODEC_ID_MJPEG, +}; + +#ifdef CONFIG_MUXERS AVOutputFormat mjpeg_oformat = { "mjpeg", "MJPEG video", @@ -328,10 +578,11 @@ AVOutputFormat mjpeg_oformat = { raw_write_packet, raw_write_trailer, }; +#endif //CONFIG_MUXERS /* pcm formats */ -#define PCMDEF(name, long_name, ext, codec) \ +#define PCMINPUTDEF(name, long_name, ext, codec) \ AVInputFormat pcm_ ## name ## _iformat = {\ #name,\ long_name,\ @@ -340,9 +591,20 @@ AVInputFormat pcm_ ## name ## _iformat = {\ raw_read_header,\ raw_read_packet,\ raw_read_close,\ + pcm_read_seek,\ .extensions = ext,\ .value = codec,\ -};\ +}; + +#if !defined(CONFIG_MUXERS) && defined(CONFIG_DEMUXERS) + +#define PCMDEF(name, long_name, ext, codec) \ + PCMINPUTDEF(name, long_name, ext, codec) + +#else + +#define PCMDEF(name, long_name, ext, codec) \ + PCMINPUTDEF(name, long_name, ext, codec)\ \ AVOutputFormat pcm_ ## name ## _oformat = {\ #name,\ @@ -356,6 +618,7 @@ AVOutputFormat pcm_ ## name ## _oformat = {\ raw_write_packet,\ raw_write_trailer,\ }; +#endif //CONFIG_MUXERS #ifdef WORDS_BIGENDIAN #define BE_DEF(s) s @@ -395,38 +658,18 @@ static int rawvideo_read_packet(AVFormatContext *s, AVPacket *pkt) int packet_size, ret, width, height; AVStream *st = s->streams[0]; - width = st->codec.width; - height = st->codec.height; + width = st->codec->width; + height = st->codec->height; - switch(st->codec.pix_fmt) { - case PIX_FMT_YUV420P: - packet_size = (width * height * 3) / 2; - break; - case PIX_FMT_YUV422: - packet_size = (width * height * 2); - break; - case PIX_FMT_BGR24: - case PIX_FMT_RGB24: - packet_size = (width * height * 3); - break; - default: - av_abort(); - break; - } + packet_size = avpicture_get_size(st->codec->pix_fmt, width, height); + if (packet_size < 0) + return -1; - if (av_new_packet(pkt, packet_size) < 0) - return -EIO; + ret= av_get_packet(&s->pb, pkt, packet_size); pkt->stream_index = 0; -#if 0 - /* bypass buffered I/O */ - ret = url_read(url_fileno(&s->pb), pkt->data, pkt->size); -#else - ret = get_buffer(&s->pb, pkt->data, pkt->size); -#endif - if (ret != pkt->size) { - av_free_packet(pkt); - return -EIO; + if (ret != packet_size) { + return AVERROR_IO; } else { return 0; } @@ -440,10 +683,11 @@ AVInputFormat rawvideo_iformat = { raw_read_header, rawvideo_read_packet, raw_read_close, - .extensions = "yuv", + .extensions = "yuv,cif,qcif", .value = CODEC_ID_RAWVIDEO, }; +#ifdef CONFIG_MUXERS AVOutputFormat rawvideo_oformat = { "rawvideo", "raw video format", @@ -456,10 +700,10 @@ AVOutputFormat rawvideo_oformat = { raw_write_packet, raw_write_trailer, }; +#endif //CONFIG_MUXERS -static int null_write_packet(struct AVFormatContext *s, - int stream_index, - unsigned char *buf, int size, int force_pts) +#ifdef CONFIG_MUXERS +static int null_write_packet(struct AVFormatContext *s, AVPacket *pkt) { return 0; } @@ -481,25 +725,46 @@ AVOutputFormat null_oformat = { raw_write_trailer, .flags = AVFMT_NOFILE | AVFMT_RAWPICTURE, }; +#endif //CONFIG_MUXERS + +#ifndef CONFIG_MUXERS +#define av_register_output_format(format) +#endif +#ifndef CONFIG_DEMUXERS +#define av_register_input_format(format) +#endif int raw_init(void) { - av_register_input_format(&mp3_iformat); - av_register_output_format(&mp2_oformat); - + + av_register_input_format(&shorten_iformat); + av_register_input_format(&ac3_iformat); av_register_output_format(&ac3_oformat); + av_register_input_format(&dts_iformat); + + av_register_input_format(&h261_iformat); + av_register_output_format(&h261_oformat); + + av_register_input_format(&h263_iformat); av_register_output_format(&h263_oformat); av_register_input_format(&m4v_iformat); av_register_output_format(&m4v_oformat); + + av_register_input_format(&h264_iformat); + av_register_output_format(&h264_oformat); av_register_input_format(&mpegvideo_iformat); av_register_output_format(&mpeg1video_oformat); + av_register_output_format(&mpeg2video_oformat); + av_register_input_format(&mjpeg_iformat); av_register_output_format(&mjpeg_oformat); + + av_register_input_format(&ingenient_iformat); av_register_input_format(&pcm_s16le_iformat); av_register_output_format(&pcm_s16le_oformat);