3 * Copyright (c) 2006 Alex Beregszaszi
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
22 #include "libavcodec/bitstream.h"
26 int totalframes
, currentframe
;
29 static int tta_probe(AVProbeData
*p
)
31 const uint8_t *d
= p
->buf
;
32 if (d
[0] == 'T' && d
[1] == 'T' && d
[2] == 'A' && d
[3] == '1')
37 static int tta_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
39 TTAContext
*c
= s
->priv_data
;
41 int i
, channels
, bps
, samplerate
, datalen
, framelen
;
44 if (get_le32(s
->pb
) != ff_get_fourcc("TTA1"))
45 return -1; // not tta file
47 url_fskip(s
->pb
, 2); // FIXME: flags
48 channels
= get_le16(s
->pb
);
49 bps
= get_le16(s
->pb
);
50 samplerate
= get_le32(s
->pb
);
51 if(samplerate
<= 0 || samplerate
> 1000000){
52 av_log(s
, AV_LOG_ERROR
, "nonsense samplerate\n");
56 datalen
= get_le32(s
->pb
);
58 av_log(s
, AV_LOG_ERROR
, "nonsense datalen\n");
62 url_fskip(s
->pb
, 4); // header crc
64 framelen
= samplerate
*256/245;
65 c
->totalframes
= datalen
/ framelen
+ ((datalen
% framelen
) ? 1 : 0);
68 if(c
->totalframes
>= UINT_MAX
/sizeof(uint32_t)){
69 av_log(s
, AV_LOG_ERROR
, "totalframes too large\n");
73 st
= av_new_stream(s
, 0);
75 return AVERROR(ENOMEM
);
77 av_set_pts_info(st
, 64, 1, samplerate
);
79 st
->duration
= datalen
;
81 framepos
= url_ftell(s
->pb
) + 4*c
->totalframes
+ 4;
83 for (i
= 0; i
< c
->totalframes
; i
++) {
84 uint32_t size
= get_le32(s
->pb
);
85 av_add_index_entry(st
, framepos
, i
*framelen
, size
, 0, AVINDEX_KEYFRAME
);
88 url_fskip(s
->pb
, 4); // seektable crc
90 st
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
91 st
->codec
->codec_id
= CODEC_ID_TTA
;
92 st
->codec
->channels
= channels
;
93 st
->codec
->sample_rate
= samplerate
;
94 st
->codec
->bits_per_sample
= bps
;
96 st
->codec
->extradata_size
= url_ftell(s
->pb
);
97 if(st
->codec
->extradata_size
+FF_INPUT_BUFFER_PADDING_SIZE
<= (unsigned)st
->codec
->extradata_size
){
98 //this check is redundant as get_buffer should fail
99 av_log(s
, AV_LOG_ERROR
, "extradata_size too large\n");
102 st
->codec
->extradata
= av_mallocz(st
->codec
->extradata_size
+FF_INPUT_BUFFER_PADDING_SIZE
);
103 url_fseek(s
->pb
, 0, SEEK_SET
);
104 get_buffer(s
->pb
, st
->codec
->extradata
, st
->codec
->extradata_size
);
109 static int tta_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
111 TTAContext
*c
= s
->priv_data
;
112 AVStream
*st
= s
->streams
[0];
116 if (c
->currentframe
> c
->totalframes
)
119 size
= st
->index_entries
[c
->currentframe
].size
;
121 ret
= av_get_packet(s
->pb
, pkt
, size
);
122 pkt
->dts
= st
->index_entries
[c
->currentframe
++].timestamp
;
126 static int tta_read_seek(AVFormatContext
*s
, int stream_index
, int64_t timestamp
, int flags
)
128 TTAContext
*c
= s
->priv_data
;
129 AVStream
*st
= s
->streams
[stream_index
];
130 int index
= av_index_search_timestamp(st
, timestamp
, flags
);
134 c
->currentframe
= index
;
135 url_fseek(s
->pb
, st
->index_entries
[index
].pos
, SEEK_SET
);
140 AVInputFormat tta_demuxer
= {