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