kopia lustrzana https://github.com/xdsopl/robot36
moved decode code into own method
rodzic
c7122665fa
commit
e579163306
314
decode.c
314
decode.c
|
@ -19,11 +19,7 @@ You should have received a copy of the CC0 Public Domain Dedication along with t
|
|||
#include "utils.h"
|
||||
#include "img.h"
|
||||
|
||||
const float hor_sync_len = 0.009;
|
||||
const float seperator_len = 0.0045;
|
||||
|
||||
const float sync_tolerance = 0.7;
|
||||
const float seperator_tolerance = 0.7;
|
||||
int first_hor_sync = 0;
|
||||
|
||||
void process_line(uint8_t *pixel, uint8_t *y_pixel, uint8_t *uv_pixel, int y_width, int uv_width, int width, int height, int n)
|
||||
{
|
||||
|
@ -157,6 +153,165 @@ int cal_header(float cnt_freq, float dat_freq, float drate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int decode(img_t **img, char *img_name, int width, int height, int *missing_sync, int *seperator_correction, float cnt_freq, float dat_freq, float drate)
|
||||
{
|
||||
const float sync_porch_len = 0.003;
|
||||
const float porch_len = 0.0015; (void)porch_len;
|
||||
const float y_len = 0.088;
|
||||
const float uv_len = 0.044;
|
||||
const float hor_len = 0.15;
|
||||
|
||||
const float hor_sync_len = 0.009;
|
||||
const float seperator_len = 0.0045;
|
||||
|
||||
const float sync_tolerance = 0.7;
|
||||
const float seperator_tolerance = 0.7;
|
||||
|
||||
static int begin_hor_sync = 0;
|
||||
static int begin_sep_evn = 0;
|
||||
static int begin_sep_odd = 0;
|
||||
static int latch_sync = 0;
|
||||
|
||||
static int y_width = 0;
|
||||
static int uv_width = 0;
|
||||
static uint8_t *y_pixel = 0;
|
||||
static uint8_t *uv_pixel = 0;
|
||||
|
||||
static int init = 0;
|
||||
if (!init) {
|
||||
y_width = drate * y_len;
|
||||
uv_width = drate * uv_len;
|
||||
y_pixel = malloc(y_width * 2);
|
||||
memset(y_pixel, 0, y_width * 2);
|
||||
uv_pixel = malloc(uv_width * 2);
|
||||
memset(uv_pixel, 0, uv_width * 2);
|
||||
init = 1;
|
||||
}
|
||||
|
||||
begin_hor_sync = fabsf(cnt_freq - 1200.0) < 50.0 ? begin_hor_sync + 1 : 0;
|
||||
begin_sep_evn = fabsf(dat_freq - 1500.0) < 50.0 ? begin_sep_evn + 1 : 0;
|
||||
begin_sep_odd = fabsf(dat_freq - 2300.0) < 350.0 ? begin_sep_odd + 1 : 0;
|
||||
|
||||
int sep_evn = begin_sep_evn >= (int)(drate * seperator_tolerance * seperator_len) ? 1 : 0;
|
||||
int sep_odd = begin_sep_odd >= (int)(drate * seperator_tolerance * seperator_len) ? 1 : 0;
|
||||
|
||||
// we want a pulse at the falling edge
|
||||
latch_sync = begin_hor_sync > (int)(drate * sync_tolerance * hor_sync_len) ? 1 : latch_sync;
|
||||
int hor_sync = begin_hor_sync > (int)(drate * sync_tolerance * hor_sync_len) ? 0 : latch_sync;
|
||||
latch_sync = hor_sync ? 0 : latch_sync;
|
||||
|
||||
// we wait until first sync
|
||||
if (first_hor_sync && !hor_sync)
|
||||
return 0;
|
||||
|
||||
static int y = 0;
|
||||
static int odd = 0;
|
||||
static int y_pixel_x = 0;
|
||||
static int uv_pixel_x = 0;
|
||||
|
||||
static int hor_ticks = -1;
|
||||
hor_ticks++;
|
||||
|
||||
// data comes after first sync
|
||||
if (first_hor_sync && hor_sync) {
|
||||
first_hor_sync = 0;
|
||||
hor_ticks = 0;
|
||||
y_pixel_x = 0;
|
||||
uv_pixel_x = 0;
|
||||
y = 0;
|
||||
odd = 0;
|
||||
if (*img) {
|
||||
close_img(*img);
|
||||
fprintf(stderr, "%d missing sync's and %d corrections from seperator\n", *missing_sync, *seperator_correction);
|
||||
*missing_sync = 0;
|
||||
*seperator_correction = 0;
|
||||
}
|
||||
if (img_name) {
|
||||
if (!open_img_write(img, img_name, width, height))
|
||||
exit(1);
|
||||
} else {
|
||||
if (!open_img_write(img, string_time("%F_%T.ppm"), width, height))
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if horizontal sync is too early, we reset to the beginning instead of ignoring
|
||||
if (hor_sync && hor_ticks < (int)((hor_len - sync_porch_len) * drate)) {
|
||||
hor_ticks = 0;
|
||||
y_pixel_x = 0;
|
||||
uv_pixel_x = 0;
|
||||
}
|
||||
|
||||
// we always sync if sync pulse is where it should be.
|
||||
if (hor_sync && (hor_ticks >= (int)((hor_len - sync_porch_len) * drate) &&
|
||||
hor_ticks < (int)((hor_len + sync_porch_len) * drate))) {
|
||||
process_line((*img)->pixel, y_pixel, uv_pixel, y_width, uv_width, width, height, y++);
|
||||
if (y == height) {
|
||||
close_img(*img);
|
||||
fprintf(stderr, "%d missing sync's and %d corrections from seperator\n", *missing_sync, *seperator_correction);
|
||||
*img = 0;
|
||||
*missing_sync = 0;
|
||||
*seperator_correction = 0;
|
||||
return 1;
|
||||
}
|
||||
odd ^= 1;
|
||||
hor_ticks = 0;
|
||||
y_pixel_x = 0;
|
||||
uv_pixel_x = 0;
|
||||
}
|
||||
|
||||
// if horizontal sync is missing, we extrapolate from last sync
|
||||
if (hor_ticks >= (int)((hor_len + sync_porch_len) * drate)) {
|
||||
process_line((*img)->pixel, y_pixel, uv_pixel, y_width, uv_width, width, height, y++);
|
||||
if (y == height) {
|
||||
close_img(*img);
|
||||
fprintf(stderr, "%d missing sync's and %d corrections from seperator\n", *missing_sync, *seperator_correction);
|
||||
*img = 0;
|
||||
*missing_sync = 0;
|
||||
*seperator_correction = 0;
|
||||
return 1;
|
||||
}
|
||||
odd ^= 1;
|
||||
(*missing_sync)++;
|
||||
hor_ticks -= (int)(hor_len * drate);
|
||||
// we are not at the pixels yet, so no correction here
|
||||
y_pixel_x = 0;
|
||||
uv_pixel_x = 0;
|
||||
}
|
||||
|
||||
static int odd_count = 0;
|
||||
static int evn_count = 0;
|
||||
|
||||
if (hor_ticks > (int)((sync_porch_len + y_len) * drate) && hor_ticks < (int)((sync_porch_len + y_len + seperator_len) * drate)) {
|
||||
odd_count += sep_odd;
|
||||
evn_count += sep_evn;
|
||||
}
|
||||
// we try to correct from odd / even seperator
|
||||
if (evn_count != odd_count && hor_ticks > (int)((sync_porch_len + y_len + seperator_len) * drate)) {
|
||||
// even seperator
|
||||
if (evn_count > odd_count && odd) {
|
||||
odd = 0;
|
||||
(*seperator_correction)++;
|
||||
}
|
||||
// odd seperator
|
||||
if (odd_count > evn_count && !odd) {
|
||||
odd = 1;
|
||||
(*seperator_correction)++;
|
||||
}
|
||||
evn_count = 0;
|
||||
odd_count = 0;
|
||||
}
|
||||
// TODO: need better way to compensate for pulse decay time
|
||||
float fixme = 0.0007;
|
||||
if (y_pixel_x < y_width && hor_ticks >= (int)((fixme + sync_porch_len) * drate))
|
||||
y_pixel[y_pixel_x++ + (y % 2) * y_width] = fclampf(255.0 * (dat_freq - 1500.0) / 800.0, 0.0, 255.0);
|
||||
|
||||
if (uv_pixel_x < uv_width && hor_ticks >= (int)((fixme + sync_porch_len + y_len + seperator_len + porch_len) * drate))
|
||||
uv_pixel[uv_pixel_x++ + odd * uv_width] = fclampf(255.0 * (dat_freq - 1500.0) / 800.0, 0.0, 255.0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pcm_t *pcm;
|
||||
|
@ -186,20 +341,9 @@ int main(int argc, char **argv)
|
|||
float complex cnt_last = -I;
|
||||
float complex dat_last = -I;
|
||||
|
||||
int begin_hor_sync = 0;
|
||||
int begin_sep_evn = 0;
|
||||
int begin_sep_odd = 0;
|
||||
int latch_sync = 0;
|
||||
|
||||
int vis_mode = 0;
|
||||
int dat_mode = 0;
|
||||
|
||||
int y = 0;
|
||||
int odd = 0;
|
||||
int odd_count = 0;
|
||||
int evn_count = 0;
|
||||
int first_hor_sync = 0;
|
||||
|
||||
#if DN && UP
|
||||
// 320 / 0.088 = 160 / 0.044 = 40000 / 11 = 3636.(36)~ pixels per second for Y, U and V
|
||||
int64_t factor_L = 40000;
|
||||
|
@ -238,11 +382,6 @@ int main(int argc, char **argv)
|
|||
|
||||
short *buff = (short *)malloc(sizeof(short) * channels * factor_M);
|
||||
|
||||
const float sync_porch_len = 0.003;
|
||||
const float porch_len = 0.0015; (void)porch_len;
|
||||
const float y_len = 0.088;
|
||||
const float uv_len = 0.044;
|
||||
const float hor_len = 0.15;
|
||||
int missing_sync = 0;
|
||||
int seperator_correction = 0;
|
||||
|
||||
|
@ -250,17 +389,7 @@ int main(int argc, char **argv)
|
|||
const int height = 240;
|
||||
img_t *img;
|
||||
|
||||
int hor_ticks = 0;
|
||||
int y_pixel_x = 0;
|
||||
int uv_pixel_x = 0;
|
||||
int y_width = drate * y_len;
|
||||
int uv_width = drate * uv_len;
|
||||
uint8_t *y_pixel = malloc(y_width * 2);
|
||||
memset(y_pixel, 0, y_width * 2);
|
||||
uint8_t *uv_pixel = malloc(uv_width * 2);
|
||||
memset(uv_pixel, 0, uv_width * 2);
|
||||
|
||||
for (int out = factor_L;; out++, hor_ticks++) {
|
||||
for (int out = factor_L;; out++) {
|
||||
if (out >= factor_L) {
|
||||
out = 0;
|
||||
if (!read_pcm(pcm, buff, factor_M))
|
||||
|
@ -280,18 +409,6 @@ int main(int argc, char **argv)
|
|||
cnt_last = cnt_q[out];
|
||||
dat_last = dat_q[out];
|
||||
|
||||
begin_hor_sync = fabsf(cnt_freq - 1200.0) < 50.0 ? begin_hor_sync + 1 : 0;
|
||||
begin_sep_evn = fabsf(dat_freq - 1500.0) < 50.0 ? begin_sep_evn + 1 : 0;
|
||||
begin_sep_odd = fabsf(dat_freq - 2300.0) < 350.0 ? begin_sep_odd + 1 : 0;
|
||||
|
||||
int sep_evn = begin_sep_evn >= (int)(drate * seperator_tolerance * seperator_len) ? 1 : 0;
|
||||
int sep_odd = begin_sep_odd >= (int)(drate * seperator_tolerance * seperator_len) ? 1 : 0;
|
||||
|
||||
// we want a pulse at the falling edge
|
||||
latch_sync = begin_hor_sync > (int)(drate * sync_tolerance * hor_sync_len) ? 1 : latch_sync;
|
||||
int hor_sync = begin_hor_sync > (int)(drate * sync_tolerance * hor_sync_len) ? 0 : latch_sync;
|
||||
latch_sync = hor_sync ? 0 : latch_sync;
|
||||
|
||||
if (cal_header(cnt_freq, dat_freq, drate)) {
|
||||
vis_mode = 1;
|
||||
dat_mode = 0;
|
||||
|
@ -313,115 +430,10 @@ int main(int argc, char **argv)
|
|||
vis_mode = 0;
|
||||
}
|
||||
|
||||
if (!dat_mode)
|
||||
continue;
|
||||
|
||||
// we wait until first sync
|
||||
if (first_hor_sync && !hor_sync)
|
||||
continue;
|
||||
|
||||
// data comes after first sync
|
||||
if (first_hor_sync && hor_sync) {
|
||||
first_hor_sync = 0;
|
||||
hor_ticks = 0;
|
||||
y_pixel_x = 0;
|
||||
uv_pixel_x = 0;
|
||||
y = 0;
|
||||
odd = 0;
|
||||
if (img) {
|
||||
close_img(img);
|
||||
fprintf(stderr, "%d missing sync's and %d corrections from seperator\n", missing_sync, seperator_correction);
|
||||
missing_sync = 0;
|
||||
seperator_correction = 0;
|
||||
}
|
||||
if (img_name) {
|
||||
if (!open_img_write(&img, img_name, width, height))
|
||||
return 1;
|
||||
} else {
|
||||
if (!open_img_write(&img, string_time("%F_%T.ppm"), width, height))
|
||||
return 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// if horizontal sync is too early, we reset to the beginning instead of ignoring
|
||||
if (hor_sync && hor_ticks < (int)((hor_len - sync_porch_len) * drate)) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
uint8_t *p = img->pixel + 3 * y * width + 3 * (width - i - 10);
|
||||
p[0] = 255;
|
||||
p[1] = 0;
|
||||
p[2] = 255;
|
||||
}
|
||||
hor_ticks = 0;
|
||||
y_pixel_x = 0;
|
||||
uv_pixel_x = 0;
|
||||
}
|
||||
|
||||
// we always sync if sync pulse is where it should be.
|
||||
if (hor_sync && (hor_ticks >= (int)((hor_len - sync_porch_len) * drate) &&
|
||||
hor_ticks < (int)((hor_len + sync_porch_len) * drate))) {
|
||||
process_line(img->pixel, y_pixel, uv_pixel, y_width, uv_width, width, height, y++);
|
||||
if (y == height) {
|
||||
close_img(img);
|
||||
fprintf(stderr, "%d missing sync's and %d corrections from seperator\n", missing_sync, seperator_correction);
|
||||
img = 0;
|
||||
if (dat_mode) {
|
||||
if (decode(&img, img_name, width, height, &missing_sync, &seperator_correction, cnt_freq, dat_freq, drate))
|
||||
dat_mode = 0;
|
||||
missing_sync = 0;
|
||||
seperator_correction = 0;
|
||||
continue;
|
||||
}
|
||||
odd ^= 1;
|
||||
hor_ticks = 0;
|
||||
y_pixel_x = 0;
|
||||
uv_pixel_x = 0;
|
||||
}
|
||||
|
||||
// if horizontal sync is missing, we extrapolate from last sync
|
||||
if (hor_ticks >= (int)((hor_len + sync_porch_len) * drate)) {
|
||||
process_line(img->pixel, y_pixel, uv_pixel, y_width, uv_width, width, height, y++);
|
||||
if (y == height) {
|
||||
close_img(img);
|
||||
fprintf(stderr, "%d missing sync's and %d corrections from seperator\n", missing_sync, seperator_correction);
|
||||
img = 0;
|
||||
dat_mode = 0;
|
||||
missing_sync = 0;
|
||||
seperator_correction = 0;
|
||||
continue;
|
||||
}
|
||||
odd ^= 1;
|
||||
missing_sync++;
|
||||
hor_ticks -= (int)(hor_len * drate);
|
||||
// we are not at the pixels yet, so no correction here
|
||||
y_pixel_x = 0;
|
||||
uv_pixel_x = 0;
|
||||
}
|
||||
|
||||
if (hor_ticks > (int)((sync_porch_len + y_len) * drate) && hor_ticks < (int)((sync_porch_len + y_len + seperator_len) * drate)) {
|
||||
odd_count += sep_odd;
|
||||
evn_count += sep_evn;
|
||||
}
|
||||
// we try to correct from odd / even seperator
|
||||
if (evn_count != odd_count && hor_ticks > (int)((sync_porch_len + y_len + seperator_len) * drate)) {
|
||||
// even seperator
|
||||
if (evn_count > odd_count && odd) {
|
||||
odd = 0;
|
||||
seperator_correction++;
|
||||
}
|
||||
// odd seperator
|
||||
if (odd_count > evn_count && !odd) {
|
||||
odd = 1;
|
||||
seperator_correction++;
|
||||
}
|
||||
evn_count = 0;
|
||||
odd_count = 0;
|
||||
}
|
||||
// TODO: need better way to compensate for pulse decay time
|
||||
float fixme = 0.0007;
|
||||
if (y_pixel_x < y_width && hor_ticks >= (int)((fixme + sync_porch_len) * drate))
|
||||
y_pixel[y_pixel_x++ + (y % 2) * y_width] = fclampf(255.0 * (dat_freq - 1500.0) / 800.0, 0.0, 255.0);
|
||||
|
||||
if (uv_pixel_x < uv_width && hor_ticks >= (int)((fixme + sync_porch_len + y_len + seperator_len + porch_len) * drate))
|
||||
uv_pixel[uv_pixel_x++ + odd * uv_width] = fclampf(255.0 * (dat_freq - 1500.0) / 800.0, 0.0, 255.0);
|
||||
}
|
||||
|
||||
if (img) {
|
||||
|
|
Ładowanie…
Reference in New Issue