]> git.sesse.net Git - ffmpeg/blob - libavformat/takdec.c
Merge commit '69caad8959982580504643d36aef22528e4aa6ce'
[ffmpeg] / libavformat / takdec.c
1 /*
2  * Raw TAK demuxer
3  * Copyright (c) 2012 Paul B Mahol
4  *
5  * This file is part of FFmpeg.
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #include "libavutil/crc.h"
23
24 #define BITSTREAM_READER_LE
25 #include "libavcodec/tak.h"
26
27 #include "apetag.h"
28 #include "avformat.h"
29 #include "avio_internal.h"
30 #include "internal.h"
31 #include "rawdec.h"
32
33 typedef struct TAKDemuxContext {
34     int     mlast_frame;
35     int64_t data_end;
36 } TAKDemuxContext;
37
38 static int tak_probe(AVProbeData *p)
39 {
40     if (!memcmp(p->buf, "tBaK", 4))
41         return AVPROBE_SCORE_EXTENSION;
42     return 0;
43 }
44
45 static unsigned long tak_check_crc(unsigned long checksum, const uint8_t *buf,
46                                    unsigned int len)
47 {
48     return av_crc(av_crc_get_table(AV_CRC_24_IEEE), checksum, buf, len);
49 }
50
51 static int tak_read_header(AVFormatContext *s)
52 {
53     TAKDemuxContext *tc = s->priv_data;
54     AVIOContext *pb     = s->pb;
55     GetBitContext gb;
56     AVStream *st;
57     uint8_t *buffer = NULL;
58     int ret;
59
60     st = avformat_new_stream(s, 0);
61     if (!st)
62         return AVERROR(ENOMEM);
63
64     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
65     st->codecpar->codec_id   = AV_CODEC_ID_TAK;
66     st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
67
68     tc->mlast_frame = 0;
69     if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) {
70         avio_seek(pb, -4, SEEK_CUR);
71         return 0;
72     }
73
74     while (!avio_feof(pb)) {
75         enum TAKMetaDataType type;
76         int size;
77
78         type = avio_r8(pb) & 0x7f;
79         size = avio_rl24(pb);
80
81         switch (type) {
82         case TAK_METADATA_STREAMINFO:
83         case TAK_METADATA_LAST_FRAME:
84         case TAK_METADATA_ENCODER:
85             if (size <= 3)
86                 return AVERROR_INVALIDDATA;
87
88             buffer = av_malloc(size - 3 + AV_INPUT_BUFFER_PADDING_SIZE);
89             if (!buffer)
90                 return AVERROR(ENOMEM);
91             memset(buffer + size - 3, 0, AV_INPUT_BUFFER_PADDING_SIZE);
92
93             ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
94             if (avio_read(pb, buffer, size - 3) != size - 3) {
95                 av_freep(&buffer);
96                 return AVERROR(EIO);
97             }
98             if (ffio_get_checksum(s->pb) != avio_rb24(pb)) {
99                 av_log(s, AV_LOG_ERROR, "%d metadata block CRC error.\n", type);
100                 if (s->error_recognition & AV_EF_EXPLODE) {
101                     av_freep(&buffer);
102                     return AVERROR_INVALIDDATA;
103                 }
104             }
105
106             break;
107         case TAK_METADATA_MD5: {
108             uint8_t md5[16];
109             int i;
110
111             if (size != 19)
112                 return AVERROR_INVALIDDATA;
113             ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
114             avio_read(pb, md5, 16);
115             if (ffio_get_checksum(s->pb) != avio_rb24(pb)) {
116                 av_log(s, AV_LOG_ERROR, "MD5 metadata block CRC error.\n");
117                 if (s->error_recognition & AV_EF_EXPLODE)
118                     return AVERROR_INVALIDDATA;
119             }
120
121             av_log(s, AV_LOG_VERBOSE, "MD5=");
122             for (i = 0; i < 16; i++)
123                 av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]);
124             av_log(s, AV_LOG_VERBOSE, "\n");
125             break;
126         }
127         case TAK_METADATA_END: {
128             int64_t curpos = avio_tell(pb);
129
130             if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
131                 ff_ape_parse_tag(s);
132                 avio_seek(pb, curpos, SEEK_SET);
133             }
134
135             tc->data_end += curpos;
136             return 0;
137         }
138         default:
139             ret = avio_skip(pb, size);
140             if (ret < 0)
141                 return ret;
142         }
143
144         if (type == TAK_METADATA_STREAMINFO) {
145             TAKStreamInfo ti;
146
147             ret = avpriv_tak_parse_streaminfo(&ti, buffer, size -3);
148             if (ret < 0)
149                 return AVERROR_INVALIDDATA;
150             if (ti.samples > 0)
151                 st->duration = ti.samples;
152             st->codecpar->bits_per_coded_sample = ti.bps;
153             if (ti.ch_layout)
154                 st->codecpar->channel_layout = ti.ch_layout;
155             st->codecpar->sample_rate           = ti.sample_rate;
156             st->codecpar->channels              = ti.channels;
157             st->start_time                   = 0;
158             avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
159             st->codecpar->extradata             = buffer;
160             st->codecpar->extradata_size        = size - 3;
161             buffer                           = NULL;
162         } else if (type == TAK_METADATA_LAST_FRAME) {
163             if (size != 11)
164                 return AVERROR_INVALIDDATA;
165             init_get_bits8(&gb, buffer, size - 3);
166             tc->mlast_frame = 1;
167             tc->data_end    = get_bits64(&gb, TAK_LAST_FRAME_POS_BITS) +
168                               get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS);
169             av_freep(&buffer);
170         } else if (type == TAK_METADATA_ENCODER) {
171             init_get_bits8(&gb, buffer, size - 3);
172             av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n",
173                    get_bits_long(&gb, TAK_ENCODER_VERSION_BITS));
174             av_freep(&buffer);
175         }
176     }
177
178     return AVERROR_EOF;
179 }
180
181 static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
182 {
183     TAKDemuxContext *tc = s->priv_data;
184     int ret;
185
186     if (tc->mlast_frame) {
187         AVIOContext *pb = s->pb;
188         int64_t size, left;
189
190         left = tc->data_end - avio_tell(pb);
191         size = FFMIN(left, 1024);
192         if (size <= 0)
193             return AVERROR_EOF;
194
195         ret = av_get_packet(pb, pkt, size);
196         if (ret < 0)
197             return ret;
198
199         pkt->stream_index = 0;
200     } else {
201         ret = ff_raw_read_partial_packet(s, pkt);
202     }
203
204     return ret;
205 }
206
207 AVInputFormat ff_tak_demuxer = {
208     .name           = "tak",
209     .long_name      = NULL_IF_CONFIG_SMALL("raw TAK"),
210     .priv_data_size = sizeof(TAKDemuxContext),
211     .read_probe     = tak_probe,
212     .read_header    = tak_read_header,
213     .read_packet    = raw_read_packet,
214     .flags          = AVFMT_GENERIC_INDEX,
215     .extensions     = "tak",
216     .raw_codec_id   = AV_CODEC_ID_TAK,
217 };