Coverage Report

Created: 2025-07-18 08:04

/src/vlc/modules/demux/mkv/mkv.hpp
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
 * mkv.hpp : matroska demuxer
3
 *****************************************************************************
4
 * Copyright (C) 2003-2005, 2008 VLC authors and VideoLAN
5
 *
6
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7
 *          Steve Lhomme <steve.lhomme@free.fr>
8
 *
9
 * This program is free software; you can redistribute it and/or modify it
10
 * under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation; either version 2.1 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 * GNU Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program; if not, write to the Free Software Foundation,
21
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22
 *****************************************************************************/
23
24
#ifndef VLC_MKV_MKV_HPP_
25
#define VLC_MKV_MKV_HPP_
26
27
/*****************************************************************************
28
 * Preamble
29
 *****************************************************************************/
30
31
#ifdef HAVE_CONFIG_H
32
# include "config.h"
33
#endif
34
35
#include <vlc_common.h>
36
#include <vlc_plugin.h>
37
38
#include <vlc_meta.h>
39
#include <vlc_input.h>
40
#include <vlc_demux.h>
41
#include <vlc_aout.h> /* For reordering */
42
43
#include <iostream>
44
#include <cassert>
45
#include <typeinfo>
46
#include <string>
47
#include <vector>
48
#include <algorithm>
49
#include <map>
50
#include <stdexcept>
51
#include <functional>
52
53
/* libebml and matroska */
54
#include <ebml/EbmlVersion.h>
55
#include <ebml/EbmlHead.h>
56
#include <ebml/EbmlSubHead.h>
57
#include <ebml/EbmlStream.h>
58
#include <ebml/EbmlContexts.h>
59
#include <ebml/EbmlVoid.h>
60
61
#include <matroska/KaxVersion.h>
62
#include <matroska/KaxAttachments.h>
63
#include <matroska/KaxAttached.h>
64
#include <matroska/KaxBlock.h>
65
#include <matroska/KaxBlockData.h>
66
#include <matroska/KaxChapters.h>
67
#include <matroska/KaxCluster.h>
68
#include <matroska/KaxClusterData.h>
69
#include <matroska/KaxContexts.h>
70
#include <matroska/KaxCues.h>
71
#include <matroska/KaxCuesData.h>
72
#include <matroska/KaxInfo.h>
73
#include <matroska/KaxInfoData.h>
74
#include <matroska/KaxSeekHead.h>
75
#include <matroska/KaxSegment.h>
76
#include <matroska/KaxTag.h>
77
#include <matroska/KaxTags.h>
78
#include <matroska/KaxTracks.h>
79
#include <matroska/KaxTrackAudio.h>
80
#include <matroska/KaxTrackVideo.h>
81
#include <matroska/KaxTrackEntryData.h>
82
#include <matroska/KaxContentEncoding.h>
83
84
44
#define GlobalTimestamp()   GlobalTimecode()
85
51
#define InitTimestamp(t,s)  InitTimecode(t,s)
86
using KaxClusterTimestamp    = libmatroska::KaxClusterTimecode;
87
using KaxTimestampScale      = libmatroska::KaxTimecodeScale;
88
using KaxTrackTimestampScale = libmatroska::KaxTrackTimecodeScale;
89
90
#include "stream_io_callback.hpp"
91
92
#ifdef HAVE_ZLIB_H
93
#   include <zlib.h>
94
#endif
95
96
#ifndef NDEBUG
97
//# define MKV_DEBUG 0
98
#endif
99
100
namespace mkv {
101
102
33
#define MATROSKA_COMPRESSION_NONE  -1
103
0
#define MATROSKA_COMPRESSION_ZLIB   0
104
#define MATROSKA_COMPRESSION_BLIB   1
105
#define MATROSKA_COMPRESSION_LZOX   2
106
7.34k
#define MATROSKA_COMPRESSION_HEADER 3
107
108
enum
109
{
110
    MATROSKA_ENCODING_SCOPE_ALL_FRAMES = 1,
111
    MATROSKA_ENCODING_SCOPE_PRIVATE = 2,
112
    MATROSKA_ENCODING_SCOPE_NEXT = 4 /* unsupported */
113
};
114
115
enum chapter_codec_id
116
{
117
    MATROSKA_CHAPTER_CODEC_NATIVE  = 0,
118
    MATROSKA_CHAPTER_CODEC_DVD     = 1,
119
};
120
121
17
#define MKVD_TIMECODESCALE 1000000
122
123
963
#define MKV_IS_ID( el, C ) ( el != NULL && (el->operator const EbmlId&()) == EBML_ID(C) && !el->IsDummy() )
124
1.36k
#define MKV_CHECKED_PTR_DECL( name, type, src ) type * name = MKV_IS_ID(src, type) ? static_cast<type*>(src) : NULL
125
22
#define MKV_CHECKED_PTR_DECL_CONST( name, type, src ) const type * name = MKV_IS_ID(src, type) ? static_cast<const type*>(src) : NULL
126
127
class MissingMandatory : public std::runtime_error
128
{
129
public:
130
    MissingMandatory(const char * type_name)
131
0
        :std::runtime_error(std::string("missing mandatory element without a default ") + type_name)
132
0
    {}
133
};
134
135
template <typename Type>
136
Type & GetMandatoryChild(const EbmlMaster & Master)
137
33
{
138
33
  auto p = static_cast<Type *>(Master.FindFirstElt(EBML_INFO(Type)));
139
33
  if (p == nullptr)
140
0
  {
141
0
    throw MissingMandatory(EBML_INFO_NAME(EBML_INFO(Type)));
142
0
  }
143
33
  return *p;
144
33
}
libmatroska::KaxTrackType& mkv::GetMandatoryChild<libmatroska::KaxTrackType>(libebml::EbmlMaster const&)
Line
Count
Source
137
33
{
138
33
  auto p = static_cast<Type *>(Master.FindFirstElt(EBML_INFO(Type)));
139
33
  if (p == nullptr)
140
0
  {
141
0
    throw MissingMandatory(EBML_INFO_NAME(EBML_INFO(Type)));
142
0
  }
143
33
  return *p;
144
33
}
Unexecuted instantiation: libmatroska::KaxFileData& mkv::GetMandatoryChild<libmatroska::KaxFileData>(libebml::EbmlMaster const&)
Unexecuted instantiation: libmatroska::KaxFileName& mkv::GetMandatoryChild<libmatroska::KaxFileName>(libebml::EbmlMaster const&)
Unexecuted instantiation: libmatroska::KaxMimeType& mkv::GetMandatoryChild<libmatroska::KaxMimeType>(libebml::EbmlMaster const&)
145
#if LIBEBML_VERSION < 0x020000
146
template <typename Type>
147
Type * FindChild(const EbmlMaster & Master)
148
2.37k
{
149
2.37k
  return static_cast<Type *>(Master.FindFirstElt(EBML_INFO(Type)));
150
2.37k
}
libmatroska::KaxBlockMore const* mkv::FindChild<libmatroska::KaxBlockMore const>(libebml::EbmlMaster const&)
Line
Count
Source
148
791
{
149
791
  return static_cast<Type *>(Master.FindFirstElt(EBML_INFO(Type)));
150
791
}
libmatroska::KaxBlockAdditional const* mkv::FindChild<libmatroska::KaxBlockAdditional const>(libebml::EbmlMaster const&)
Line
Count
Source
148
791
{
149
791
  return static_cast<Type *>(Master.FindFirstElt(EBML_INFO(Type)));
150
791
}
libmatroska::KaxBlockAddID const* mkv::FindChild<libmatroska::KaxBlockAddID const>(libebml::EbmlMaster const&)
Line
Count
Source
148
791
{
149
791
  return static_cast<Type *>(Master.FindFirstElt(EBML_INFO(Type)));
150
791
}
Unexecuted instantiation: libmatroska::KaxChapterProcessData* mkv::FindChild<libmatroska::KaxChapterProcessData>(libebml::EbmlMaster const&)
Unexecuted instantiation: libmatroska::KaxChapterProcessTime* mkv::FindChild<libmatroska::KaxChapterProcessTime>(libebml::EbmlMaster const&)
151
152
template <typename Type>
153
Type * FindNextChild(const EbmlMaster & Master, const Type & PastElt)
154
{
155
  return static_cast<Type *>(Master.FindNextElt(PastElt));
156
}
157
#endif
158
159
using namespace libmatroska;
160
161
class matroska_segment_c;
162
struct matroska_stream_c
163
{
164
    matroska_stream_c(stream_t *s, bool owner);
165
17
    ~matroska_stream_c() {}
166
167
    bool isUsed() const;
168
169
    vlc_stream_io_callback io_callback;
170
    matroska_iostream_c    estream;
171
172
    std::vector<matroska_segment_c*> segments;
173
};
174
175
class chapter_codec_cmds_c;
176
using chapter_cmd_match = std::function<bool(const chapter_codec_cmds_c &)>;
177
178
using chapter_uid = uint64_t;
179
180
181
/*****************************************************************************
182
 * definitions of structures and functions used by this plugins
183
 *****************************************************************************/
184
class PrivateTrackData
185
{
186
public:
187
0
    virtual ~PrivateTrackData() {}
188
0
    virtual int32_t Init() { return 0; }
189
};
190
191
class mkv_track_t
192
{
193
    public:
194
        mkv_track_t(enum es_format_category_e es_cat);
195
        ~mkv_track_t();
196
197
        typedef unsigned int track_id_t;
198
199
        bool         b_default;
200
        bool         b_enabled;
201
        bool         b_forced;
202
        track_id_t   i_number;
203
204
        size_t       i_extra_data;
205
        uint8_t      *p_extra_data;
206
207
        std::string  codec;
208
        bool         b_dts_only;
209
        bool         b_pts_only;
210
211
        bool         b_no_duration;
212
        vlc_tick_t   i_default_duration;
213
        float        f_timecodescale;
214
        vlc_tick_t   i_last_dts;
215
        uint64_t     i_skip_until_fpos; /*< any block before this fpos should be ignored */
216
217
        /* video */
218
        es_format_t fmt;
219
        float       f_fps;
220
        es_out_id_t *p_es;
221
222
        /* audio */
223
        unsigned int i_original_rate;
224
        uint8_t i_chans_to_reorder;            /* do we need channel reordering */
225
        uint8_t pi_chan_table[AOUT_CHAN_MAX];
226
227
228
        /* Private track parameters */
229
        PrivateTrackData *p_sys;
230
231
        bool            b_discontinuity;
232
        bool            b_has_alpha;
233
234
        /* informative */
235
        std::string str_codec_name;
236
237
        /* encryption/compression */
238
        int                    i_compression_type;
239
        uint32_t               i_encoding_scope;
240
        KaxContentCompSettings *p_compression_data;
241
242
        /* Matroska 4 new elements used by Opus */
243
        vlc_tick_t i_seek_preroll;
244
        vlc_tick_t i_codec_delay;
245
};
246
247
} // namespace
248
249
#endif /* _MKV_HPP_ */