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