00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavcodec/get_bits.h"
00023 #include "avformat.h"
00024 #include "internal.h"
00025 #include "id3v1.h"
00026 #include "libavutil/dict.h"
00027
00028 typedef struct {
00029 int totalframes, currentframe;
00030 int frame_size;
00031 int last_frame_size;
00032 } TTAContext;
00033
00034 static int tta_probe(AVProbeData *p)
00035 {
00036 const uint8_t *d = p->buf;
00037
00038 if (d[0] == 'T' && d[1] == 'T' && d[2] == 'A' && d[3] == '1')
00039 return 80;
00040 return 0;
00041 }
00042
00043 static int tta_read_header(AVFormatContext *s)
00044 {
00045 TTAContext *c = s->priv_data;
00046 AVStream *st;
00047 int i, channels, bps, samplerate, datalen;
00048 uint64_t framepos, start_offset;
00049
00050 if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
00051 ff_id3v1_read(s);
00052
00053 start_offset = avio_tell(s->pb);
00054 if (avio_rl32(s->pb) != AV_RL32("TTA1"))
00055 return -1;
00056
00057 avio_skip(s->pb, 2);
00058 channels = avio_rl16(s->pb);
00059 bps = avio_rl16(s->pb);
00060 samplerate = avio_rl32(s->pb);
00061 if(samplerate <= 0 || samplerate > 1000000){
00062 av_log(s, AV_LOG_ERROR, "nonsense samplerate\n");
00063 return -1;
00064 }
00065
00066 datalen = avio_rl32(s->pb);
00067 if(datalen < 0){
00068 av_log(s, AV_LOG_ERROR, "nonsense datalen\n");
00069 return -1;
00070 }
00071
00072 avio_skip(s->pb, 4);
00073
00074 c->frame_size = samplerate * 256 / 245;
00075 c->last_frame_size = datalen % c->frame_size;
00076 if (!c->last_frame_size)
00077 c->last_frame_size = c->frame_size;
00078 c->totalframes = datalen / c->frame_size + (c->last_frame_size < c->frame_size);
00079 c->currentframe = 0;
00080
00081 if(c->totalframes >= UINT_MAX/sizeof(uint32_t) || c->totalframes <= 0){
00082 av_log(s, AV_LOG_ERROR, "totalframes %d invalid\n", c->totalframes);
00083 return -1;
00084 }
00085
00086 st = avformat_new_stream(s, NULL);
00087 if (!st)
00088 return AVERROR(ENOMEM);
00089
00090 avpriv_set_pts_info(st, 64, 1, samplerate);
00091 st->start_time = 0;
00092 st->duration = datalen;
00093
00094 framepos = avio_tell(s->pb) + 4*c->totalframes + 4;
00095
00096 for (i = 0; i < c->totalframes; i++) {
00097 uint32_t size = avio_rl32(s->pb);
00098 av_add_index_entry(st, framepos, i * c->frame_size, size, 0,
00099 AVINDEX_KEYFRAME);
00100 framepos += size;
00101 }
00102 avio_skip(s->pb, 4);
00103
00104 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00105 st->codec->codec_id = AV_CODEC_ID_TTA;
00106 st->codec->channels = channels;
00107 st->codec->sample_rate = samplerate;
00108 st->codec->bits_per_coded_sample = bps;
00109
00110 st->codec->extradata_size = avio_tell(s->pb) - start_offset;
00111 if(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)st->codec->extradata_size){
00112
00113 av_log(s, AV_LOG_ERROR, "extradata_size too large\n");
00114 return -1;
00115 }
00116 st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE);
00117 if (!st->codec->extradata) {
00118 st->codec->extradata_size = 0;
00119 return AVERROR(ENOMEM);
00120 }
00121 avio_seek(s->pb, start_offset, SEEK_SET);
00122 avio_read(s->pb, st->codec->extradata, st->codec->extradata_size);
00123
00124 return 0;
00125 }
00126
00127 static int tta_read_packet(AVFormatContext *s, AVPacket *pkt)
00128 {
00129 TTAContext *c = s->priv_data;
00130 AVStream *st = s->streams[0];
00131 int size, ret;
00132
00133
00134 if (c->currentframe >= c->totalframes)
00135 return AVERROR_EOF;
00136
00137 size = st->index_entries[c->currentframe].size;
00138
00139 ret = av_get_packet(s->pb, pkt, size);
00140 pkt->dts = st->index_entries[c->currentframe++].timestamp;
00141 pkt->duration = c->currentframe == c->totalframes ? c->last_frame_size :
00142 c->frame_size;
00143 return ret;
00144 }
00145
00146 static int tta_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
00147 {
00148 TTAContext *c = s->priv_data;
00149 AVStream *st = s->streams[stream_index];
00150 int index = av_index_search_timestamp(st, timestamp, flags);
00151 if (index < 0)
00152 return -1;
00153 if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0)
00154 return -1;
00155
00156 c->currentframe = index;
00157
00158 return 0;
00159 }
00160
00161 AVInputFormat ff_tta_demuxer = {
00162 .name = "tta",
00163 .long_name = NULL_IF_CONFIG_SMALL("TTA (True Audio)"),
00164 .priv_data_size = sizeof(TTAContext),
00165 .read_probe = tta_probe,
00166 .read_header = tta_read_header,
00167 .read_packet = tta_read_packet,
00168 .read_seek = tta_read_seek,
00169 .extensions = "tta",
00170 };