Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * VQF demuxer
  3.  * Copyright (c) 2009 Vitor Sessak
  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 "avformat.h"
  23. #include "internal.h"
  24. #include "libavutil/intreadwrite.h"
  25. #include "libavutil/dict.h"
  26. #include "libavutil/mathematics.h"
  27. #include "riff.h"
  28.  
  29. typedef struct VqfContext {
  30.     int frame_bit_len;
  31.     uint8_t last_frame_bits;
  32.     int remaining_bits;
  33. } VqfContext;
  34.  
  35. static int vqf_probe(AVProbeData *probe_packet)
  36. {
  37.     if (AV_RL32(probe_packet->buf) != MKTAG('T','W','I','N'))
  38.         return 0;
  39.  
  40.     if (!memcmp(probe_packet->buf + 4, "97012000", 8))
  41.         return AVPROBE_SCORE_MAX;
  42.  
  43.     if (!memcmp(probe_packet->buf + 4, "00052200", 8))
  44.         return AVPROBE_SCORE_MAX;
  45.  
  46.     return AVPROBE_SCORE_EXTENSION;
  47. }
  48.  
  49. static void add_metadata(AVFormatContext *s, uint32_t tag,
  50.                          unsigned int tag_len, unsigned int remaining)
  51. {
  52.     int len = FFMIN(tag_len, remaining);
  53.     char *buf, key[5] = {0};
  54.  
  55.     if (len == UINT_MAX)
  56.         return;
  57.  
  58.     buf = av_malloc(len+1);
  59.     if (!buf)
  60.         return;
  61.     avio_read(s->pb, buf, len);
  62.     buf[len] = 0;
  63.     AV_WL32(key, tag);
  64.     av_dict_set(&s->metadata, key, buf, AV_DICT_DONT_STRDUP_VAL);
  65. }
  66.  
  67. static const AVMetadataConv vqf_metadata_conv[] = {
  68.     { "(c) ", "copyright" },
  69.     { "ARNG", "arranger"  },
  70.     { "AUTH", "author"    },
  71.     { "BAND", "band"      },
  72.     { "CDCT", "conductor" },
  73.     { "COMT", "comment"   },
  74.     { "FILE", "filename"  },
  75.     { "GENR", "genre"     },
  76.     { "LABL", "publisher" },
  77.     { "MUSC", "composer"  },
  78.     { "NAME", "title"     },
  79.     { "NOTE", "note"      },
  80.     { "PROD", "producer"  },
  81.     { "PRSN", "personnel" },
  82.     { "REMX", "remixer"   },
  83.     { "SING", "singer"    },
  84.     { "TRCK", "track"     },
  85.     { "WORD", "words"     },
  86.     { 0 },
  87. };
  88.  
  89. static int vqf_read_header(AVFormatContext *s)
  90. {
  91.     VqfContext *c = s->priv_data;
  92.     AVStream *st  = avformat_new_stream(s, NULL);
  93.     int chunk_tag;
  94.     int rate_flag = -1;
  95.     int header_size;
  96.     int read_bitrate = 0;
  97.     int size;
  98.     uint8_t comm_chunk[12];
  99.  
  100.     if (!st)
  101.         return AVERROR(ENOMEM);
  102.  
  103.     avio_skip(s->pb, 12);
  104.  
  105.     header_size = avio_rb32(s->pb);
  106.  
  107.     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
  108.     st->codec->codec_id   = AV_CODEC_ID_TWINVQ;
  109.     st->start_time = 0;
  110.  
  111.     do {
  112.         int len;
  113.         chunk_tag = avio_rl32(s->pb);
  114.  
  115.         if (chunk_tag == MKTAG('D','A','T','A'))
  116.             break;
  117.  
  118.         len = avio_rb32(s->pb);
  119.  
  120.         if ((unsigned) len > INT_MAX/2) {
  121.             av_log(s, AV_LOG_ERROR, "Malformed header\n");
  122.             return -1;
  123.         }
  124.  
  125.         header_size -= 8;
  126.  
  127.         switch(chunk_tag){
  128.         case MKTAG('C','O','M','M'):
  129.             avio_read(s->pb, comm_chunk, 12);
  130.             st->codec->channels = AV_RB32(comm_chunk    ) + 1;
  131.             read_bitrate        = AV_RB32(comm_chunk + 4);
  132.             rate_flag           = AV_RB32(comm_chunk + 8);
  133.             avio_skip(s->pb, len-12);
  134.  
  135.             if (st->codec->channels <= 0) {
  136.                 av_log(s, AV_LOG_ERROR, "Invalid number of channels\n");
  137.                 return AVERROR_INVALIDDATA;
  138.             }
  139.  
  140.             st->codec->bit_rate              = read_bitrate*1000;
  141.             break;
  142.         case MKTAG('D','S','I','Z'): // size of compressed data
  143.         {
  144.             char buf[8] = {0};
  145.             int size = avio_rb32(s->pb);
  146.  
  147.             snprintf(buf, sizeof(buf), "%d", size);
  148.             av_dict_set(&s->metadata, "size", buf, 0);
  149.         }
  150.             break;
  151.         case MKTAG('Y','E','A','R'): // recording date
  152.         case MKTAG('E','N','C','D'): // compression date
  153.         case MKTAG('E','X','T','R'): // reserved
  154.         case MKTAG('_','Y','M','H'): // reserved
  155.         case MKTAG('_','N','T','T'): // reserved
  156.         case MKTAG('_','I','D','3'): // reserved for ID3 tags
  157.             avio_skip(s->pb, FFMIN(len, header_size));
  158.             break;
  159.         default:
  160.             add_metadata(s, chunk_tag, len, header_size);
  161.             break;
  162.         }
  163.  
  164.         header_size -= len;
  165.  
  166.     } while (header_size >= 0 && !url_feof(s->pb));
  167.  
  168.     switch (rate_flag) {
  169.     case -1:
  170.         av_log(s, AV_LOG_ERROR, "COMM tag not found!\n");
  171.         return -1;
  172.     case 44:
  173.         st->codec->sample_rate = 44100;
  174.         break;
  175.     case 22:
  176.         st->codec->sample_rate = 22050;
  177.         break;
  178.     case 11:
  179.         st->codec->sample_rate = 11025;
  180.         break;
  181.     default:
  182.         if (rate_flag < 8 || rate_flag > 44) {
  183.             av_log(s, AV_LOG_ERROR, "Invalid rate flag %d\n", rate_flag);
  184.             return AVERROR_INVALIDDATA;
  185.         }
  186.         st->codec->sample_rate = rate_flag*1000;
  187.         break;
  188.     }
  189.  
  190.     if (read_bitrate / st->codec->channels <  8 ||
  191.         read_bitrate / st->codec->channels > 48) {
  192.         av_log(s, AV_LOG_ERROR, "Invalid bitrate per channel %d\n",
  193.                read_bitrate / st->codec->channels);
  194.         return AVERROR_INVALIDDATA;
  195.     }
  196.  
  197.     switch (((st->codec->sample_rate/1000) << 8) +
  198.             read_bitrate/st->codec->channels) {
  199.     case (11<<8) + 8 :
  200.     case (8 <<8) + 8 :
  201.     case (11<<8) + 10:
  202.     case (22<<8) + 32:
  203.         size = 512;
  204.         break;
  205.     case (16<<8) + 16:
  206.     case (22<<8) + 20:
  207.     case (22<<8) + 24:
  208.         size = 1024;
  209.         break;
  210.     case (44<<8) + 40:
  211.     case (44<<8) + 48:
  212.         size = 2048;
  213.         break;
  214.     default:
  215.         av_log(s, AV_LOG_ERROR, "Mode not suported: %d Hz, %d kb/s.\n",
  216.                st->codec->sample_rate, st->codec->bit_rate);
  217.         return -1;
  218.     }
  219.     c->frame_bit_len = st->codec->bit_rate*size/st->codec->sample_rate;
  220.     avpriv_set_pts_info(st, 64, size, st->codec->sample_rate);
  221.  
  222.     /* put first 12 bytes of COMM chunk in extradata */
  223.     if (ff_alloc_extradata(st->codec, 12))
  224.         return AVERROR(ENOMEM);
  225.     memcpy(st->codec->extradata, comm_chunk, 12);
  226.  
  227.     ff_metadata_conv_ctx(s, NULL, vqf_metadata_conv);
  228.  
  229.     return 0;
  230. }
  231.  
  232. static int vqf_read_packet(AVFormatContext *s, AVPacket *pkt)
  233. {
  234.     VqfContext *c = s->priv_data;
  235.     int ret;
  236.     int size = (c->frame_bit_len - c->remaining_bits + 7)>>3;
  237.  
  238.     if (av_new_packet(pkt, size+2) < 0)
  239.         return AVERROR(EIO);
  240.  
  241.     pkt->pos          = avio_tell(s->pb);
  242.     pkt->stream_index = 0;
  243.     pkt->duration     = 1;
  244.  
  245.     pkt->data[0] = 8 - c->remaining_bits; // Number of bits to skip
  246.     pkt->data[1] = c->last_frame_bits;
  247.     ret = avio_read(s->pb, pkt->data+2, size);
  248.  
  249.     if (ret<=0) {
  250.         av_free_packet(pkt);
  251.         return AVERROR(EIO);
  252.     }
  253.  
  254.     c->last_frame_bits = pkt->data[size+1];
  255.     c->remaining_bits  = (size << 3) - c->frame_bit_len + c->remaining_bits;
  256.  
  257.     return size+2;
  258. }
  259.  
  260. static int vqf_read_seek(AVFormatContext *s,
  261.                          int stream_index, int64_t timestamp, int flags)
  262. {
  263.     VqfContext *c = s->priv_data;
  264.     AVStream *st;
  265.     int ret;
  266.     int64_t pos;
  267.  
  268.     st = s->streams[stream_index];
  269.     pos = av_rescale_rnd(timestamp * st->codec->bit_rate,
  270.                          st->time_base.num,
  271.                          st->time_base.den * (int64_t)c->frame_bit_len,
  272.                          (flags & AVSEEK_FLAG_BACKWARD) ?
  273.                                                    AV_ROUND_DOWN : AV_ROUND_UP);
  274.     pos *= c->frame_bit_len;
  275.  
  276.     st->cur_dts = av_rescale(pos, st->time_base.den,
  277.                              st->codec->bit_rate * (int64_t)st->time_base.num);
  278.  
  279.     if ((ret = avio_seek(s->pb, ((pos-7) >> 3) + s->data_offset, SEEK_SET)) < 0)
  280.         return ret;
  281.  
  282.     c->remaining_bits = -7 - ((pos-7)&7);
  283.     return 0;
  284. }
  285.  
  286. AVInputFormat ff_vqf_demuxer = {
  287.     .name           = "vqf",
  288.     .long_name      = NULL_IF_CONFIG_SMALL("Nippon Telegraph and Telephone Corporation (NTT) TwinVQ"),
  289.     .priv_data_size = sizeof(VqfContext),
  290.     .read_probe     = vqf_probe,
  291.     .read_header    = vqf_read_header,
  292.     .read_packet    = vqf_read_packet,
  293.     .read_seek      = vqf_read_seek,
  294.     .extensions     = "vqf,vql,vqe",
  295. };
  296.