27 #define LOC QString("VBI608Extractor: ")
30 const QList<uint> &raw_minimas,
const QList<uint> &raw_maximas,
31 const QList<float> &minimas,
const QList<float> &maximas)
35 for (
uint minima : std::as_const(raw_minimas))
36 raw_mins += QString(
"%1,").arg(minima);
37 for (
uint maxima : std::as_const(raw_maximas))
38 raw_maxs += QString(
"%1,").arg(maxima);
39 LOG(VB_VBI, LOG_DEBUG, QString(
"raw mins: %1").arg(raw_mins));
40 LOG(VB_VBI, LOG_DEBUG, QString(
"raw maxs: %1").arg(raw_maxs));
44 for (
float minima : std::as_const(minimas))
45 mins += QString(
"%1,").arg(minima);
46 for (
float maxima : std::as_const(maximas))
47 maxs += QString(
"%1,").arg(maxima);
48 LOG(VB_VBI, LOG_DEBUG, QString(
"mins: %1 maxs: %2")
54 float min_diff = FLT_MAX;
55 float max_diff = 0.0F;
56 float avg_diff = 0.0F;
57 for (
uint i = 1; i <
uint(list.size()); i++)
59 float diff = list[i] - list[i-1];
60 min_diff = std::min(diff, min_diff);
61 max_diff = std::max(diff, max_diff);
65 avg_diff /= (list.size() - 1);
66 if (avg_diff * 1.15F < max_diff)
68 LOG(VB_VBI, LOG_DEBUG,
"max_diff too big");
71 if (avg_diff * 0.85F > max_diff)
73 LOG(VB_VBI, LOG_DEBUG,
"min_diff too small");
89 for (
uint j = width / 8; j < width / 4; j++)
90 minv = std::min(
uint(buf[j]), minv);
92 for (
uint j = width / 8; j < width / 4; j++)
93 maxv = std::max(
uint(buf[j]), maxv);
94 uint avgv = (maxv<minv) ? 0 : minv + ((maxv-minv) / 2);
97 LOG(VB_VBI, LOG_DEBUG, QString(
"FindClocks: avgv(%1) <= 11").arg(avgv));
102 uint noise_flr_sm = std::max(
uint(0.003 * width), 2U);
103 uint noise_flr_lg = std::max(
uint(0.007 * width), noise_flr_sm+1);
106 for (
uint i = 0; i < (width/3); i++)
108 if (buf[i] > avgv+10)
110 else if (last_max>=0 && (i - last_max) <= noise_flr_sm)
112 else if (buf[i] < avgv-10)
114 else if (last_min>=0 && (i - last_min) <= noise_flr_lg)
124 if (end_idx - start_idx > noise_flr_lg)
125 m_maximas.push_back((start_idx + end_idx) * 0.5F);
130 LOG(VB_VBI, LOG_DEBUG,
LOC +
131 QString(
"FindClocks: maximas %1 < 7").arg(
m_maximas.size()));
140 float min_diff = width * 8;
141 float max_diff = 0.0F;
142 float avg_diff = 0.0F;
146 min_diff = std::min(diff, min_diff);
147 max_diff = std::max(diff, max_diff);
150 avg_diff -= min_diff;
151 avg_diff -= max_diff;
155 if (avg_diff * 1.1F < max_diff)
159 if (last_diff*1.01F >= max_diff || last_diff > avg_diff * 1.2F)
165 if ((
m_maximas.size() > 7) && (first_diff*1.01F >= max_diff))
172 if (avg_diff * 0.9F > min_diff)
177 (last_diff*0.99F <= min_diff || last_diff < avg_diff * 0.80F))
183 if ((
m_maximas.size() > 7) && (first_diff*0.99F <= min_diff))
193 LOG(VB_VBI, LOG_DEBUG,
LOC + QString(
"FindClocks: maximas: %1 != 7")
206 float center = (start_idx + end_idx) * 0.5F;
207 if (end_idx - start_idx > noise_flr_lg &&
216 LOG(VB_VBI, LOG_DEBUG,
LOC + QString(
"FindClocks: minimas: %1 != 6")
225 m_rate = (maxima_avg_diff * 7 + minima_avg_diff * 6) / 13.0F;
226 if (maxima_avg_diff == 0.0F || minima_avg_diff == 0.0F)
243 LOG(VB_VBI, LOG_DEBUG,
LOC + QString(
"FindClocks: end %1 > width %2")
250 LOG(VB_VBI, LOG_DEBUG,
LOC + QString(
"FindClocks: Clock start %1, rate %2")
260 int ywidth = picframe->
m_width;
267 for (
uint i = 0; i < max_lines; i++)
269 const unsigned char *y = picframe->
m_buffer +
270 picframe->
m_offsets[0] + (i *
static_cast<ptrdiff_t
>(ypitch));
275 maxv = std::max(
uint((y+(i *
static_cast<ptrdiff_t
>(ypitch)))[j]), maxv);
276 uint avgv = maxv / 2;
286 for (
uint j = 0; j < 8+8; j++)
290 (
m_code[found_cnt]>>1) | (bit?(1<<15):0);
297 unsigned char *Y =
const_cast<unsigned char*
>(y);
298 unsigned char *u =
const_cast<unsigned char*
>
299 (picframe->buf + picframe->offsets[1] +
300 (i*picframe->pitches[1]));
301 unsigned char *v =
const_cast<unsigned char*
>
302 (picframe->buf + picframe->offsets[2] +
303 (i*picframe->pitches[2]));
304 unsigned uwidth = picframe->pitches[1];
305 v[uwidth / 3] = 0x40;
306 for (
uint j = 0; j < 7+3+8+8; j++)
317 return found_cnt > 0;
327 maxv = std::max(
uint(buf[j]), maxv);
328 uint avgv = maxv / 2;
334 LOG(VB_VBI, LOG_DEBUG,
LOC +
"did not find VBI 608 header");
339 for (
uint j = 0; j < 8+8; j++)
357 maxv = std::max(
uint(buf[j]), maxv);
358 uint avgv = maxv / 2;
368 for (
uint j = 0; j < 8+8; j++)
381 if (
m_code[0] != UINT16_MAX)
384 cc_data[3] = (
m_code[0]) & 0xff;
385 cc_data[4] = (
m_code[0]>>8) & 0xff;
389 if (
m_code[1] != UINT16_MAX)
391 cc_data[2+(3*cc_count)] = 0x04|0x01;
392 cc_data[3+(3*cc_count)] = (
m_code[1]) & 0xff;
393 cc_data[4+(3*cc_count)] = (
m_code[1]>>8) & 0xff;
399 cc_data[0] = 0x40 | cc_count;
401 return 2+(3*cc_count);