ffmpeg / libavformat / tta.c @ 756fb7fe
History | View | Annotate | Download (3.73 KB)
1 | aafaeabb | Alex Beregszaszi | /*
|
---|---|---|---|
2 | * TTA demuxer
|
||
3 | * Copyright (c) 2006 Alex Beregszaszi
|
||
4 | *
|
||
5 | b78e7197 | Diego Biurrun | * This file is part of FFmpeg.
|
6 | *
|
||
7 | * FFmpeg is free software; you can redistribute it and/or
|
||
8 | aafaeabb | Alex Beregszaszi | * modify it under the terms of the GNU Lesser General Public
|
9 | * License as published by the Free Software Foundation; either
|
||
10 | b78e7197 | Diego Biurrun | * version 2.1 of the License, or (at your option) any later version.
|
11 | aafaeabb | Alex Beregszaszi | *
|
12 | b78e7197 | Diego Biurrun | * FFmpeg is distributed in the hope that it will be useful,
|
13 | aafaeabb | Alex Beregszaszi | * 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.
|
||
16 | *
|
||
17 | * You should have received a copy of the GNU Lesser General Public
|
||
18 | b78e7197 | Diego Biurrun | * License along with FFmpeg; if not, write to the Free Software
|
19 | 538389c9 | Diego Biurrun | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
20 | aafaeabb | Alex Beregszaszi | */
|
21 | #include "avformat.h" |
||
22 | #include "bitstream.h" |
||
23 | |||
24 | typedef struct { |
||
25 | int totalframes, currentframe;
|
||
26 | } TTAContext; |
||
27 | |||
28 | static int tta_probe(AVProbeData *p) |
||
29 | { |
||
30 | const uint8_t *d = p->buf;
|
||
31 | if (d[0] == 'T' && d[1] == 'T' && d[2] == 'A' && d[3] == '1') |
||
32 | return 80; |
||
33 | return 0; |
||
34 | } |
||
35 | |||
36 | static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap) |
||
37 | { |
||
38 | TTAContext *c = s->priv_data; |
||
39 | AVStream *st; |
||
40 | 09a62866 | Michael Niedermayer | int i, channels, bps, samplerate, datalen, framelen;
|
41 | 756fb7fe | David Conrad | uint64_t framepos; |
42 | aafaeabb | Alex Beregszaszi | |
43 | if (get_le32(&s->pb) != ff_get_fourcc("TTA1")) |
||
44 | return -1; // not tta file |
||
45 | |||
46 | url_fskip(&s->pb, 2); // FIXME: flags |
||
47 | channels = get_le16(&s->pb); |
||
48 | bps = get_le16(&s->pb); |
||
49 | samplerate = get_le32(&s->pb); |
||
50 | a443a253 | Michael Niedermayer | if(samplerate <= 0 || samplerate > 1000000){ |
51 | av_log(s, AV_LOG_ERROR, "nonsense samplerate\n");
|
||
52 | return -1; |
||
53 | } |
||
54 | |||
55 | aafaeabb | Alex Beregszaszi | datalen = get_le32(&s->pb); |
56 | a443a253 | Michael Niedermayer | if(datalen < 0){ |
57 | av_log(s, AV_LOG_ERROR, "nonsense datalen\n");
|
||
58 | return -1; |
||
59 | } |
||
60 | |||
61 | aafaeabb | Alex Beregszaszi | url_fskip(&s->pb, 4); // header crc |
62 | |||
63 | dc417a6e | Michael Niedermayer | framelen = samplerate*256/245; |
64 | aafaeabb | Alex Beregszaszi | c->totalframes = datalen / framelen + ((datalen % framelen) ? 1 : 0); |
65 | c->currentframe = 0;
|
||
66 | |||
67 | a443a253 | Michael Niedermayer | if(c->totalframes >= UINT_MAX/sizeof(uint32_t)){ |
68 | av_log(s, AV_LOG_ERROR, "totalframes too large\n");
|
||
69 | return -1; |
||
70 | } |
||
71 | aafaeabb | Alex Beregszaszi | |
72 | st = av_new_stream(s, 0);
|
||
73 | if (!st)
|
||
74 | return AVERROR_NOMEM;
|
||
75 | 756fb7fe | David Conrad | |
76 | av_set_pts_info(st, 64, 1, samplerate); |
||
77 | st->start_time = 0;
|
||
78 | st->duration = datalen; |
||
79 | |||
80 | framepos = url_ftell(&s->pb) + 4*c->totalframes + 4; |
||
81 | |||
82 | for (i = 0; i < c->totalframes; i++) { |
||
83 | uint32_t size = get_le32(&s->pb); |
||
84 | av_add_index_entry(st, framepos, i*framelen, size, 0, AVINDEX_KEYFRAME);
|
||
85 | framepos += size; |
||
86 | } |
||
87 | url_fskip(&s->pb, 4); // seektable crc |
||
88 | |||
89 | aafaeabb | Alex Beregszaszi | st->codec->codec_type = CODEC_TYPE_AUDIO; |
90 | st->codec->codec_id = CODEC_ID_TTA; |
||
91 | st->codec->channels = channels; |
||
92 | st->codec->sample_rate = samplerate; |
||
93 | st->codec->bits_per_sample = bps; |
||
94 | |||
95 | 09a62866 | Michael Niedermayer | st->codec->extradata_size = url_ftell(&s->pb); |
96 | a443a253 | Michael Niedermayer | if(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)st->codec->extradata_size){ |
97 | //this check is redundant as get_buffer should fail
|
||
98 | av_log(s, AV_LOG_ERROR, "extradata_size too large\n");
|
||
99 | return -1; |
||
100 | } |
||
101 | aa11db2f | Alex Beregszaszi | st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); |
102 | 09a62866 | Michael Niedermayer | url_fseek(&s->pb, 0, SEEK_SET);
|
103 | aafaeabb | Alex Beregszaszi | get_buffer(&s->pb, st->codec->extradata, st->codec->extradata_size); |
104 | |||
105 | return 0; |
||
106 | } |
||
107 | |||
108 | static int tta_read_packet(AVFormatContext *s, AVPacket *pkt) |
||
109 | { |
||
110 | TTAContext *c = s->priv_data; |
||
111 | 756fb7fe | David Conrad | AVStream *st = s->streams[0];
|
112 | int size;
|
||
113 | aafaeabb | Alex Beregszaszi | |
114 | // FIXME!
|
||
115 | if (c->currentframe > c->totalframes)
|
||
116 | 756fb7fe | David Conrad | return -1; |
117 | aafaeabb | Alex Beregszaszi | |
118 | 756fb7fe | David Conrad | size = st->index_entries[c->currentframe++].size; |
119 | aafaeabb | Alex Beregszaszi | |
120 | 756fb7fe | David Conrad | return av_get_packet(&s->pb, pkt, size);
|
121 | aafaeabb | Alex Beregszaszi | } |
122 | |||
123 | d2a067d1 | Måns Rullgård | AVInputFormat tta_demuxer = { |
124 | aafaeabb | Alex Beregszaszi | "tta",
|
125 | "true-audio",
|
||
126 | sizeof(TTAContext),
|
||
127 | tta_probe, |
||
128 | tta_read_header, |
||
129 | tta_read_packet, |
||
130 | 756fb7fe | David Conrad | NULL,
|
131 | aafaeabb | Alex Beregszaszi | .extensions = "tta",
|
132 | }; |