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
|