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

« back to all changes in this revision

Viewing changes to src/merge/timecode_calculator.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
/*
 
2
   mkvmerge -- utility for splicing together matroska files
 
3
   from component media subtypes
 
4
 
 
5
   Distributed under the GPL v2
 
6
   see the file COPYING for details
 
7
   or visit http://www.gnu.org/copyleft/gpl.html
 
8
 
 
9
   the timecode calculator implementation
 
10
 
 
11
   Written by Moritz Bunkus <moritz@bunkus.org>.
 
12
*/
 
13
 
 
14
#include "common/common_pch.h"
 
15
 
 
16
#include "merge/timecode_calculator.h"
 
17
#include "merge/packet.h"
 
18
 
 
19
timecode_calculator_c::timecode_calculator_c(int64_t samples_per_second)
 
20
  : m_reference_timecode{timecode_c::ns(0)}
 
21
  , m_samples_per_second{samples_per_second}
 
22
  , m_samples_since_reference_timecode{}
 
23
  , m_samples_to_timecode{1000000000, static_cast<int64_t>(samples_per_second)}
 
24
{
 
25
}
 
26
 
 
27
void
 
28
timecode_calculator_c::add_timecode(timecode_c const &timecode) {
 
29
  if (timecode.valid())
 
30
    m_available_timecodes.push_back(timecode);
 
31
}
 
32
 
 
33
void
 
34
timecode_calculator_c::add_timecode(int64_t timecode) {
 
35
  if (-1 != timecode)
 
36
    m_available_timecodes.push_back(timecode_c::ns(timecode));
 
37
}
 
38
 
 
39
void
 
40
timecode_calculator_c::add_timecode(packet_cptr const &packet) {
 
41
  if (packet->has_timecode())
 
42
    m_available_timecodes.push_back(timecode_c::ns(packet->timecode));
 
43
}
 
44
 
 
45
timecode_c
 
46
timecode_calculator_c::get_next_timecode(int64_t samples_in_frame) {
 
47
  if (!m_available_timecodes.empty()) {
 
48
    auto next_timecode                 = m_available_timecodes.front();
 
49
    m_reference_timecode               = next_timecode;
 
50
    m_samples_since_reference_timecode = samples_in_frame;
 
51
 
 
52
    m_available_timecodes.pop_front();
 
53
 
 
54
    return next_timecode;
 
55
  }
 
56
 
 
57
  if (!m_samples_per_second)
 
58
    throw std::invalid_argument{"samples per second must not be 0"};
 
59
 
 
60
  auto next_timecode                  = m_reference_timecode + timecode_c::ns(m_samples_to_timecode * m_samples_since_reference_timecode);
 
61
  m_samples_since_reference_timecode += samples_in_frame;
 
62
 
 
63
  return next_timecode;
 
64
}
 
65
 
 
66
timecode_c
 
67
timecode_calculator_c::get_duration(int64_t samples) {
 
68
  if (!m_samples_per_second)
 
69
    throw std::invalid_argument{"samples per second must not be 0"};
 
70
 
 
71
  return timecode_c::ns(m_samples_to_timecode * samples);
 
72
}
 
73
 
 
74
void
 
75
timecode_calculator_c::set_samples_per_second(int64_t samples_per_second) {
 
76
  if (!samples_per_second || (samples_per_second == m_samples_per_second))
 
77
    return;
 
78
 
 
79
  m_reference_timecode               += get_duration(m_samples_since_reference_timecode);
 
80
  m_samples_since_reference_timecode  = 0;
 
81
  m_samples_to_timecode.set(1000000000, samples_per_second);
 
82
}