~ubuntu-branches/ubuntu/wily/mkvtoolnix/wily

« back to all changes in this revision

Viewing changes to src/merge/reader_detection_and_creation.cpp

  • Committer: Package Import Robot
  • Author(s): Christian Marillat
  • Date: 2015-04-26 10:36:27 UTC
  • mfrom: (1.1.29) (4.2.45 sid)
  • Revision ID: package-import@ubuntu.com-20150426103627-k53p8hrai2ynikaa
Tags: 7.8.0-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** \brief output handling
 
2
 
 
3
   mkvmerge -- utility for splicing together matroska files
 
4
   from component media subtypes
 
5
 
 
6
   Distributed under the GPL v2
 
7
   see the file COPYING for details
 
8
   or visit http://www.gnu.org/copyleft/gpl.html
 
9
 
 
10
   Written by Moritz Bunkus <moritz@bunkus.org>.
 
11
*/
 
12
 
 
13
#include "common/common_pch.h"
 
14
 
 
15
#include "common/mm_mpls_multi_file_io.h"
 
16
#include "common/mm_read_buffer_io.h"
 
17
#include "common/strings/formatting.h"
 
18
#include "common/xml/xml.h"
 
19
#include "input/r_aac.h"
 
20
#include "input/r_aac_adif.h"
 
21
#include "input/r_ac3.h"
 
22
#include "input/r_asf.h"
 
23
#include "input/r_avc.h"
 
24
#include "input/r_avi.h"
 
25
#include "input/r_cdxa.h"
 
26
#include "input/r_coreaudio.h"
 
27
#include "input/r_dirac.h"
 
28
#include "input/r_dts.h"
 
29
#include "input/r_dv.h"
 
30
#include "input/r_flac.h"
 
31
#include "input/r_flv.h"
 
32
#include "input/r_hdsub.h"
 
33
#include "input/r_hevc.h"
 
34
#include "input/r_ivf.h"
 
35
#include "input/r_matroska.h"
 
36
#include "input/r_microdvd.h"
 
37
#include "input/r_mp3.h"
 
38
#include "input/r_mpeg_es.h"
 
39
#include "input/r_mpeg_ps.h"
 
40
#include "input/r_mpeg_ts.h"
 
41
#include "input/r_ogm.h"
 
42
#include "input/r_pgssup.h"
 
43
#include "input/r_qtmp4.h"
 
44
#include "input/r_real.h"
 
45
#include "input/r_srt.h"
 
46
#include "input/r_ssa.h"
 
47
#include "input/r_truehd.h"
 
48
#include "input/r_tta.h"
 
49
#include "input/r_usf.h"
 
50
#include "input/r_vc1.h"
 
51
#include "input/r_vobbtn.h"
 
52
#include "input/r_vobsub.h"
 
53
#include "input/r_wav.h"
 
54
#include "input/r_wavpack.h"
 
55
#include "merge/filelist.h"
 
56
#include "merge/input_x.h"
 
57
#include "merge/reader_detection_and_creation.h"
 
58
 
 
59
static std::vector<bfs::path>
 
60
file_names_to_paths(const std::vector<std::string> &file_names) {
 
61
  std::vector<bfs::path> paths;
 
62
  for (auto &file_name : file_names)
 
63
    paths.push_back(bfs::system_complete(bfs::path(file_name)));
 
64
 
 
65
  return paths;
 
66
}
 
67
 
 
68
static mm_io_cptr
 
69
open_input_file(filelist_t &file) {
 
70
  try {
 
71
    if (file.all_names.size() == 1)
 
72
      return mm_io_cptr(new mm_read_buffer_io_c(new mm_file_io_c(file.name), 1 << 17));
 
73
 
 
74
    else {
 
75
      std::vector<bfs::path> paths = file_names_to_paths(file.all_names);
 
76
      return mm_io_cptr(new mm_read_buffer_io_c(new mm_multi_file_io_c(paths, file.name), 1 << 17));
 
77
    }
 
78
 
 
79
  } catch (mtx::mm_io::exception &ex) {
 
80
    mxerror(boost::format(Y("The file '%1%' could not be opened for reading: %2%.\n")) % file.name % ex);
 
81
    return mm_io_cptr{};
 
82
 
 
83
  } catch (...) {
 
84
    mxerror(boost::format(Y("The source file '%1%' could not be opened successfully, or retrieving its size by seeking to the end did not work.\n")) % file.name);
 
85
    return mm_io_cptr{};
 
86
  }
 
87
}
 
88
 
 
89
static bool
 
90
open_playlist_file(filelist_t &file,
 
91
                   mm_io_c *in) {
 
92
  auto mpls_in = mm_mpls_multi_file_io_c::open_multi(in);
 
93
  if (!mpls_in)
 
94
    return false;
 
95
 
 
96
  file.is_playlist      = true;
 
97
  file.playlist_mpls_in = std::static_pointer_cast<mm_mpls_multi_file_io_c>(mpls_in);
 
98
 
 
99
  return true;
 
100
}
 
101
 
 
102
static file_type_e
 
103
detect_text_file_formats(filelist_t const &file) {
 
104
  auto text_io = mm_text_io_cptr{};
 
105
  try {
 
106
    text_io        = std::make_shared<mm_text_io_c>(new mm_file_io_c(file.name));
 
107
    auto text_size = text_io->get_size();
 
108
 
 
109
    if (srt_reader_c::probe_file(text_io.get(), text_size))
 
110
      return FILE_TYPE_SRT;
 
111
    else if (ssa_reader_c::probe_file(text_io.get(), text_size))
 
112
      return FILE_TYPE_SSA;
 
113
    else if (vobsub_reader_c::probe_file(text_io.get(), text_size))
 
114
      return FILE_TYPE_VOBSUB;
 
115
    else if (usf_reader_c::probe_file(text_io.get(), text_size))
 
116
      return FILE_TYPE_USF;
 
117
 
 
118
    // Unsupported text subtitle formats
 
119
    else if (microdvd_reader_c::probe_file(text_io.get(), text_size))
 
120
      return FILE_TYPE_MICRODVD;
 
121
 
 
122
  } catch (mtx::mm_io::exception &ex) {
 
123
    mxerror(boost::format(Y("The file '%1%' could not be opened for reading: %2%.\n")) % file.name % ex);
 
124
 
 
125
  } catch (...) {
 
126
    mxerror(boost::format(Y("The source file '%1%' could not be opened successfully, or retrieving its size by seeking to the end did not work.\n")) % file.name);
 
127
  }
 
128
 
 
129
  return FILE_TYPE_IS_UNKNOWN;
 
130
}
 
131
 
 
132
/** \brief Probe the file type
 
133
 
 
134
   Opens the input file and calls the \c probe_file function for each known
 
135
   file reader class. Uses \c mm_text_io_c for subtitle probing.
 
136
*/
 
137
static std::pair<file_type_e, int64_t>
 
138
get_file_type_internal(filelist_t &file) {
 
139
  mm_io_cptr af_io = open_input_file(file);
 
140
  mm_io_c *io      = af_io.get();
 
141
  int64_t size     = std::min(io->get_size(), static_cast<int64_t>(1 << 25));
 
142
 
 
143
  auto is_playlist = !file.is_playlist && open_playlist_file(file, io);
 
144
  if (is_playlist)
 
145
    io = file.playlist_mpls_in.get();
 
146
 
 
147
  file_type_e type = FILE_TYPE_IS_UNKNOWN;
 
148
 
 
149
  // File types that can be detected unambiguously but are not supported
 
150
  if (aac_adif_reader_c::probe_file(io, size))
 
151
    type = FILE_TYPE_AAC;
 
152
  else if (asf_reader_c::probe_file(io, size))
 
153
    type = FILE_TYPE_ASF;
 
154
  else if (cdxa_reader_c::probe_file(io, size))
 
155
    type = FILE_TYPE_CDXA;
 
156
  else if (flv_reader_c::probe_file(io, size))
 
157
    type = FILE_TYPE_FLV;
 
158
  else if (hdsub_reader_c::probe_file(io, size))
 
159
    type = FILE_TYPE_HDSUB;
 
160
 
 
161
  // File types that can be detected unambiguously
 
162
  else if (avi_reader_c::probe_file(io, size))
 
163
    type = FILE_TYPE_AVI;
 
164
  else if (kax_reader_c::probe_file(io, size))
 
165
    type = FILE_TYPE_MATROSKA;
 
166
  else if (wav_reader_c::probe_file(io, size))
 
167
    type = FILE_TYPE_WAV;
 
168
  else if (ogm_reader_c::probe_file(io, size))
 
169
    type = FILE_TYPE_OGM;
 
170
  else if (flac_reader_c::probe_file(io, size))
 
171
    type = FILE_TYPE_FLAC;
 
172
  else if (pgssup_reader_c::probe_file(io, size))
 
173
    type = FILE_TYPE_PGSSUP;
 
174
  else if (real_reader_c::probe_file(io, size))
 
175
    type = FILE_TYPE_REAL;
 
176
  else if (qtmp4_reader_c::probe_file(io, size))
 
177
    type = FILE_TYPE_QTMP4;
 
178
  else if (tta_reader_c::probe_file(io, size))
 
179
    type = FILE_TYPE_TTA;
 
180
  else if (vc1_es_reader_c::probe_file(io, size))
 
181
    type = FILE_TYPE_VC1;
 
182
  else if (wavpack_reader_c::probe_file(io, size))
 
183
    type = FILE_TYPE_WAVPACK4;
 
184
  else if (ivf_reader_c::probe_file(io, size))
 
185
    type = FILE_TYPE_IVF;
 
186
  else if (coreaudio_reader_c::probe_file(io, size))
 
187
    type = FILE_TYPE_COREAUDIO;
 
188
  else if (dirac_es_reader_c::probe_file(io, size))
 
189
    type = FILE_TYPE_DIRAC;
 
190
 
 
191
  // All text file types (subtitles).
 
192
  else
 
193
    type = detect_text_file_formats(file);
 
194
 
 
195
  if (FILE_TYPE_IS_UNKNOWN != type)
 
196
    ;                           // intentional fall-through
 
197
  // File types that are misdetected sometimes and that aren't supported
 
198
  else if (dv_reader_c::probe_file(io, size))
 
199
    type = FILE_TYPE_DV;
 
200
  // File types that are misdetected sometimes
 
201
  else if (dts_reader_c::probe_file(io, size, true))
 
202
    type = FILE_TYPE_DTS;
 
203
  else if (mpeg_ts_reader_c::probe_file(io, size))
 
204
    type = FILE_TYPE_MPEG_TS;
 
205
  else if (mpeg_ps_reader_c::probe_file(io, size))
 
206
    type = FILE_TYPE_MPEG_PS;
 
207
  else if (mpeg_es_reader_c::probe_file(io, size))
 
208
    type = FILE_TYPE_MPEG_ES;
 
209
  else {
 
210
    // File types which are the same in raw format and in other container formats.
 
211
    // Detection requires 20 or more consecutive packets.
 
212
    static const int s_probe_sizes[]                          = { 128 * 1024, 256 * 1024, 512 * 1024, 1024 * 1024, 0 };
 
213
    static const int s_probe_num_required_consecutive_packets = 64;
 
214
 
 
215
    int i;
 
216
    for (i = 0; (0 != s_probe_sizes[i]) && (FILE_TYPE_IS_UNKNOWN == type); ++i)
 
217
      if (mp3_reader_c::probe_file(io, size, s_probe_sizes[i], s_probe_num_required_consecutive_packets))
 
218
        type = FILE_TYPE_MP3;
 
219
      else if (ac3_reader_c::probe_file(io, size, s_probe_sizes[i], s_probe_num_required_consecutive_packets))
 
220
        type = FILE_TYPE_AC3;
 
221
      else if (aac_reader_c::probe_file(io, size, s_probe_sizes[i], s_probe_num_required_consecutive_packets))
 
222
        type = FILE_TYPE_AAC;
 
223
  }
 
224
  // More file types with detection issues.
 
225
  if (type != FILE_TYPE_IS_UNKNOWN)
 
226
    ;
 
227
  else if (truehd_reader_c::probe_file(io, size))
 
228
    type = FILE_TYPE_TRUEHD;
 
229
  else if (dts_reader_c::probe_file(io, size))
 
230
    type = FILE_TYPE_DTS;
 
231
  else if (vobbtn_reader_c::probe_file(io, size))
 
232
    type = FILE_TYPE_VOBBTN;
 
233
 
 
234
  // Try some more of the raw audio formats before trying h.264 (which
 
235
  // often enough simply works). However, require that the first frame
 
236
  // starts at the beginning of the file.
 
237
  else if (mp3_reader_c::probe_file(io, size, 32 * 1024, 1, true))
 
238
    type = FILE_TYPE_MP3;
 
239
  else if (ac3_reader_c::probe_file(io, size, 32 * 1024, 1, true))
 
240
    type = FILE_TYPE_AC3;
 
241
  else if (aac_reader_c::probe_file(io, size, 32 * 1024, 1, true))
 
242
    type = FILE_TYPE_AAC;
 
243
 
 
244
  else if (avc_es_reader_c::probe_file(io, size))
 
245
    type = FILE_TYPE_AVC_ES;
 
246
  else if (hevc_es_reader_c::probe_file(io, size))
 
247
    type = FILE_TYPE_HEVC_ES;
 
248
  else {
 
249
    // File types which are the same in raw format and in other container formats.
 
250
    // Detection requires 20 or more consecutive packets.
 
251
    static const int s_probe_sizes[]                          = { 32 * 1024, 64 * 1024, 128 * 1024, 256 * 1024, 512 * 1024, 1024 * 1024, 0 };
 
252
    static const int s_probe_num_required_consecutive_packets = 20;
 
253
 
 
254
    int i;
 
255
    for (i = 0; (0 != s_probe_sizes[i]) && (FILE_TYPE_IS_UNKNOWN == type); ++i)
 
256
      if (mp3_reader_c::probe_file(io, size, s_probe_sizes[i], s_probe_num_required_consecutive_packets))
 
257
        type = FILE_TYPE_MP3;
 
258
      else if (ac3_reader_c::probe_file(io, size, s_probe_sizes[i], s_probe_num_required_consecutive_packets))
 
259
        type = FILE_TYPE_AC3;
 
260
      else if (aac_reader_c::probe_file(io, size, s_probe_sizes[i], s_probe_num_required_consecutive_packets))
 
261
        type = FILE_TYPE_AAC;
 
262
  }
 
263
 
 
264
  return std::make_pair(type, size);
 
265
}
 
266
 
 
267
void
 
268
get_file_type(filelist_t &file) {
 
269
  auto result = get_file_type_internal(file);
 
270
 
 
271
  g_file_sizes += result.second;
 
272
 
 
273
  file.size     = result.second;
 
274
  file.type     = result.first;
 
275
}
 
276
 
 
277
/** \brief Creates the file readers
 
278
 
 
279
   For each file the appropriate file reader class is instantiated.
 
280
   The newly created class must read all track information in its
 
281
   contrsuctor and throw an exception in case of an error. Otherwise
 
282
   it is assumed that the file can be hanlded.
 
283
*/
 
284
void
 
285
create_readers() {
 
286
  static auto s_debug_timecode_restrictions = debugging_option_c{"timecode_restrictions"};
 
287
 
 
288
  for (auto &file : g_files) {
 
289
    try {
 
290
      mm_io_cptr input_file = file->playlist_mpls_in ? std::static_pointer_cast<mm_io_c>(file->playlist_mpls_in) : open_input_file(*file);
 
291
 
 
292
      switch (file->type) {
 
293
        case FILE_TYPE_AAC:
 
294
          file->reader.reset(new aac_reader_c(*file->ti, input_file));
 
295
          break;
 
296
        case FILE_TYPE_AC3:
 
297
          file->reader.reset(new ac3_reader_c(*file->ti, input_file));
 
298
          break;
 
299
        case FILE_TYPE_AVC_ES:
 
300
          file->reader.reset(new avc_es_reader_c(*file->ti, input_file));
 
301
          break;
 
302
        case FILE_TYPE_HEVC_ES:
 
303
          file->reader.reset(new hevc_es_reader_c(*file->ti, input_file));
 
304
          break;
 
305
        case FILE_TYPE_AVI:
 
306
          file->reader.reset(new avi_reader_c(*file->ti, input_file));
 
307
          break;
 
308
        case FILE_TYPE_COREAUDIO:
 
309
          file->reader.reset(new coreaudio_reader_c(*file->ti, input_file));
 
310
          break;
 
311
        case FILE_TYPE_DIRAC:
 
312
          file->reader.reset(new dirac_es_reader_c(*file->ti, input_file));
 
313
          break;
 
314
        case FILE_TYPE_DTS:
 
315
          file->reader.reset(new dts_reader_c(*file->ti, input_file));
 
316
          break;
 
317
#if defined(HAVE_FLAC_FORMAT_H)
 
318
        case FILE_TYPE_FLAC:
 
319
          file->reader.reset(new flac_reader_c(*file->ti, input_file));
 
320
          break;
 
321
#endif
 
322
        case FILE_TYPE_FLV:
 
323
          file->reader.reset(new flv_reader_c(*file->ti, input_file));
 
324
          break;
 
325
        case FILE_TYPE_IVF:
 
326
          file->reader.reset(new ivf_reader_c(*file->ti, input_file));
 
327
          break;
 
328
        case FILE_TYPE_MATROSKA:
 
329
          file->reader.reset(new kax_reader_c(*file->ti, input_file));
 
330
          break;
 
331
        case FILE_TYPE_MP3:
 
332
          file->reader.reset(new mp3_reader_c(*file->ti, input_file));
 
333
          break;
 
334
        case FILE_TYPE_MPEG_ES:
 
335
          file->reader.reset(new mpeg_es_reader_c(*file->ti, input_file));
 
336
          break;
 
337
        case FILE_TYPE_MPEG_PS:
 
338
          file->reader.reset(new mpeg_ps_reader_c(*file->ti, input_file));
 
339
          break;
 
340
        case FILE_TYPE_MPEG_TS:
 
341
          file->reader.reset(new mpeg_ts_reader_c(*file->ti, input_file));
 
342
          break;
 
343
        case FILE_TYPE_OGM:
 
344
          file->reader.reset(new ogm_reader_c(*file->ti, input_file));
 
345
          break;
 
346
        case FILE_TYPE_PGSSUP:
 
347
          file->reader.reset(new pgssup_reader_c(*file->ti, input_file));
 
348
          break;
 
349
        case FILE_TYPE_QTMP4:
 
350
          file->reader.reset(new qtmp4_reader_c(*file->ti, input_file));
 
351
          break;
 
352
        case FILE_TYPE_REAL:
 
353
          file->reader.reset(new real_reader_c(*file->ti, input_file));
 
354
          break;
 
355
        case FILE_TYPE_SSA:
 
356
          file->reader.reset(new ssa_reader_c(*file->ti, input_file));
 
357
          break;
 
358
        case FILE_TYPE_SRT:
 
359
          file->reader.reset(new srt_reader_c(*file->ti, input_file));
 
360
          break;
 
361
        case FILE_TYPE_TRUEHD:
 
362
          file->reader.reset(new truehd_reader_c(*file->ti, input_file));
 
363
          break;
 
364
        case FILE_TYPE_TTA:
 
365
          file->reader.reset(new tta_reader_c(*file->ti, input_file));
 
366
          break;
 
367
        case FILE_TYPE_USF:
 
368
          file->reader.reset(new usf_reader_c(*file->ti, input_file));
 
369
          break;
 
370
        case FILE_TYPE_VC1:
 
371
          file->reader.reset(new vc1_es_reader_c(*file->ti, input_file));
 
372
          break;
 
373
        case FILE_TYPE_VOBBTN:
 
374
          file->reader.reset(new vobbtn_reader_c(*file->ti, input_file));
 
375
          break;
 
376
        case FILE_TYPE_VOBSUB:
 
377
          file->reader.reset(new vobsub_reader_c(*file->ti, input_file));
 
378
          break;
 
379
        case FILE_TYPE_WAV:
 
380
          file->reader.reset(new wav_reader_c(*file->ti, input_file));
 
381
          break;
 
382
        case FILE_TYPE_WAVPACK4:
 
383
          file->reader.reset(new wavpack_reader_c(*file->ti, input_file));
 
384
          break;
 
385
        default:
 
386
          mxerror(boost::format(Y("EVIL internal bug! (unknown file type). %1%\n")) % BUGMSG);
 
387
          break;
 
388
      }
 
389
 
 
390
      file->reader->read_headers();
 
391
      file->reader->set_timecode_restrictions(file->restricted_timecode_min, file->restricted_timecode_max);
 
392
 
 
393
      // Re-calculate file size because the reader might switch to a
 
394
      // multi I/O reader in read_headers().
 
395
      file->size = file->reader->get_file_size();
 
396
 
 
397
      mxdebug_if(s_debug_timecode_restrictions,
 
398
                 boost::format("Timecode restrictions for %3%: min %1% max %2%\n") % file->restricted_timecode_min % file->restricted_timecode_max % file->ti->m_fname);
 
399
 
 
400
    } catch (mtx::mm_io::open_x &error) {
 
401
      mxerror(boost::format(Y("The demultiplexer for the file '%1%' failed to initialize:\n%2%\n")) % file->ti->m_fname % Y("The file could not be opened for reading, or there was not enough data to parse its headers."));
 
402
 
 
403
    } catch (mtx::input::open_x &error) {
 
404
      mxerror(boost::format(Y("The demultiplexer for the file '%1%' failed to initialize:\n%2%\n")) % file->ti->m_fname % Y("The file could not be opened for reading, or there was not enough data to parse its headers."));
 
405
 
 
406
    } catch (mtx::input::invalid_format_x &error) {
 
407
      mxerror(boost::format(Y("The demultiplexer for the file '%1%' failed to initialize:\n%2%\n")) % file->ti->m_fname % Y("The file content does not match its format type and was not recognized."));
 
408
 
 
409
    } catch (mtx::input::header_parsing_x &error) {
 
410
      mxerror(boost::format(Y("The demultiplexer for the file '%1%' failed to initialize:\n%2%\n")) % file->ti->m_fname % Y("The file headers could not be parsed, e.g. because they're incomplete, invalid or damaged."));
 
411
 
 
412
    } catch (mtx::input::exception &error) {
 
413
      mxerror(boost::format(Y("The demultiplexer for the file '%1%' failed to initialize:\n%2%\n")) % file->ti->m_fname % error.error());
 
414
    }
 
415
  }
 
416
}