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
|