Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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_bits8(&gb, buffer, size - 3);
  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. };
  211.