LCOV - code coverage report
Current view: top level - libavformat - dtshddec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 65 79 82.3 %
Date: 2017-12-17 04:34:43 Functions: 3 3 100.0 %

          Line data    Source code
       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 "libavcodec/dca.h"
      25             : #include "avformat.h"
      26             : #include "internal.h"
      27             : 
      28             : #define AUPR_HDR 0x415550522D484452
      29             : #define AUPRINFO 0x41555052494E464F
      30             : #define BITSHVTB 0x4249545348565442
      31             : #define BLACKOUT 0x424C41434B4F5554
      32             : #define BRANCHPT 0x4252414E43485054
      33             : #define BUILDVER 0x4255494C44564552
      34             : #define CORESSMD 0x434F524553534D44
      35             : #define DTSHDHDR 0x4454534844484452
      36             : #define EXTSS_MD 0x45585453535f4d44
      37             : #define FILEINFO 0x46494C45494E464F
      38             : #define NAVI_TBL 0x4E4156492D54424C
      39             : #define STRMDATA 0x5354524D44415441
      40             : #define TIMECODE 0x54494D45434F4445
      41             : 
      42             : typedef struct DTSHDDemuxContext {
      43             :     uint64_t    data_end;
      44             : } DTSHDDemuxContext;
      45             : 
      46        6130 : static int dtshd_probe(AVProbeData *p)
      47             : {
      48        6130 :     if (AV_RB64(p->buf) == DTSHDHDR)
      49          41 :         return AVPROBE_SCORE_MAX;
      50        6089 :     return 0;
      51             : }
      52             : 
      53          41 : static int dtshd_read_header(AVFormatContext *s)
      54             : {
      55          41 :     DTSHDDemuxContext *dtshd = s->priv_data;
      56          41 :     AVIOContext *pb = s->pb;
      57             :     uint64_t chunk_type, chunk_size;
      58             :     int64_t duration, data_start;
      59             :     AVStream *st;
      60             :     int ret;
      61             :     char *value;
      62             : 
      63          41 :     st = avformat_new_stream(s, NULL);
      64          41 :     if (!st)
      65           0 :         return AVERROR(ENOMEM);
      66          41 :     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
      67          41 :     st->codecpar->codec_id   = AV_CODEC_ID_DTS;
      68          41 :     st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
      69             : 
      70             :     for (;;) {
      71         733 :         chunk_type = avio_rb64(pb);
      72         387 :         chunk_size = avio_rb64(pb);
      73             : 
      74         387 :         if (avio_feof(pb))
      75          41 :             break;
      76             : 
      77         346 :         if (chunk_size < 4) {
      78           0 :             av_log(s, AV_LOG_ERROR, "chunk size too small\n");
      79           0 :             return AVERROR_INVALIDDATA;
      80             :         }
      81         346 :         if (chunk_size > ((uint64_t)1 << 61)) {
      82           0 :             av_log(s, AV_LOG_ERROR, "chunk size too big\n");
      83           0 :             return AVERROR_INVALIDDATA;
      84             :         }
      85             : 
      86         346 :         switch (chunk_type) {
      87          41 :         case STRMDATA:
      88          41 :             data_start = avio_tell(pb);
      89          41 :             dtshd->data_end = data_start + chunk_size;
      90          41 :             if (dtshd->data_end <= chunk_size)
      91           0 :                 return AVERROR_INVALIDDATA;
      92          41 :             if (!(pb->seekable & AVIO_SEEKABLE_NORMAL))
      93           0 :                 goto break_loop;
      94          41 :             goto skip;
      95             :             break;
      96          41 :         case AUPR_HDR:
      97          41 :             if (chunk_size < 21)
      98           0 :                 return AVERROR_INVALIDDATA;
      99          41 :             avio_skip(pb, 3);
     100          41 :             st->codecpar->sample_rate = avio_rb24(pb);
     101          41 :             if (!st->codecpar->sample_rate)
     102           0 :                 return AVERROR_INVALIDDATA;
     103          41 :             duration  = avio_rb32(pb); // num_frames
     104          41 :             duration *= avio_rb16(pb); // samples_per_frames
     105          41 :             st->duration = duration;
     106          41 :             avio_skip(pb, 5);
     107          41 :             st->codecpar->channels = ff_dca_count_chs_for_mask(avio_rb16(pb));
     108          41 :             st->codecpar->initial_padding = avio_rb16(pb);
     109          41 :             avio_skip(pb, chunk_size - 21);
     110          41 :             break;
     111          41 :         case FILEINFO:
     112          41 :             if (chunk_size > INT_MAX)
     113           0 :                 goto skip;
     114          41 :             value = av_malloc(chunk_size);
     115          41 :             if (!value)
     116           0 :                 goto skip;
     117          41 :             avio_read(pb, value, chunk_size);
     118          41 :             value[chunk_size - 1] = 0;
     119          41 :             av_dict_set(&s->metadata, "fileinfo", value,
     120             :                         AV_DICT_DONT_STRDUP_VAL);
     121          41 :             break;
     122             :         default:
     123         264 : skip:
     124         264 :             ret = avio_skip(pb, chunk_size);
     125         264 :             if (ret < 0)
     126           0 :                 return ret;
     127             :         };
     128             :     }
     129             : 
     130          41 :     if (!dtshd->data_end)
     131           0 :         return AVERROR_EOF;
     132             : 
     133          41 :     avio_seek(pb, data_start, SEEK_SET);
     134             : 
     135          41 : break_loop:
     136          41 :     if (st->codecpar->sample_rate)
     137          41 :         avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
     138             : 
     139          41 :     return 0;
     140             : }
     141             : 
     142        1399 : static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
     143             : {
     144        1399 :     DTSHDDemuxContext *dtshd = s->priv_data;
     145             :     int64_t size, left;
     146             :     int ret;
     147             : 
     148        1399 :     left = dtshd->data_end - avio_tell(s->pb);
     149        1399 :     size = FFMIN(left, 1024);
     150        1399 :     if (size <= 0)
     151         123 :         return AVERROR_EOF;
     152             : 
     153        1276 :     ret = av_get_packet(s->pb, pkt, size);
     154        1276 :     if (ret < 0)
     155           0 :         return ret;
     156             : 
     157        1276 :     pkt->stream_index = 0;
     158             : 
     159        1276 :     return ret;
     160             : }
     161             : 
     162             : AVInputFormat ff_dtshd_demuxer = {
     163             :     .name           = "dtshd",
     164             :     .long_name      = NULL_IF_CONFIG_SMALL("raw DTS-HD"),
     165             :     .priv_data_size = sizeof(DTSHDDemuxContext),
     166             :     .read_probe     = dtshd_probe,
     167             :     .read_header    = dtshd_read_header,
     168             :     .read_packet    = raw_read_packet,
     169             :     .flags          = AVFMT_GENERIC_INDEX,
     170             :     .extensions     = "dtshd",
     171             :     .raw_codec_id   = AV_CODEC_ID_DTS,
     172             : };

Generated by: LCOV version 1.13