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  for (FrameAnalyzer::FrameMap::const_iterator ii = frameMap->begin();
91  ii != frameMap->end();
92  ++ii)
93  sum += *ii;
94  return sum;
95 }
96 
97 bool
98 removeShortBreaks(FrameAnalyzer::FrameMap *breakMap, float fps, int minbreaklen,
99  bool verbose)
100 {
101  /*
102  * Remove any breaks that are less than "minbreaklen" units long.
103  *
104  * Return whether or not any breaks were actually removed.
105  */
106  FrameAnalyzer::FrameMap::Iterator bb;
107  bool removed;
108 
109  removed = false;
110 
111  /* Don't remove the initial commercial break, no matter how short. */
112  bb = breakMap->begin();
113  if (bb != breakMap->end() && bb.key() == 0)
114  ++bb;
115  while (bb != breakMap->end())
116  {
117  if (*bb >= minbreaklen)
118  {
119  ++bb;
120  continue;
121  }
122 
123  /* Don't remove the final commercial break, no matter how short. */
124  FrameAnalyzer::FrameMap::Iterator bb1 = bb;
125  ++bb;
126  if (bb == breakMap->end())
127  continue;
128 
129  if (verbose)
130  {
131  long long start = bb1.key();
132  long long end = start + *bb1 - 1;
133  LOG(VB_COMMFLAG, LOG_INFO, QString("Removing break %1-%2 (%3-%4)")
134  .arg(frameToTimestamp(start, fps))
135  .arg(frameToTimestamp(end, fps))
136  .arg(start + 1).arg(end + 1));
137  }
138  breakMap->erase(bb1);
139  removed = true;
140  }
141 
142  return removed;
143 }
144 
145 bool
146 removeShortSegments(FrameAnalyzer::FrameMap *breakMap, long long nframes,
147  float fps, int minseglen, bool verbose)
148 {
149  /*
150  * Remove any segments that are less than "minseglen" units long.
151  *
152  * Return whether or not any segments were actually removed.
153  */
154  FrameAnalyzer::FrameMap::Iterator bb, bbnext;
155  bool removed;
156 
157  removed = false;
158 
159 
160  for (bb = breakMap->begin(); bb != breakMap->end(); bb = bbnext)
161  {
162  /* Never remove initial segment (beginning at frame 0). */
163  if (bb == breakMap->begin() && bb != breakMap->end() &&
164  bb.key() != 0 && bb.key() < minseglen)
165  ++bb;
166 
167  bbnext = bb;
168  ++bbnext;
169  long long brkb = bb.key();
170  long long segb = brkb + *bb;
171  long long sege = bbnext == breakMap->end() ? nframes : bbnext.key();
172  long long seglen = sege - segb;
173  if (seglen >= minseglen)
174  continue;
175 
176  /* Merge break with next break. */
177  if (bbnext == breakMap->end())
178  {
179  if (segb != nframes)
180  {
181  /* Extend break "bb" to end of recording. */
182  if (verbose)
183  {
184  long long old1 = brkb;
185  long long old2 = segb - 1;
186  long long new1 = brkb;
187  long long new2 = nframes - 1;
188  LOG(VB_COMMFLAG, LOG_INFO,
189  QString("Removing segment %1-%2 (%3-%4)")
190  .arg(frameToTimestamp(segb + 1, fps))
191  .arg(frameToTimestamp(sege + 1, fps))
192  .arg(segb + 1).arg(sege + 1));
193  LOG(VB_COMMFLAG, LOG_INFO,
194  QString("Replacing break %1-%2 (%3-%4)"
195  " with %5-%6 (%7-%8, EOF)")
196  .arg(frameToTimestamp(old1 + 1, fps))
197  .arg(frameToTimestamp(old2 + 1, fps))
198  .arg(old1 + 1).arg(old2 + 1)
199  .arg(frameToTimestamp(new1 + 1, fps))
200  .arg(frameToTimestamp(new2 + 1, fps))
201  .arg(new1 + 1).arg(new2 + 1));
202  }
203  breakMap->remove(brkb);
204  breakMap->insert(brkb, nframes - brkb);
205  removed = true;
206  }
207  }
208  else
209  {
210  /* Extend break "bb" to cover "bbnext"; delete "bbnext". */
211  if (verbose)
212  {
213  long long old1 = brkb;
214  long long old2 = segb - 1;
215  long long new1 = brkb;
216  long long new2 = bbnext.key() + *bbnext - 1;
217  LOG(VB_COMMFLAG, LOG_INFO,
218  QString("Removing segment %1-%2 (%3-%4)")
219  .arg(frameToTimestamp(segb + 1, fps))
220  .arg(frameToTimestamp(sege + 1, fps))
221  .arg(segb + 1).arg(sege + 1));
222  LOG(VB_COMMFLAG, LOG_INFO,
223  QString("Replacing break %1-%2 (%3-%4)"
224  " with %5-%6 (%7-%8)")
225  .arg(frameToTimestamp(old1 + 1, fps))
226  .arg(frameToTimestamp(old2 + 1, fps))
227  .arg(old1 + 1).arg(old2 + 1)
228  .arg(frameToTimestamp(new1 + 1, fps))
229  .arg(frameToTimestamp(new2 + 1, fps))
230  .arg(new1 + 1).arg(new2 + 1));
231  }
232  breakMap->remove(brkb);
233  breakMap->insert(brkb, bbnext.key() + *bbnext - brkb);
234 
235  bb = bbnext;
236  ++bbnext;
237  if (verbose)
238  {
239  long long start = bb.key();
240  long long end = start + *bb - 1;
241  LOG(VB_COMMFLAG, LOG_INFO,
242  QString("Removing break %1-%2 (%3-%4)")
243  .arg(frameToTimestamp(start + 1, fps))
244  .arg(frameToTimestamp(end + 1, fps))
245  .arg(start + 1).arg(end + 1));
246  }
247  breakMap->erase(bb);
248 
249  removed = true;
250  }
251  }
252 
253  return removed;
254 }
255 
256 FrameAnalyzer::FrameMap::const_iterator
258  long long markend)
259 {
260  /*
261  * Search forwards to find the earliest block "block" such that
262  *
263  * mark <= blockbegin < markend
264  *
265  * Return frameMap->constEnd() if there is no such block.
266  */
267  FrameAnalyzer::FrameMap::const_iterator block = frameMap->constBegin();
268 
269  for (; block != frameMap->constEnd(); ++block)
270  {
271  const long long bb = block.key();
272  const long long ee = bb + *block;
273  if (mark < ee)
274  {
275  if (mark <= bb && bb < markend)
276  return block;
277  break;
278  }
279  }
280  return frameMap->constEnd();
281 }
282 
283 FrameAnalyzer::FrameMap::const_iterator
285  long long markbegin, long long mark)
286 {
287  /*
288  * Search backards to find the latest block "block" such that
289  *
290  * markbegin < blockend <= mark
291  *
292  * Return frameMap->constEnd() if there is no such block.
293  */
294  FrameAnalyzer::FrameMap::const_iterator block = frameMap->constEnd();
295  for (--block; block != frameMap->constBegin(); --block)
296  {
297  const long long bb = block.key();
298  const long long ee = bb + *block;
299  if (bb < mark)
300  {
301  if (markbegin < ee && ee <= mark)
302  return block;
303  break;
304  }
305  }
306  return frameMap->constEnd();
307 }
308 
309 }; /* namespace */
310 
311 /* 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)
#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)
QMap< long long, long long > FrameMap
Definition: FrameAnalyzer.h:44
void frameAnalyzerReportMapms(const FrameAnalyzer::FrameMap *frameMap, float fps, const char *comment)