File: logo.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 (300 lines) | stat: -rw-r--r-- 10,850 bytes parent folder | download | duplicates (2)
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
/*
 * logo.h: A program for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *
 */

#ifndef __logo_h_
#define __logo_h_

#include "global.h"
#include "debug.h"
#include "tools.h"
#include "video.h"
#include "decoder.h"
#include "audio.h"
#include "sobel.h"
#include "index.h"
#include "sobel.h"


#define TOP_LEFT     0
#define TOP_RIGHT    1
#define BOTTOM_LEFT  2
#define BOTTOM_RIGHT 3

#define LOGO_SEARCH_ERROR  -1
#define LOGO_SEARCH_FOUND   0

/**
 * logo after sobel transformation
 */
struct sLogoInfo {
    int frameNumber = -1;      //!< frame number of the logo
    //!<
    int64_t pts     = -1;      //!< pts of frame number of the logo
    //!<
    int hits        = 0;       //!< number of similar other logos
    //!<
    bool resized    = false;   //!< true if Resize() was done
    //!<
    uchar **sobel   = nullptr; //!< sobel transformed corner picture data
    //!<
};


/**
 * class to extract logo from recording
 */
class cExtractLogo : protected cTools {
public:

    /**
     * constructor for class to search end extract logo from recording
     * @param recDirParam          recording directory
     * @param channelNameParam     channel name
     * @param threads              count of FFmpeg threads
     * @param fullDecodeParam      true for full decoding
     * @param hwaccel              device type of hwaccel
     * @param forceHW              force hwaccel for MPEG2 codec
     * @param requestedAspectRatio video aspect ratio for requested logo
     */
    explicit cExtractLogo(const char *recDirParam, const char *channelNameParam, const int threads, const bool fullDecodeParam, char *hwaccel, const bool forceHW, const sAspectRatio requestedAspectRatio);
    ~cExtractLogo();

    /**
     * copy constructor
     */
    cExtractLogo(const cExtractLogo &origin) {
        recDir              = nullptr;
        channelName         = nullptr;
        decoder             = nullptr;
        criteria            = nullptr;
        sobel               = nullptr;
        hBorder             = nullptr;
        vborder             = nullptr;
        fullDecode          = origin.fullDecode;
        recordingFrameCount = origin.recordingFrameCount;
        audioState          = origin.audioState;
        memcpy(aCorner, origin.aCorner, sizeof(origin.aCorner));
        for (int i = 0; i < CORNERS; i++) {
            logoInfoVector[i]   = origin.logoInfoVector[i];
        }
    }

    /**
     * operator=
     */
    cExtractLogo &operator =(const cExtractLogo *origin) {
        recDir              = nullptr;
        channelName         = nullptr;
        decoder             = nullptr;
        criteria            = nullptr;
        sobel               = nullptr;
        hBorder             = nullptr;
        vborder             = nullptr;
        fullDecode          = origin->fullDecode;
        recordingFrameCount = origin->recordingFrameCount;
        audioState          = origin->audioState;
        memcpy(aCorner, origin->aCorner, sizeof(origin->aCorner));
        for (int i = 0; i < CORNERS; i++) {
            logoInfoVector[i]   = origin->logoInfoVector[i];
        }
        return *this;
    }

    /**
     * search and extract logo from recording
     * @param startPacket   frame number to start search
     * @param force         finding a logo, even on weak matches
     * @return last read frame during search
     */
    int SearchLogo(int startPacket, const bool force);

    /**
     * compare logo pair
     * @param logo1      pixel map of logo 1
     * @param logo2      pixel map of logo 2
     * @param logoHeight logo height
     * @param logoWidth  logo width
     * @param corner     logo corner
     * @param match0     minimum requested rate of similars in pane 0 to thread as similar
     * @param match12    minimum requested rate of similars in pane 1 and 2 to thread as similar
     * @param[out] rate0 match rate of the two logos
     * @return true if logo pair is similar, false otherwise
     */
    bool CompareLogoPair(const sLogoInfo *logo1, const sLogoInfo *logo2, const int logoHeight, const int logoWidth, const int corner, int match0 = 0, int match12 = 0, int *rate0 = nullptr);

    /**
     * manually extrct logo from recording
     * @param corner  video picture corner
     * @param width   logo width
     * @param height  logo height
     */
    void ManuallyExtractLogo(const int corner, const int width, const int height);

private:
    /**
     * save logo picture, used for debugging
     * @param actLogoInfo logo pixel map
     * @param logoSizeFinal   logo size of final selected logo
     * @param logoAspectRatio logo from this video aspect ratio
     * @param corner          logo corner
     * @return                true if saved successful, false otherwise
     */
    bool SaveLogo(const sLogoInfo *actLogoInfo, sLogoSize *logoSizeFinal, const sAspectRatio logoAspectRatio, const int corner);

    /**
     * check if logo is valid
     * @param actLogoInfo logo pixel map
     * @param corner          logo corner
     * @return                true if logo is valid
     */
    bool CheckValid(const sLogoInfo *actLogoInfo, const int corner);

    /**
     * compare logo with all other in list
     * @param actLogoInfo pixel map of logo
     * @param logoHeight      logo height
     * @param logoWidth       logo width
     * @param corner          logo corner
     * @return                true if logo pair is similar, false otherwise
     */
    int Compare(sLogoInfo *actLogoInfo, const int logoHeight, const int logoWidth, const int corner);

    /**
     * compare rotating logo pair
     * @param logo1      pixel map of logo 1
     * @param logo2      pixel map of logo 2
     * @param logoHeight logo height
     * @param logoWidth  logo width
     * @param corner     logo corner
     * @return true if logo pair is similar, false otherwise
     */
    bool CompareLogoPairRotating(sLogoInfo *logo1, sLogoInfo *logo2, const int logoHeight, const int logoWidth, const int corner);

    /**
     * cut logo picture
     * @param logoInfo              logo pixel map
     * @param cutPixelH             number of pixel to cut off horizontal
     * @param cutPixelV             number of pixel ro cut off vertical
     * @param[in,out] logoSizeFinal logo size of final setected logo
     * @param corner                logo corner
     */
    void CutOut(sLogoInfo *logoInfo, int cutPixelH, int cutPixelV, sLogoSize *logoSizeFinal, const int corner) const;

    /**
     * check if found logo size and corner is valid
     * @param logoSizeFinal final logo size
     * @param logoCorner    corner of logo
     * @return              true if logo size and corner is valid, false otherwise
     */
    bool CheckLogoSize(sLogoSize *logoSizeFinal, const int logoCorner);

    /**
     * remove white frame and resize logo
     * @param bestLogoInfo          logo pixel map
     * @param[in,out] logoSizeFinal size of final setected logo
     * @param bestLogoCorner        logo corner
     * @return                      true if successful, false otherwise
     */
    bool Resize(sLogoInfo *bestLogoInfo, sLogoSize *logoSizeFinal, const int bestLogoCorner);

    /**
     * check of plane has pixel
     * @param actLogoInfo logo pixel
     * @param logoSizePlane   logo size of this plane
     * @param plane           pixel plane number
     * @return                true if there are no pixel, false otherwise
     */
    static bool IsWhitePlane(const sLogoInfo *actLogoInfo, const sLogoSize logoSizePlane, const int plane);

    /**
     * check of logo had a changed colour
     * @param logoSizeFinal  final size of selected logo
     * @param corner         logo corner
     * @param plane          number of plane
     * @return               true if logo changed colour, false otherwise
     */
    bool IsLogoColourChange(const sLogoSize *logoSizeFinal, const int corner, const int plane);

    /**
     * delete frames from logo list
     * @param from      start frame to delete from
     * @param to        end frame
     * @return          number of deleted frames
     */
    int DeleteFrames(const int from, const int to);

    /**
     * wait for more frames if markad runs during recording
     * @param decoder   pointer to decoder
     * @param minFrame  minimum framenumber we need
     * @return          true if we have enough frames, false otherwise
     */
    bool WaitForFrames(const cDecoder *decoder, const int minFrame);

    /**
     * get first frame number of stored logos
     * @return first frame number of stored logos
     */
    int GetFirstFrame();

    /**
     * get last frame number of stored logos
     * @return last frame number of stored logos
     */
    int GetLastFrame();

    /**
     * count of stored logo frames
     * @return count of stored logo frames
     */
    int CountFrames();

    /**
     * remove single pixel defect in logo
     * @param [in,out] logoInfo logo pixel map
     * @param corner            logo corner
     */
    void RemovePixelDefects(sLogoInfo *logoInfo, const int corner);

    /**
     * check audio channel status
     * @return  0 = undefined, 1 = got first 2 channel, 2 = now 6 channel, 3 now 2 channel
     */
    int AudioInBroadcast();

    const char *recDir                    = nullptr;      //!< recording directory
    //!<
    const char *channelName               = nullptr;      //!< channel name, used for logo file name
    //!<
    cDecoder *decoder                     = nullptr;      //!< pointer to decoder
    //!<
    cCriteria *criteria                   = nullptr;      //!< channel criteria for logo detection
    //!<
    bool fullDecode                       = false;        //!< true if we do full decoding
    //!<
    sAreaT area                           = {};           //!< sobel transformed pixels of logo area
    //!<
    cSobel *sobel                         = nullptr;      //!< pointer to sobel transformation
    //!<
    cHorizBorderDetect *hBorder           = nullptr;      //!< pointer to hBorder detection
    //!<
    cVertBorderDetect *vborder            = nullptr;      //!< pointer to hBorder detection
    //!<
    int recordingFrameCount               = 0;            //!< frame count of the recording
    //!<
    sAspectRatio requestedLogoAspectRatio = {0};          //!< aspect ratio of requested logo
    //!<
    int audioState                        = 0;            //!< 0 = undefined, 1 = got first 2 channel, 2 = now 6 channel, 3 now 2 channel
    //!<
    const char *aCorner[CORNERS]          = { "TOP_LEFT", "TOP_RIGHT", "BOTTOM_LEFT", "BOTTOM_RIGHT" }; //!< array to transform enum corner to text
    //!<
    std::vector<sLogoInfo> logoInfoVector[CORNERS];   //!< infos of all proccessed logos
    //!<


};
#endif