MythTV  master
cutter.cpp
Go to the documentation of this file.
1 
2 #include "cutter.h"
3 
4 #include <algorithm> // for min
5 
6 #include <QMap> // for QMap
7 
8 #include "mythlogging.h"
9 
11 {
12  // Break each cut into two parts, the first for
13  // the player and the second for the transcode loop.
14  frm_dir_map_t remainingCutList;
15  int64_t start = 0;
16  int64_t leadinLength = 0;
17 
19  m_foreshortenedCutList.clear();
20 
21  for (auto it = deleteMap.begin(); it != deleteMap.end(); ++it)
22  {
23  switch(it.value())
24  {
25  case MARK_CUT_START:
27  start = it.key();
28  break;
29 
30  case MARK_CUT_END:
31  leadinLength = std::min((int64_t)(it.key() - start),
32  (int64_t)MAXLEADIN);
33  if (leadinLength >= MINCUT)
34  {
35  m_foreshortenedCutList[it.key() - leadinLength + 2] =
37  remainingCutList[it.key() - leadinLength + 1] =
39  remainingCutList[it.key()] = MARK_CUT_END;
40  }
41  else
42  {
43  // Cut too short to use new method.
45  }
46  break;
47 
48  default:
49  // Ignore all other mark types.
50  break;
51  }
52  }
53 
54  m_tracker.SetMap(remainingCutList);
55 }
56 
58 {
60 }
61 
62 void Cutter::Activate(float v2a, int64_t total)
63 {
64  m_active = true;
66  m_totalFrames = total;
70 }
71 
72 void Cutter::NewFrame(int64_t currentFrame)
73 {
74  if (m_active)
75  {
76  if (m_videoFramesToCut == 0)
77  {
78  uint64_t jumpTo = 0;
79 
80  if (m_tracker.TrackerWantsToJump(currentFrame, jumpTo))
81  {
82  // Reset the tracker and work out how much video and audio
83  // to drop
84  m_tracker.TrackerReset(jumpTo);
85  m_videoFramesToCut = jumpTo - currentFrame;
88  LOG(VB_GENERAL, LOG_INFO,
89  QString("Clean cut: discarding frame from %1 to %2: "
90  "vid %3 aud %4")
91  .arg(currentFrame).arg((long)jumpTo)
92  .arg(m_videoFramesToCut)
93  .arg(m_audioFramesToCut));
94  }
95  }
96  }
97 }
98 
100 {
101  if (m_videoFramesToCut == 0)
102  {
103  return false;
104  }
105 
106  // We are inside a cut. Inhibit use of this frame
108 
109  if(m_videoFramesToCut == 0)
110  {
111  LOG(VB_GENERAL, LOG_INFO,
112  QString("Clean cut: end of video cut; audio frames left "
113  "to cut %1") .arg(m_audioFramesToCut));
114  }
115 
116  return true;
117 }
118 
119 bool Cutter::InhibitUseAudioFrames(int64_t frames, long *totalAudio)
120 {
121  int64_t delta = m_audioFramesToCut - frames;
122  if (delta < 0)
123  delta = -delta;
124 
125  if (m_audioFramesToCut == 0)
126  {
127  return false;
128  }
129  if (delta < m_audioFramesToCut)
130  {
131  // Drop the packet containing these frames if doing
132  // so gets us closer to zero left to drop
133  m_audioFramesToCut -= frames;
134  if(m_audioFramesToCut == 0)
135  {
136  LOG(VB_GENERAL, LOG_INFO,
137  QString("Clean cut: end of audio cut; vidio frames left "
138  "to cut %1") .arg(m_videoFramesToCut));
139  }
140  return true;
141  }
142 
143  // Don't drop this packet even though we still have frames to cut,
144  // because doing so would put us further out. Instead, inflate the
145  // callers record of how many audio frames have been output.
146  *totalAudio += m_audioFramesToCut;
147  m_audioFramesToCut = 0;
148  LOG(VB_GENERAL, LOG_INFO,
149  QString("Clean cut: end of audio cut; vidio frames left to "
150  "cut %1") .arg(m_videoFramesToCut));
151  return false;
152 }
153 
155 {
156  if (m_audioFramesToCut > 0)
157  {
158  // If the cutter is in the process of dropping audio then
159  // it is better to drop more audio rather than insert a dummy frame
161  return true;
162  }
163  return false;
164 }
165 
167 {
169  {
170  // If the cutter is in the process of dropping audio and the
171  // amount to drop is sufficient then we can drop less
172  // audio rather than drop a frame
174 
175  // But if it's a frame we are supposed to drop anyway, still do so,
176  // and record that we have
177  if (m_videoFramesToCut > 0)
178  {
180  return false;
181  }
182  return true;
183  }
184  return false;
185 }
186 
187 /* vim: set expandtab tabstop=4 shiftwidth=4: */
188 
DeleteMap::SetPlayerContext
void SetPlayerContext(PlayerContext *ctx)
Definition: deletemap.h:31
Cutter::Activate
void Activate(float v2a, int64_t total)
Definition: cutter.cpp:62
Cutter::InhibitDummyFrame
bool InhibitDummyFrame(void)
Definition: cutter.cpp:154
Cutter::m_foreshortenedCutList
frm_dir_map_t m_foreshortenedCutList
Definition: cutter.h:28
DeleteMap::TrackerReset
void TrackerReset(uint64_t frame)
Resets the internal state tracker.
Definition: deletemap.cpp:806
DeleteMap::SetMap
void SetMap(const frm_dir_map_t &map)
Use the given map.
Definition: deletemap.cpp:715
Cutter::MAXLEADIN
@ MAXLEADIN
Definition: cutter.h:36
MARK_CUT_END
@ MARK_CUT_END
Definition: programtypes.h:56
cutter.h
frm_dir_map_t
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
Definition: programtypes.h:119
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
Cutter::m_audioFramesPerVideoFrame
float m_audioFramesPerVideoFrame
Definition: cutter.h:33
DeleteMap::TrackerWantsToJump
bool TrackerWantsToJump(uint64_t frame, uint64_t &to) const
Returns true if the given frame has passed the last cut point start and provides the frame number of ...
Definition: deletemap.cpp:840
Cutter::AdjustedCutList
frm_dir_map_t AdjustedCutList() const
Definition: cutter.cpp:57
mythlogging.h
Cutter::NewFrame
void NewFrame(int64_t currentFrame)
Definition: cutter.cpp:72
Cutter::m_audioFramesToCut
int64_t m_audioFramesToCut
Definition: cutter.h:32
Cutter::m_videoFramesToCut
int64_t m_videoFramesToCut
Definition: cutter.h:31
Cutter::InhibitDropFrame
bool InhibitDropFrame(void)
Definition: cutter.cpp:166
Cutter::InhibitUseAudioFrames
bool InhibitUseAudioFrames(int64_t frames, long *totalAudio)
Definition: cutter.cpp:119
MARK_CUT_START
@ MARK_CUT_START
Definition: programtypes.h:57
Cutter::m_tracker
DeleteMap m_tracker
Definition: cutter.h:29
PlayerContext
Definition: playercontext.h:52
Cutter::m_totalFrames
int64_t m_totalFrames
Definition: cutter.h:30
Cutter::MINCUT
@ MINCUT
Definition: cutter.h:37
Cutter::m_active
bool m_active
Definition: cutter.h:27
Cutter::InhibitUseVideoFrame
bool InhibitUseVideoFrame(void)
Definition: cutter.cpp:99
Cutter::SetCutList
void SetCutList(frm_dir_map_t &deleteMap, PlayerContext *ctx)
Definition: cutter.cpp:10