2 * Chronomaster DFA Format Demuxer
3 * Copyright (c) 2011 Konstantin Shishkov
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
24 #include "libavutil/intreadwrite.h"
28 static int dfa_probe(AVProbeData
*p
)
30 if (p
->buf_size
< 4 || AV_RL32(p
->buf
) != MKTAG('D', 'F', 'I', 'A'))
33 if (AV_RL32(p
->buf
+ 16) != 0x80)
34 return AVPROBE_SCORE_MAX
/ 4;
36 return AVPROBE_SCORE_MAX
;
39 static int dfa_read_header(AVFormatContext
*s
)
41 AVIOContext
*pb
= s
->pb
;
47 if (avio_rl32(pb
) != MKTAG('D', 'F', 'I', 'A')) {
48 av_log(s
, AV_LOG_ERROR
, "Invalid magic for DFA\n");
49 return AVERROR_INVALIDDATA
;
52 version
= avio_rl16(pb
);
53 frames
= avio_rl16(pb
);
55 st
= avformat_new_stream(s
, NULL
);
57 return AVERROR(ENOMEM
);
59 st
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
60 st
->codec
->codec_id
= AV_CODEC_ID_DFA
;
61 st
->codec
->width
= avio_rl16(pb
);
62 st
->codec
->height
= avio_rl16(pb
);
65 av_log(s
, AV_LOG_WARNING
, "Zero FPS reported, defaulting to 10\n");
68 avpriv_set_pts_info(st
, 24, mspf
, 1000);
69 avio_skip(pb
, 128 - 16); // padding
70 st
->duration
= frames
;
72 if (ff_alloc_extradata(st
->codec
, 2))
73 return AVERROR(ENOMEM
);
74 AV_WL16(st
->codec
->extradata
, version
);
76 st
->sample_aspect_ratio
= (AVRational
){2, 1};
81 static int dfa_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
83 AVIOContext
*pb
= s
->pb
;
90 if (av_get_packet(pb
, pkt
, 12) != 12)
92 while (!avio_feof(pb
)) {
94 ret
= av_append_packet(pb
, pkt
, 12);
101 frame_size
= AV_RL32(pkt
->data
+ pkt
->size
- 8);
102 if (frame_size
> INT_MAX
- 4) {
103 av_log(s
, AV_LOG_ERROR
, "Too large chunk size: %"PRIu32
"\n", frame_size
);
106 if (AV_RL32(pkt
->data
+ pkt
->size
- 12) == MKTAG('E', 'O', 'F', 'R')) {
108 av_log(s
, AV_LOG_WARNING
,
109 "skipping %"PRIu32
" bytes of end-of-frame marker chunk\n",
111 avio_skip(pb
, frame_size
);
115 ret
= av_append_packet(pb
, pkt
, frame_size
);
125 AVInputFormat ff_dfa_demuxer
= {
127 .long_name
= NULL_IF_CONFIG_SMALL("Chronomaster DFA"),
128 .read_probe
= dfa_probe
,
129 .read_header
= dfa_read_header
,
130 .read_packet
= dfa_read_packet
,
131 .flags
= AVFMT_GENERIC_INDEX
,