3eb1a8ec2d40185c4ea2955c0d17d4daf94dfcf5
[platform/framework/web/crosswalk.git] / src / third_party / 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 #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 (!avio_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             memset(buffer + size - 3, 0, FF_INPUT_BUFFER_PADDING_SIZE);
89
90             ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
91             if (avio_read(pb, buffer, size - 3) != size - 3) {
92                 av_freep(&buffer);
93                 return AVERROR(EIO);
94             }
95             if (ffio_get_checksum(s->pb) != avio_rb24(pb)) {
96                 av_log(s, AV_LOG_ERROR, "%d metadata block CRC error.\n", type);
97                 if (s->error_recognition & AV_EF_EXPLODE) {
98                     av_freep(&buffer);
99                     return AVERROR_INVALIDDATA;
100                 }
101             }
102
103             init_get_bits8(&gb, buffer, size - 3);
104             break;
105         case TAK_METADATA_MD5: {
106             uint8_t md5[16];
107             int i;
108
109             if (size != 19)
110                 return AVERROR_INVALIDDATA;
111             ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
112             avio_read(pb, md5, 16);
113             if (ffio_get_checksum(s->pb) != avio_rb24(pb)) {
114                 av_log(s, AV_LOG_ERROR, "MD5 metadata block CRC error.\n");
115                 if (s->error_recognition & AV_EF_EXPLODE)
116                     return AVERROR_INVALIDDATA;
117             }
118
119             av_log(s, AV_LOG_VERBOSE, "MD5=");
120             for (i = 0; i < 16; i++)
121                 av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]);
122             av_log(s, AV_LOG_VERBOSE, "\n");
123             break;
124         }
125         case TAK_METADATA_END: {
126             int64_t curpos = avio_tell(pb);
127
128             if (pb->seekable) {
129                 ff_ape_parse_tag(s);
130                 avio_seek(pb, curpos, SEEK_SET);
131             }
132
133             tc->data_end += curpos;
134             return 0;
135         }
136         default:
137             ret = avio_skip(pb, size);
138             if (ret < 0)
139                 return ret;
140         }
141
142         if (type == TAK_METADATA_STREAMINFO) {
143             TAKStreamInfo ti;
144
145             avpriv_tak_parse_streaminfo(&gb, &ti);
146             if (ti.samples > 0)
147                 st->duration = ti.samples;
148             st->codec->bits_per_coded_sample = ti.bps;
149             if (ti.ch_layout)
150                 st->codec->channel_layout = ti.ch_layout;
151             st->codec->sample_rate           = ti.sample_rate;
152             st->codec->channels              = ti.channels;
153             st->start_time                   = 0;
154             avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
155             st->codec->extradata             = buffer;
156             st->codec->extradata_size        = size - 3;
157             buffer                           = NULL;
158         } else if (type == TAK_METADATA_LAST_FRAME) {
159             if (size != 11)
160                 return AVERROR_INVALIDDATA;
161             tc->mlast_frame = 1;
162             tc->data_end    = get_bits64(&gb, TAK_LAST_FRAME_POS_BITS) +
163                               get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS);
164             av_freep(&buffer);
165         } else if (type == TAK_METADATA_ENCODER) {
166             av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n",
167                    get_bits_long(&gb, TAK_ENCODER_VERSION_BITS));
168             av_freep(&buffer);
169         }
170     }
171
172     return AVERROR_EOF;
173 }
174
175 static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
176 {
177     TAKDemuxContext *tc = s->priv_data;
178     int ret;
179
180     if (tc->mlast_frame) {
181         AVIOContext *pb = s->pb;
182         int64_t size, left;
183
184         left = tc->data_end - avio_tell(pb);
185         size = FFMIN(left, 1024);
186         if (size <= 0)
187             return AVERROR_EOF;
188
189         ret = av_get_packet(pb, pkt, size);
190         if (ret < 0)
191             return ret;
192
193         pkt->stream_index = 0;
194     } else {
195         ret = ff_raw_read_partial_packet(s, pkt);
196     }
197
198     return ret;
199 }
200
201 AVInputFormat ff_tak_demuxer = {
202     .name           = "tak",
203     .long_name      = NULL_IF_CONFIG_SMALL("raw TAK"),
204     .priv_data_size = sizeof(TAKDemuxContext),
205     .read_probe     = tak_probe,
206     .read_header    = tak_read_header,
207     .read_packet    = raw_read_packet,
208     .flags          = AVFMT_GENERIC_INDEX,
209     .extensions     = "tak",
210     .raw_codec_id   = AV_CODEC_ID_TAK,
211 };