MythTV  master
FrameAnalyzer.cpp
Go to the documentation of this file.
1 #include "mythlogging.h"
2 #include "CommDetector2.h"
3 #include "FrameAnalyzer.h"
4 
5 using namespace commDetector2;
6 
7 namespace frameAnalyzer {
8 
9 bool
10 rrccinrect(int rr, int cc, int rrow, int rcol, int rwidth, int rheight)
11 {
12  return rr >= rrow && cc >= rcol &&
13  rr < rrow + rheight && cc < rcol + rwidth;
14 }
15 
16 void
18  const char *comment)
19 {
20  for (FrameAnalyzer::FrameMap::const_iterator ii = frameMap->begin();
21  ii != frameMap->end();
22  ++ii)
23  {
24  /*
25  * QMap'd as 0-based index, but display as 1-based index to match "Edit
26  * Recording" OSD.
27  */
28  long long bb = ii.key() + 1;
29  if (*ii)
30  {
31  long long ee = bb + *ii;
32  long long len = ee - bb;
33 
34  LOG(VB_COMMFLAG, LOG_INFO, QString("%1: %2-%3 (%4-%5, %6)")
35  .arg(comment)
36  .arg(bb, 6).arg(ee - 1, 6)
37  .arg(frameToTimestamp(bb, fps))
38  .arg(frameToTimestamp(ee - 1, fps))
39  .arg(frameToTimestamp(len, fps)));
40  }
41  else
42  {
43  LOG(VB_COMMFLAG, LOG_INFO, QString("%1: %2 (%3)")
44  .arg(comment)
45  .arg(bb, 6)
46  .arg(frameToTimestamp(bb, fps)));
47  }
48  }
49 }
50 
51 void
53  const char *comment)
54 {
55  for (FrameAnalyzer::FrameMap::const_iterator ii = frameMap->begin();
56  ii != frameMap->end();
57  ++ii)
58  {
59  /*
60  * QMap'd as 0-based index, but display as 1-based index to match "Edit
61  * Recording" OSD.
62  */
63  long long bb = ii.key() + 1;
64  if (*ii)
65  {
66  long long ee = bb + *ii;
67  long long len = ee - bb;
68 
69  LOG(VB_COMMFLAG, LOG_INFO, QString("%1: %2-%3 (%4-%5, %6)")
70  .arg(comment)
71  .arg(bb, 6).arg(ee - 1, 6)
72  .arg(frameToTimestamp(bb, fps))
73  .arg(frameToTimestamp(ee - 1, fps))
74  .arg(frameToTimestampms(len, fps)));
75  }
76  else
77  {
78  LOG(VB_COMMFLAG, LOG_INFO, QString("%1: %2 (%3)")
79  .arg(comment)
80  .arg(bb, 6)
81  .arg(frameToTimestamp(bb, fps)));
82  }
83  }
84 }
85 
86 long long
88 {
89  long long sum = 0;
90  foreach (long long ii, *frameMap)
91  sum += ii;
92  return sum;
93 }
94 
95 bool
96 removeShortBreaks(FrameAnalyzer::FrameMap *breakMap, float fps, int minbreaklen,
97  bool verbose)
98 {
99  /*
100  * Remove any breaks that are less than "minbreaklen" units long.
101  *
102  * Return whether or not any breaks were actually removed.
103  */
104  FrameAnalyzer::FrameMap::Iterator bb;
105 
106  bool removed = false;
107 
108  /* Don't remove the initial commercial break, no matter how short. */
109  bb = breakMap->begin();
110  if (bb != breakMap->end() && bb.key() == 0)
111  ++bb;
112  while (bb != breakMap->end())
113  {
114  if (*bb >= minbreaklen)
115  {
116  ++bb;
117  continue;
118  }
119 
120  /* Don't remove the final commercial break, no matter how short. */
121  FrameAnalyzer::FrameMap::Iterator bb1 = bb;
122  ++bb;
123  if (bb == breakMap->end())
124  continue;
125 
126  if (verbose)
127  {
128  long long start = bb1.key();
129  long long end = start + *bb1 - 1;
130  LOG(VB_COMMFLAG, LOG_INFO, QString("Removing break %1-%2 (%3-%4)")
131  .arg(frameToTimestamp(start, fps))
132  .arg(frameToTimestamp(end, fps))
133  .arg(start + 1).arg(end + 1));
134  }
135  breakMap->erase(bb1);
136  removed = true;
137  }
138 
139  return removed;
140 }
141 
142 bool
143 removeShortSegments(FrameAnalyzer::FrameMap *breakMap, long long nframes,
144  float fps, int minseglen, bool verbose)
145 {
146  /*
147  * Remove any segments that are less than "minseglen" units long.
148  *
149  * Return whether or not any segments were actually removed.
150  */
151  FrameAnalyzer::FrameMap::Iterator bb;
152  FrameAnalyzer::FrameMap::Iterator bbnext;
153 
154  bool removed = false;
155 
156  for (bb = breakMap->begin(); bb != breakMap->end(); bb = bbnext)
157  {
158  /* Never remove initial segment (beginning at frame 0). */
159  if (bb == breakMap->begin() && bb != breakMap->end() &&
160  bb.key() != 0 && bb.key() < minseglen)
161  ++bb;
162 
163  bbnext = bb;
164  ++bbnext;
165  long long brkb = bb.key();
166  long long segb = brkb + *bb;
167  long long sege = bbnext == breakMap->end() ? nframes : bbnext.key();
168  long long seglen = sege - segb;
169  if (seglen >= minseglen)
170  continue;
171 
172  /* Merge break with next break. */
173  if (bbnext == breakMap->end())
174  {
175  if (segb != nframes)
176  {
177  /* Extend break "bb" to end of recording. */
178  if (verbose)
179  {
180  long long old1 = brkb;
181  long long old2 = segb - 1;
182  long long new1 = brkb;
183  long long new2 = nframes - 1;
184  LOG(VB_COMMFLAG, LOG_INFO,
185  QString("Removing segment %1-%2 (%3-%4)")
186  .arg(frameToTimestamp(segb + 1, fps))
187  .arg(frameToTimestamp(sege + 1, fps))
188  .arg(segb + 1).arg(sege + 1));
189  LOG(VB_COMMFLAG, LOG_INFO,
190  QString("Replacing break %1-%2 (%3-%4)"
191  " with %5-%6 (%7-%8, EOF)")
192  .arg(frameToTimestamp(old1 + 1, fps))
193  .arg(frameToTimestamp(old2 + 1, fps))
194  .arg(old1 + 1).arg(old2 + 1)
195  .arg(frameToTimestamp(new1 + 1, fps))
196  .arg(frameToTimestamp(new2 + 1, fps))
197  .arg(new1 + 1).arg(new2 + 1));
198  }
199  breakMap->remove(brkb);
200  breakMap->insert(brkb, nframes - brkb);
201  removed = true;
202  }
203  }
204  else
205  {
206  /* Extend break "bb" to cover "bbnext"; delete "bbnext". */
207  if (verbose)
208  {
209  long long old1 = brkb;
210  long long old2 = segb - 1;
211  long long new1 = brkb;
212  long long new2 = bbnext.key() + *bbnext - 1;
213  LOG(VB_COMMFLAG, LOG_INFO,
214  QString("Removing segment %1-%2 (%3-%4)")
215  .arg(frameToTimestamp(segb + 1, fps))
216  .arg(frameToTimestamp(sege + 1, fps))
217  .arg(segb + 1).arg(sege + 1));
218  LOG(VB_COMMFLAG, LOG_INFO,
219  QString("Replacing break %1-%2 (%3-%4)"
220  " with %5-%6 (%7-%8)")
221  .arg(frameToTimestamp(old1 + 1, fps))
222  .arg(frameToTimestamp(old2 + 1, fps))
223  .arg(old1 + 1).arg(old2 + 1)
224  .arg(frameToTimestamp(new1 + 1, fps))
225  .arg(frameToTimestamp(new2 + 1, fps))
226  .arg(new1 + 1).arg(new2 + 1));
227  }
228  breakMap->remove(brkb);
229  breakMap->insert(brkb, bbnext.key() + *bbnext - brkb);
230 
231  bb = bbnext;
232  ++bbnext;
233  if (verbose)
234  {
235  long long start = bb.key();
236  long long end = start + *bb - 1;
237  LOG(VB_COMMFLAG, LOG_INFO,
238  QString("Removing break %1-%2 (%3-%4)")
239  .arg(frameToTimestamp(start + 1, fps))
240  .arg(frameToTimestamp(end + 1, fps))
241  .arg(start + 1).arg(end + 1));
242  }
243  breakMap->erase(bb);
244 
245  removed = true;
246  }
247  }
248 
249  return removed;
250 }
251 
252 FrameAnalyzer::FrameMap::const_iterator
254  long long markend)
255 {
256  /*
257  * Search forwards to find the earliest block "block" such that
258  *
259  * mark <= blockbegin < markend
260  *
261  * Return frameMap->constEnd() if there is no such block.
262  */
263  FrameAnalyzer::FrameMap::const_iterator block = frameMap->constBegin();
264 
265  for (; block != frameMap->constEnd(); ++block)
266  {
267  const long long bb = block.key();
268  const long long ee = bb + *block;
269  if (mark < ee)
270  {
271  if (mark <= bb && bb < markend)
272  return block;
273  break;
274  }
275  }
276  return frameMap->constEnd();
277 }
278 
279 FrameAnalyzer::FrameMap::const_iterator
281  long long markbegin, long long mark)
282 {
283  /*
284  * Search backards to find the latest block "block" such that
285  *
286  * markbegin < blockend <= mark
287  *
288  * Return frameMap->constEnd() if there is no such block.
289  */
290  FrameAnalyzer::FrameMap::const_iterator block = frameMap->constEnd();
291  for (--block; block != frameMap->constBegin(); --block)
292  {
293  const long long bb = block.key();
294  const long long ee = bb + *block;
295  if (bb < mark)
296  {
297  if (markbegin < ee && ee <= mark)
298  return block;
299  break;
300  }
301  }
302  return frameMap->constEnd();
303 }
304 
305 }; /* namespace */
306 
307 /* vim: set expandtab tabstop=4 shiftwidth=4: */
bool removeShortBreaks(FrameAnalyzer::FrameMap *breakMap, float fps, int minbreaklen, bool verbose)
bool rrccinrect(int rr, int cc, int rrow, int rcol, int rwidth, int rheight)
Definition: cc.h:13
QString frameToTimestamp(long long frameno, float fps)
Definition: lang.c:20
bool removeShortSegments(FrameAnalyzer::FrameMap *breakMap, long long nframes, float fps, int minseglen, bool verbose)
FrameAnalyzer::FrameMap::const_iterator frameMapSearchBackwards(const FrameAnalyzer::FrameMap *frameMap, long long markbegin, long long mark)
void frameAnalyzerReportMap(const FrameAnalyzer::FrameMap *frameMap, float fps, const char *comment)
QMap< long long, long long > FrameMap
Definition: FrameAnalyzer.h:43
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
long long frameAnalyzerMapSum(const FrameAnalyzer::FrameMap *frameMap)
FrameAnalyzer::FrameMap::const_iterator frameMapSearchForwards(const FrameAnalyzer::FrameMap *frameMap, long long mark, long long markend)
QString frameToTimestampms(long long frameno, float fps)
void frameAnalyzerReportMapms(const FrameAnalyzer::FrameMap *frameMap, float fps, const char *comment)