summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorD Richard Felker III <dalias@aerifal.cx>2003-08-05 09:32:31 +0000
committerMichael Niedermayer <michaelni@gmx.at>2003-08-05 09:32:31 +0000
commit2864dfd5794a5a9bff612e730179a9026f042a06 (patch)
treebb5d61e7c4ed333fffa6592569395da374e7cda9
parent769fc4660cba3768737692a8e82f25c076e05cdb (diff)
yuv4mpeg pipe reader for libavformat patch by (D Richard Felker III <dalias at aerifal dot cx>)
Originally committed as revision 2102 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavformat/allformats.c2
-rw-r--r--libavformat/avformat.h3
-rw-r--r--libavformat/yuv4mpeg.c97
3 files changed, 101 insertions, 1 deletions
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 95d440f288..6d7064cb1d 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -54,7 +54,7 @@ void av_register_all(void)
#ifdef AMR_NB
amr_init();
#endif
- av_register_output_format(&yuv4mpegpipe_oformat);
+ yuv4mpeg_init();
#ifdef CONFIG_VORBIS
ogg_init();
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 15edc9001c..e89d1619a0 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -328,6 +328,9 @@ int wav_init(void);
/* raw.c */
int raw_init(void);
+/* yuv4mpeg.c */
+int yuv4mpeg_init(void);
+
/* ogg.c */
int ogg_init(void);
diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c
index 7aa35a8687..83b5ff2ab1 100644
--- a/libavformat/yuv4mpeg.c
+++ b/libavformat/yuv4mpeg.c
@@ -173,4 +173,101 @@ AVOutputFormat yuv4mpegpipe_oformat = {
.flags = AVFMT_RAWPICTURE,
};
+#define MAX_YUV4_HEADER 50
+#define MAX_FRAME_HEADER 10
+
+static int yuv4_read_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+ char header[MAX_YUV4_HEADER+1];
+ int i;
+ ByteIOContext *pb = &s->pb;
+ int width, height, raten, rated, aspectn, aspectd;
+ char lacing;
+ AVStream *st;
+
+ for (i=0; i<MAX_YUV4_HEADER; i++) {
+ header[i] = get_byte(pb);
+ if (header[i] == '\n') {
+ header[i+1] = 0;
+ break;
+ }
+ }
+ if (i == MAX_YUV4_HEADER) return -1;
+ if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC))) return -1;
+ sscanf(header+strlen(Y4M_MAGIC), " W%d H%d F%d:%d I%c A%d:%d",
+ &width, &height, &raten, &rated, &lacing, &aspectn, &aspectd);
+
+ st = av_new_stream(s, 0);
+ st = s->streams[0];
+ st->codec.width = width;
+ st->codec.height = height;
+ av_reduce(&raten, &rated, raten, rated, (1UL<<31)-1);
+ st->codec.frame_rate = raten;
+ st->codec.frame_rate_base = rated;
+ st->codec.pix_fmt = PIX_FMT_YUV420P;
+ st->codec.codec_type = CODEC_TYPE_VIDEO;
+ st->codec.codec_id = CODEC_ID_RAWVIDEO;
+
+ return 0;
+}
+
+static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ int i;
+ char header[MAX_FRAME_HEADER+1];
+ int packet_size, ret, width, height;
+ AVStream *st = s->streams[0];
+
+ for (i=0; i<MAX_FRAME_HEADER; i++) {
+ header[i] = get_byte(&s->pb);
+ if (header[i] == '\n') {
+ header[i+1] = 0;
+ break;
+ }
+ }
+ if (i == MAX_FRAME_HEADER) return -1;
+ if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC))) return -1;
+
+ width = st->codec.width;
+ height = st->codec.height;
+
+ packet_size = avpicture_get_size(st->codec.pix_fmt, width, height);
+ if (packet_size < 0)
+ av_abort();
+
+ if (av_new_packet(pkt, packet_size) < 0)
+ return -EIO;
+
+ pkt->stream_index = 0;
+ ret = get_buffer(&s->pb, pkt->data, pkt->size);
+ if (ret != pkt->size) {
+ av_free_packet(pkt);
+ return -EIO;
+ } else {
+ return 0;
+ }
+}
+
+static int yuv4_read_close(AVFormatContext *s)
+{
+ return 0;
+}
+
+AVInputFormat yuv4mpegpipe_iformat = {
+ "yuv4mpegpipe",
+ "YUV4MPEG pipe format",
+ 0,
+ NULL,
+ yuv4_read_header,
+ yuv4_read_packet,
+ yuv4_read_close,
+ .extensions = "yuv4mpeg"
+};
+
+int yuv4mpeg_init(void)
+{
+ av_register_input_format(&yuv4mpegpipe_iformat);
+ av_register_output_format(&yuv4mpegpipe_oformat);
+ return 0;
+}