File: evaluate.h

package info (click to toggle)
vdr-plugin-markad 4.2.15-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,084 kB
  • sloc: cpp: 22,441; python: 613; makefile: 270; sh: 95
file content (378 lines) | stat: -rw-r--r-- 16,130 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
/**
 * @file evaluate.h
 * A program for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *
 */

#ifndef __evaluate_h_
#define __evaluate_h_

#include "debug.h"
#include "global.h"
#include "marks.h"
#include "video.h"
#include "tools.h"
#include "logo.h"


// max range of search after stop mark for closing credits
#define MAX_CLOSING_CREDITS_SEARCH 25 //!< max range of search after stop mark for closing credits

#define MAX_AD_IN_FRAME 60  //!< max range of search after logo start / before logo stop marks for ad in frame with logo
// sometimes advertising in frame has text in "e.g. Werbung"
// check longer range to prevent to detect text as second logo
// changed from 35 to 60


/**
 * class to evaluate logo stop/start pair
 */
class cEvaluateLogoStopStartPair {
public:
    /**
     * class to evaluate stop / start pair for special logos (info logo, logo change nd introduction logo"
     */
    cEvaluateLogoStopStartPair(cDecoder *decoderParam, cCriteria *criteriaParam);
    ~cEvaluateLogoStopStartPair();

    /**
     * set decoder to use in this object
     * @param decoderParam    pointer to current decoder to use in this object
     */
    void SetDecoder(cDecoder *decoderParam);

    /**
     * check logo stop/start pairs
     * @param marks           object with all marks
     * @param blackMarks      object with all black screen marks
     * @param iStart          assumed start frame position
     * @param chkSTART        frame position to check start part
     * @param packetEndPart   start of end part
     * @param iStopA          assumed end mark position
     */
    void CheckLogoStopStartPairs(cMarks *marks, cMarks *blackMarks, const int iStart, const int chkSTART, const int packetEndPart, const int iStopA);

    /**
     * check if logo stop/start pair can have ad in frame before/after
     * @param         marks             object with all marks
     * @param[in,out] logoStopStartPair structure of logo/stop start pair, result is stored here, isClosingCredits is set to -1 if the part is no logo change
     */
    void IsAdInFrame(cMarks *marks, sLogoStopStartPair *logoStopStartPair);

    /**
     * check if logo stop/start pair could be closing credits
     * @param[in]     marks             object with all marks
     * @param[in,out] logoStopStartPair structure of logo/stop start pair, result is stored here, isClosingCredits is set to -1 if the part is no logo change
     */
    static void IsClosingCredits(cMarks *marks, sLogoStopStartPair *logoStopStartPair);

    /**
     * check if logo stop/start pair could be a logo change
     * @param[in]     marks             object with all marks
     * @param[in,out] logoStopStartPair structure of logo/stop start pair, result is stored here, isLogoChange is set to -1 if the part is no logo change
     * @param[in]     iStart            assumed start mark position
     * @param[in]     chkSTART          search for start mark position
     */
    void IsLogoChange(cMarks *marks, sLogoStopStartPair *logoStopStartPair, const int iStart, const int chkSTART);

    /**
     * check if logo stop/start pair could be an info logo
     * @param marks             object with all marks
     * @param blackMarks        object with all black screen marks
     * @param logoStopStartPair structure of logo/stop start pair, result is stored here
     * @param startA            assumed stop frame number
     * @param iStopA            assumed stop frame number
     */
    void IsInfoLogo(cMarks *marks, cMarks *blackMarks, sLogoStopStartPair *logoStopStartPair, const int startA, const int iStopA);

    /**
     * get next logo stop/start pair
     * @param logoStopStartPair  pointer to structure of logo stop/start pair
     * @return                   true if there is a next logo stop/start pair, false otherwise
     */
    bool GetNextPair(sLogoStopStartPair *logoStopStartPair);

    /**
     * get ad in frame status from logo stop position or logo start position
     * @param stopPosition   position of the logo stop mark
     * @param startPosition  position of the logo start mark
     * @return               state
     */
    int GetIsAdInFrame(const int stopPosition, const int startPosition);

    /**
     * set ad in frame status to state
     * @param stopPosition  frame number of the logo stop mark
     * @param state new state
     */
    void SetIsAdInFrameAroundStop(const int stopPosition, const int state);

    /**
     * set info logo status to STATUS_YES
     * @param stopPosition  frame number of the logo stop mark
     * @param startPosition frame number of the logo start mark
     */
    void SetIsInfoLogo(const int stopPosition, const int startPosition);

    /**
     * set closing credits status to STATUS_YES <br>
     * stopPosition / startPosition do not need exact match, they must be inbetween stop/start pair
     * @param stopPosition              packet number of the logo stop mark
     * @param startPosition             packet number of the logo start mark
     * @param endClosingCreditsPosition mark position of end of closing credits
     * @param endClosingCreditsPTS      mark PTS of end of closing credits
     * @param state                     new state
     */
    void SetIsClosingCredits(const int stopPosition, const int startPosition, const int endClosingCreditsPosition, const int64_t endClosingCreditsPTS, const eEvaluateStatus state);

    /**
     * get closing credits status before start mark
     * @param startPosition frame number of the logo start mark
     * @return value of isClosingCredits
     */
    int GetIsClosingCreditsBefore(const int startPosition);

    /**
     * get closing credits status after mark
     * @param stopPosition frame number of the logo stop mark
     * @return value of isClosingCredits
     */
    int GetIsClosingCreditsAfter(const int stopPosition);

    /**
     * add adinframe pair
     * we need to add pair because it is not result of a logo stop/start pair
     * @param startPosition frame number of the last frame before adinframe
     * @param stopPosition  frame number of the last frame of adinframe
     */
    void AddAdInFrame(const int startPosition, const int stopPosition);


    /**
     * get closing credits status
     * @param stopPosition      frame number of logo stop mark
     * @param startPosition     frame number of logo start mark
     * @param endClosingCredits end position of closing credits
     * @return value of isClosingCredits
     */
    eEvaluateStatus GetIsClosingCredits(const int stopPosition, const int startPosition, sMarkPos *endClosingCredits);

    /** check if there is a info logo part between a logo stop/start pair
     * @param stopPosition  frame number of logo stop mark
     * @param startPosition frame number of logo start mark
     * @return true, if there is a info logo part between a logo stop/start pair
     */
    bool IncludesInfoLogo(const int stopPosition, const int startPosition);

private:
    cDecoder *decoder   = nullptr;                                  //!< pointer to decoder
    //!<
    cCriteria *criteria = nullptr;                                  //!< analyse criteria
    //!<
    std::vector<sLogoStopStartPair> logoPairVector;                 //!< logo stop/start pair vector
    //!<
    std::vector<sLogoStopStartPair>::iterator nextLogoPairIterator; //!< iterator for logo stop/start pair vector
    //!<
};


/**
 * class to calculate logo size
 */
class cDetectLogoStopStart {
public:
    /**
     * constructor for class to dectect special logo stop/start pair
     * @param decoderParam                   pointer to decoder
     * @param indexParam                     pointer to recording index
     * @param criteriaParam                  detection criteria
     * @param logoCornerParam                logo corner index
     * @param evaluateLogoStopStartPairParam class to evaluate logo stop/start pairs
     */
    cDetectLogoStopStart(cDecoder *decoderParam, cIndex *indexParam, cCriteria *criteriaParam, cEvaluateLogoStopStartPair *evaluateLogoStopStartPairParam, const int logoCornerParam);

    ~cDetectLogoStopStart();

    /**
    * copy constructor
    */
    cDetectLogoStopStart(const cDetectLogoStopStart &origin) {
        memcpy(aCorner, origin.aCorner, sizeof(origin.aCorner));
        evaluateLogoStopStartPair = origin.evaluateLogoStopStartPair;
        compareResult = origin.compareResult;
        sobel = nullptr;
        logoCorner = origin.logoCorner;
        criteria = origin.criteria;
        index = origin.index;
        decoder =origin.decoder;
    }

    /**
     * operator=
     */
    cDetectLogoStopStart &operator =(const cDetectLogoStopStart *origin) {
        memcpy(aCorner, origin->aCorner, sizeof(origin->aCorner));
        evaluateLogoStopStartPair = origin->evaluateLogoStopStartPair;
        compareResult = origin->compareResult;
        sobel = origin->sobel;
        logoCorner = origin->logoCorner;
        criteria = origin->criteria;
        index = origin->index;
        decoder = origin->decoder;
        return *this;
    }


    /**
     * find first pixel in a sobel transformed picture
     * @param      picture sobel transformed picture
     * @param      corner  source corner of picture
     * @param      width   picture width
     * @param      height  picture height
     * @param      startX  x position to start search
     * @param      startY  y position to start search
     * @param      offsetX x offset for each search step (usually +1 or -1)
     * @param      offsetY y offset for each search step (usually +1 or -1)
     */
    int FindFrameFirstPixel(const uchar *picture, const int corner, const int width, const int height, int startX, int startY, const int offsetX, const int offsetY);

    /**
     * find start position of a possible frame in a sobel transformed picture
     * @param         picture sobel transformed picture
     * @param         width   picture width
     * @param         height  picture height
     * @param[in,out] startX  in: x position to start search, out: x position of possible frame
     * @param[in,out] startY  in: y position to start search, out: y position of possible frame
     * @param         offsetX x offset for each search step (usually +1 or -1)
     * @param         offsetY y offset for each search step (usually +1 or -1)
     */
    int FindFrameStartPixel(const uchar *picture, const int width, const int height,  int startX, int startY, const int offsetX, const int offsetY);

    /**
     * find start position of a possible frame in a sobel transformed picture
     * @param         picture sobel transformed picture
     * @param         width   picture width
     * @param         height  picture height
     * @param[in]     startX  x position to start search (start pixel)
     * @param[in]     startY  y position to start search (start pixel)
     * @param         offsetX x offset for each search step (usually +1 or -1)
     * @param         offsetY y offset for each search step (usually +1 or -1)
     * @param[in,out] endX    x position from end of the frame
     * @param[in,out] endY    y position from end of the frame
     */
    int FindFrameEndPixel(const uchar *picture, const int width, const int height, const int startX, const int startY, const int offsetX, const int offsetY, int *endX, int *endY);

    /**
     * detect a frame in a sobel transformed picture
     * @param picture     plane 0 of sobel transformed picture
     * @param width       picture width in pixel
     * @param height      picture height in pixel
     * @param corner      source corner of picture
     */
    int DetectFrame(const uchar *picture, const int width, const int height, const int corner);

    /**
     * compare all frames in range and calculate similar rate
     * @param startFrame start frame number
     * @param endFrame   end frame number
     * @return true if successful, false otherwise
     */
    bool Detect(int startFrame, int endFrame);

/// detect if current logo stop/start pair contains a info logo
    /**
     * a info logo is a static alternate logo (e.g. telexext info) <br>
     * fade in/out is possible
     * @param startPos  start position of possible info logo
     * @param endPos    end position of possible info logo
     * @param hasBorder true if there is a vborder or hborder from startPos to endPos
     * @return true if part is info logo, false otherwise
     */
    bool IsInfoLogo(int startPos, int endPos, const bool hasBorder);

/// check for logo change
    /**
     * logo change parts contains dynamic changing alternative logos (used only by TELE5)
     * @return true if part contains a logo change, false otherwise
     */
    bool IsLogoChange(int startPos, int endPos);

    /**
     * check for closing credits without logo and for closing still image
     * @param startPos           start position for search (stop mark)
     * @param endPos             end position for search
     * @param endClosingCredits  new end mark position after closing credits
     * @param noLogoCornerCheck  if true we not check logo corner because there is an info logo
     */
    void ClosingCredit(int startPos, int endPos, sMarkPos *endClosingCredits, const bool noLogoCornerCheck = false);

    /**
     * check if current range is an advertising in frame with logo
     * @param startPos  start frame position
     * @param endPos    end   frame position
     * @param adInFrame position of ad in frame
     * @param isStartMark true if called to check after start mark, false if called to check before stop mark
     * @param isEndMark   true if called to check after stop mark, false if called to check before stop mark
     */
    void AdInFrameWithLogo(int startPos, int endPos,  sMarkPos *adInFrame, const bool isStartMark, const bool isEndMark);

    /**
     * check if current range is a introduction logo
     * @param startPos          search start position
     * @param endPos            end position of search
     * @param introductionStart start position of introducion logo if found
     */
    void IntroductionLogo(int startPos, int endPos, sMarkPos *introductionStart);

private:
    /**
     * compair two logos
     * @param logo1      first logo
     * @param logo2      second logo
     * @param logoHeight logo height
     * @param logoWidth  logo width
     * @param corner     logo corner
     * @param rate0      similar rate
     * @return true if compair was successful
     */
    bool CompareLogoPair(const sLogoInfo *logo1, const sLogoInfo *logo2, const int logoHeight, const int logoWidth, const int corner, int *rate0);

    cDecoder *decoder         = nullptr;  //!< decoder
    //!<
    cIndex *index             = nullptr;  //!< decoder
    //!<
    cCriteria *criteria       = nullptr;  //!< class for mark detection criteria
    //!<
    sAreaT area               = {};       //!< result area
    //!<
    int logoCorner            = -1;       //!< index of logo corner
    //!<
    cSobel *sobel             = nullptr;  //!< class for sobel transformation
    //!<
    /**
     * compare two frames
     */
    struct sCompareInfo {
        int frameNumber1          = -1;       //!< frame number 1
        //!<
        int64_t pts1              = -1;       //!< pts of frame number 1
        //!<
        int frameNumber2          = -1;       //!< frame number 2
        //!<
        int64_t pts2              = -1;       //!< pts of frame number 2
        //!<
        int rate[CORNERS]         = {0};     //!< similar rate of frame pair per corner
        //!<
        int framePortion[CORNERS] = {0};     //!< portion of frame pixels of corner
        //!<
    };
    std::vector<sCompareInfo> compareResult;                //!< vector of frame compare results
    //!<
    cEvaluateLogoStopStartPair *evaluateLogoStopStartPair;  //!< class to evaluate logo stop/start pairs
    //!<
    const char *aCorner[CORNERS] = { "TOP_LEFT", "TOP_RIGHT", "BOTTOM_LEFT", "BOTTOM_RIGHT" };  //!< array to convert corner anum to text
    //!<
};
#endif