• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2010 David Conrad
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "avformat.h"
22 #include "internal.h"
23 #include "riff.h"
24 #include "libavutil/intreadwrite.h"
25 
probe(const AVProbeData * p)26 static int probe(const AVProbeData *p)
27 {
28     if (AV_RL32(p->buf) == MKTAG('D','K','I','F')
29         && !AV_RL16(p->buf+4) && AV_RL16(p->buf+6) == 32)
30         return AVPROBE_SCORE_MAX-2;
31 
32     return 0;
33 }
34 
read_header(AVFormatContext * s)35 static int read_header(AVFormatContext *s)
36 {
37     AVStream *st;
38     AVRational time_base;
39 
40     avio_rl32(s->pb); // DKIF
41     avio_rl16(s->pb); // version
42     avio_rl16(s->pb); // header size
43 
44     st = avformat_new_stream(s, NULL);
45     if (!st)
46         return AVERROR(ENOMEM);
47 
48 
49     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
50     st->codecpar->codec_tag  = avio_rl32(s->pb);
51     st->codecpar->codec_id   = ff_codec_get_id(ff_codec_bmp_tags, st->codecpar->codec_tag);
52     st->codecpar->width      = avio_rl16(s->pb);
53     st->codecpar->height     = avio_rl16(s->pb);
54     time_base.den         = avio_rl32(s->pb);
55     time_base.num         = avio_rl32(s->pb);
56     st->duration          = avio_rl32(s->pb);
57     avio_skip(s->pb, 4); // unused
58 
59     st->need_parsing      = AVSTREAM_PARSE_HEADERS;
60 
61     if (!time_base.den || !time_base.num) {
62         av_log(s, AV_LOG_ERROR, "Invalid frame rate\n");
63         return AVERROR_INVALIDDATA;
64     }
65 
66     avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
67 
68     return 0;
69 }
70 
read_packet(AVFormatContext * s,AVPacket * pkt)71 static int read_packet(AVFormatContext *s, AVPacket *pkt)
72 {
73     int ret, size = avio_rl32(s->pb);
74     int64_t   pts = avio_rl64(s->pb);
75 
76     ret = av_get_packet(s->pb, pkt, size);
77     pkt->stream_index = 0;
78     pkt->pts          = pts;
79     pkt->pos         -= 12;
80 
81     return ret;
82 }
83 
84 AVInputFormat ff_ivf_demuxer = {
85     .name           = "ivf",
86     .long_name      = NULL_IF_CONFIG_SMALL("On2 IVF"),
87     .read_probe     = probe,
88     .read_header    = read_header,
89     .read_packet    = read_packet,
90     .flags          = AVFMT_GENERIC_INDEX,
91     .codec_tag      = (const AVCodecTag* const []){ ff_codec_bmp_tags, 0 },
92 };
93