annotate tmv.c @ 5237:496723640f94 libavformat

Extend DV autodetection to also reliably detect single-frame DVs with a higher score that MAX/4. It checks that there are at least 10 DIF headers and at least one per 24000 bytes, and if so considers the file reliably detected as DV. Passes probetest, too.
author reimar
date Tue, 29 Sep 2009 10:12:18 +0000
parents 21f7970b66d4
children bcd5ff60e3da
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4910
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
1 /*
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
2 * 8088flex TMV file demuxer
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
3 * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
4 *
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
5 * This file is part of FFmpeg.
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
6 *
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
11 *
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
15 * Lesser General Public License for more details.
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
16 *
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
20 */
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
21
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
22 /**
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
23 * 8088flex TMV file demuxer
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
24 * @file libavformat/tmv.c
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
25 * @author Daniel Verkamp
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
26 * @sa http://www.oldskool.org/pc/8088_Corruption
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
27 */
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
28
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
29 #include "libavutil/intreadwrite.h"
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
30 #include "avformat.h"
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
31
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
32 enum {
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
33 TMV_PADDING = 0x01,
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
34 TMV_STEREO = 0x02,
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
35 };
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
36
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
37 #define TMV_TAG MKTAG('T', 'M', 'A', 'V')
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
38
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
39 typedef struct TMVContext {
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
40 unsigned audio_chunk_size;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
41 unsigned video_chunk_size;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
42 unsigned padding;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
43 unsigned stream_index;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
44 } TMVContext;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
45
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
46 static int tmv_probe(AVProbeData *p)
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
47 {
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
48 if (AV_RL32(p->buf) == TMV_TAG)
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
49 return AVPROBE_SCORE_MAX;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
50 return 0;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
51 }
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
52
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
53 static int tmv_read_header(AVFormatContext *s, AVFormatParameters *ap)
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
54 {
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
55 TMVContext *tmv = s->priv_data;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
56 ByteIOContext *pb = s->pb;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
57 AVStream *vst, *ast;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
58 AVRational fps;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
59 unsigned comp_method, char_cols, char_rows, features;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
60
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
61 if (get_le32(pb) != TMV_TAG)
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
62 return -1;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
63
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
64 if (!(vst = av_new_stream(s, 0)))
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
65 return AVERROR(ENOMEM);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
66
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
67 if (!(ast = av_new_stream(s, 0)))
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
68 return AVERROR(ENOMEM);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
69
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
70 ast->codec->sample_rate = get_le16(pb);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
71 tmv->audio_chunk_size = get_le16(pb);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
72 if (!tmv->audio_chunk_size) {
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
73 av_log(s, AV_LOG_ERROR, "invalid audio chunk size\n");
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
74 return -1;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
75 }
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
76
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
77 comp_method = get_byte(pb);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
78 if (comp_method) {
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
79 av_log(s, AV_LOG_ERROR, "unsupported compression method %d\n",
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
80 comp_method);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
81 return -1;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
82 }
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
83
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
84 char_cols = get_byte(pb);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
85 char_rows = get_byte(pb);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
86 tmv->video_chunk_size = char_cols * char_rows * 2;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
87
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
88 features = get_byte(pb);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
89 if (features & ~(TMV_PADDING | TMV_STEREO)) {
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
90 av_log(s, AV_LOG_ERROR, "unsupported features 0x%02x\n",
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
91 features & ~(TMV_PADDING | TMV_STEREO));
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
92 return -1;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
93 }
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
94
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
95 ast->codec->codec_type = CODEC_TYPE_AUDIO;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
96 ast->codec->codec_id = CODEC_ID_PCM_U8;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
97 ast->codec->sample_fmt = SAMPLE_FMT_U8;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
98 ast->codec->channels = features & TMV_STEREO ? 2 : 1;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
99 ast->codec->bits_per_coded_sample = 8;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
100 ast->codec->bit_rate = ast->codec->sample_rate *
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
101 ast->codec->bits_per_coded_sample;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
102 av_set_pts_info(ast, 32, 1, ast->codec->sample_rate);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
103
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
104 fps.num = ast->codec->sample_rate * ast->codec->channels;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
105 fps.den = tmv->audio_chunk_size;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
106 av_reduce(&fps.num, &fps.den, fps.num, fps.den, 0xFFFFFFFFLL);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
107
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
108 vst->codec->codec_type = CODEC_TYPE_VIDEO;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
109 vst->codec->codec_id = CODEC_ID_TMV;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
110 vst->codec->pix_fmt = PIX_FMT_PAL8;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
111 vst->codec->width = char_cols * 8;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
112 vst->codec->height = char_rows * 8;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
113 av_set_pts_info(vst, 32, fps.den, fps.num);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
114
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
115 if (features & TMV_PADDING)
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
116 tmv->padding =
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
117 ((tmv->video_chunk_size + tmv->audio_chunk_size + 511) & ~511) -
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
118 (tmv->video_chunk_size + tmv->audio_chunk_size);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
119
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
120 vst->codec->bit_rate = ((tmv->video_chunk_size + tmv->padding) *
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
121 fps.num * 8) / fps.den;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
122
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
123 return 0;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
124 }
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
125
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
126 static int tmv_read_packet(AVFormatContext *s, AVPacket *pkt)
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
127 {
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
128 TMVContext *tmv = s->priv_data;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
129 ByteIOContext *pb = s->pb;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
130 int ret, pkt_size = tmv->stream_index ?
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
131 tmv->audio_chunk_size : tmv->video_chunk_size;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
132
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
133 if (url_feof(pb))
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
134 return AVERROR_EOF;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
135
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
136 ret = av_get_packet(pb, pkt, pkt_size);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
137
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
138 if (tmv->stream_index)
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
139 url_fskip(pb, tmv->padding);
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
140
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
141 pkt->stream_index = tmv->stream_index;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
142 tmv->stream_index ^= 1;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
143 pkt->flags |= PKT_FLAG_KEY;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
144
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
145 return ret;
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
146 }
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
147
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
148 AVInputFormat tmv_demuxer = {
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
149 "tmv",
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
150 NULL_IF_CONFIG_SMALL("8088flex TMV"),
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
151 sizeof(TMVContext),
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
152 tmv_probe,
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
153 tmv_read_header,
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
154 tmv_read_packet,
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
155 .flags = AVFMT_GENERIC_INDEX,
21f7970b66d4 Add 8088flex TMV file demuxer.
stefano
parents:
diff changeset
156 };