00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavcodec/tak.h"
00023 #include "avformat.h"
00024 #include "internal.h"
00025 #include "rawdec.h"
00026 #include "apetag.h"
00027
00028 typedef struct TAKDemuxContext {
00029 int mlast_frame;
00030 int64_t data_end;
00031 } TAKDemuxContext;
00032
00033 static int tak_probe(AVProbeData *p)
00034 {
00035 if (!memcmp(p->buf, "tBaK", 4))
00036 return AVPROBE_SCORE_MAX / 2;
00037 return 0;
00038 }
00039
00040 static int tak_read_header(AVFormatContext *s)
00041 {
00042 TAKDemuxContext *tc = s->priv_data;
00043 AVIOContext *pb = s->pb;
00044 GetBitContext gb;
00045 AVStream *st;
00046 uint8_t *buffer = NULL;
00047 int ret;
00048
00049 st = avformat_new_stream(s, 0);
00050 if (!st)
00051 return AVERROR(ENOMEM);
00052
00053 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00054 st->codec->codec_id = AV_CODEC_ID_TAK;
00055 st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
00056
00057 tc->mlast_frame = 0;
00058 if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) {
00059 avio_seek(pb, -4, SEEK_CUR);
00060 return 0;
00061 }
00062
00063 while (!url_feof(pb)) {
00064 enum TAKMetaDataType type;
00065 int size;
00066
00067 type = avio_r8(pb) & 0x7f;
00068 size = avio_rl24(pb);
00069
00070 switch (type) {
00071 case TAK_METADATA_STREAMINFO:
00072 case TAK_METADATA_LAST_FRAME:
00073 case TAK_METADATA_ENCODER:
00074 buffer = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
00075 if (!buffer)
00076 return AVERROR(ENOMEM);
00077
00078 if (avio_read(pb, buffer, size) != size) {
00079 av_freep(&buffer);
00080 return AVERROR(EIO);
00081 }
00082
00083 init_get_bits(&gb, buffer, size * 8);
00084 break;
00085 case TAK_METADATA_MD5: {
00086 uint8_t md5[16];
00087 int i;
00088
00089 if (size != 19)
00090 return AVERROR_INVALIDDATA;
00091 avio_read(pb, md5, 16);
00092 avio_skip(pb, 3);
00093 av_log(s, AV_LOG_VERBOSE, "MD5=");
00094 for (i = 0; i < 16; i++)
00095 av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]);
00096 av_log(s, AV_LOG_VERBOSE, "\n");
00097 break;
00098 }
00099 case TAK_METADATA_END: {
00100 int64_t curpos = avio_tell(pb);
00101
00102 if (pb->seekable) {
00103 ff_ape_parse_tag(s);
00104 avio_seek(pb, curpos, SEEK_SET);
00105 }
00106
00107 tc->data_end += curpos;
00108 return 0;
00109 }
00110 default:
00111 ret = avio_skip(pb, size);
00112 if (ret < 0)
00113 return ret;
00114 }
00115
00116 if (type == TAK_METADATA_STREAMINFO) {
00117 TAKStreamInfo ti;
00118
00119 avpriv_tak_parse_streaminfo(&gb, &ti);
00120 if (ti.samples > 0)
00121 st->duration = ti.samples;
00122 st->codec->bits_per_coded_sample = ti.bps;
00123 if (ti.ch_layout)
00124 st->codec->channel_layout = ti.ch_layout;
00125 st->codec->sample_rate = ti.sample_rate;
00126 st->codec->channels = ti.channels;
00127 st->start_time = 0;
00128 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
00129 st->codec->extradata = buffer;
00130 st->codec->extradata_size = size;
00131 buffer = NULL;
00132 } else if (type == TAK_METADATA_LAST_FRAME) {
00133 if (size != 11)
00134 return AVERROR_INVALIDDATA;
00135 tc->mlast_frame = 1;
00136 tc->data_end = get_bits64(&gb, TAK_LAST_FRAME_POS_BITS) +
00137 get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS);
00138 av_freep(&buffer);
00139 } else if (type == TAK_METADATA_ENCODER) {
00140 av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n",
00141 get_bits_long(&gb, TAK_ENCODER_VERSION_BITS));
00142 av_freep(&buffer);
00143 }
00144 }
00145
00146 return AVERROR_EOF;
00147 }
00148
00149 static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
00150 {
00151 TAKDemuxContext *tc = s->priv_data;
00152 int ret;
00153
00154 if (tc->mlast_frame) {
00155 AVIOContext *pb = s->pb;
00156 int64_t size, left;
00157
00158 left = tc->data_end - avio_tell(s->pb);
00159 size = FFMIN(left, 1024);
00160 if (size <= 0)
00161 return AVERROR_EOF;
00162
00163 ret = av_get_packet(pb, pkt, size);
00164 if (ret < 0)
00165 return ret;
00166
00167 pkt->stream_index = 0;
00168 } else {
00169 ret = ff_raw_read_partial_packet(s, pkt);
00170 }
00171
00172 return ret;
00173 }
00174
00175 AVInputFormat ff_tak_demuxer = {
00176 .name = "tak",
00177 .long_name = NULL_IF_CONFIG_SMALL("raw TAK"),
00178 .priv_data_size = sizeof(TAKDemuxContext),
00179 .read_probe = tak_probe,
00180 .read_header = tak_read_header,
00181 .read_packet = raw_read_packet,
00182 .flags = AVFMT_GENERIC_INDEX,
00183 .extensions = "tak",
00184 .raw_codec_id = AV_CODEC_ID_TAK,
00185 };