Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Raw DTS-HD 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/intreadwrite.h"
  23. #include "libavutil/dict.h"
  24. #include "avformat.h"
  25.  
  26. #define AUPR_HDR 0x415550522D484452
  27. #define AUPRINFO 0x41555052494E464F
  28. #define BITSHVTB 0x4249545348565442
  29. #define BLACKOUT 0x424C41434B4F5554
  30. #define BRANCHPT 0x4252414E43485054
  31. #define BUILDVER 0x4255494C44564552
  32. #define CORESSMD 0x434F524553534D44
  33. #define DTSHDHDR 0x4454534844484452
  34. #define EXTSS_MD 0x45585453535f4d44
  35. #define FILEINFO 0x46494C45494E464F
  36. #define NAVI_TBL 0x4E4156492D54424C
  37. #define STRMDATA 0x5354524D44415441
  38. #define TIMECODE 0x54494D45434F4445
  39.  
  40. typedef struct DTSHDDemuxContext {
  41.     uint64_t    data_end;
  42. } DTSHDDemuxContext;
  43.  
  44. static int dtshd_probe(AVProbeData *p)
  45. {
  46.     if (AV_RB64(p->buf) == DTSHDHDR)
  47.         return AVPROBE_SCORE_MAX;
  48.     return 0;
  49. }
  50.  
  51. static int dtshd_read_header(AVFormatContext *s)
  52. {
  53.     DTSHDDemuxContext *dtshd = s->priv_data;
  54.     AVIOContext *pb = s->pb;
  55.     uint64_t chunk_type, chunk_size;
  56.     AVStream *st;
  57.     int ret;
  58.     char *value;
  59.  
  60.     st = avformat_new_stream(s, NULL);
  61.     if (!st)
  62.         return AVERROR(ENOMEM);
  63.     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
  64.     st->codec->codec_id   = AV_CODEC_ID_DTS;
  65.     st->need_parsing      = AVSTREAM_PARSE_FULL_RAW;
  66.  
  67.     while (!url_feof(pb)) {
  68.         chunk_type = avio_rb64(pb);
  69.         chunk_size = avio_rb64(pb);
  70.  
  71.         if (chunk_size < 4) {
  72.             av_log(s, AV_LOG_ERROR, "chunk size too small\n");
  73.             return AVERROR_INVALIDDATA;
  74.         }
  75.         if (chunk_size > ((uint64_t)1 << 61)) {
  76.             av_log(s, AV_LOG_ERROR, "chunk size too big\n");
  77.             return AVERROR_INVALIDDATA;
  78.         }
  79.  
  80.         switch (chunk_type) {
  81.         case STRMDATA:
  82.             dtshd->data_end = chunk_size + avio_tell(pb);
  83.             if (dtshd->data_end <= chunk_size)
  84.                 return AVERROR_INVALIDDATA;
  85.             return 0;
  86.             break;
  87.         case FILEINFO:
  88.             if (chunk_size > INT_MAX)
  89.                 goto skip;
  90.             value = av_malloc(chunk_size);
  91.             if (!value)
  92.                 goto skip;
  93.             avio_read(pb, value, chunk_size);
  94.             value[chunk_size - 1] = 0;
  95.             av_dict_set(&s->metadata, "fileinfo", value,
  96.                         AV_DICT_DONT_STRDUP_VAL);
  97.             break;
  98.         default:
  99. skip:
  100.             ret = avio_skip(pb, chunk_size);
  101.             if (ret < 0)
  102.                 return ret;
  103.         };
  104.     }
  105.  
  106.     return AVERROR_EOF;
  107. }
  108.  
  109. static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
  110. {
  111.     DTSHDDemuxContext *dtshd = s->priv_data;
  112.     int64_t size, left;
  113.     int ret;
  114.  
  115.     left = dtshd->data_end - avio_tell(s->pb);
  116.     size = FFMIN(left, 1024);
  117.     if (size <= 0)
  118.         return AVERROR_EOF;
  119.  
  120.     ret = av_get_packet(s->pb, pkt, size);
  121.     if (ret < 0)
  122.         return ret;
  123.  
  124.     pkt->stream_index = 0;
  125.  
  126.     return ret;
  127. }
  128.  
  129. AVInputFormat ff_dtshd_demuxer = {
  130.     .name           = "dtshd",
  131.     .long_name      = NULL_IF_CONFIG_SMALL("raw DTS-HD"),
  132.     .priv_data_size = sizeof(DTSHDDemuxContext),
  133.     .read_probe     = dtshd_probe,
  134.     .read_header    = dtshd_read_header,
  135.     .read_packet    = raw_read_packet,
  136.     .flags          = AVFMT_GENERIC_INDEX,
  137.     .extensions     = "dtshd",
  138.     .raw_codec_id   = AV_CODEC_ID_DTS,
  139. };
  140.