mirror of
https://github.com/steve-m/hsdaoh.git
synced 2025-12-10 07:44:41 +01:00
lib: rework synchronization logic
On Windows it apparently happens that right after startup of libuvc the first frames are 'out of order'. Require at least 5 frames to be received in order before considering the data stream synchronized.
This commit is contained in:
parent
a5375f79cc
commit
0ad2ea5b97
1 changed files with 13 additions and 8 deletions
|
|
@ -84,6 +84,7 @@ struct hsdaoh_dev {
|
||||||
uint8_t edid_seq_cnt;
|
uint8_t edid_seq_cnt;
|
||||||
int frames_since_error;
|
int frames_since_error;
|
||||||
int discard_start_frames;
|
int discard_start_frames;
|
||||||
|
unsigned int in_order_cnt;
|
||||||
uint16_t last_frame_cnt;
|
uint16_t last_frame_cnt;
|
||||||
uint16_t last_crc;
|
uint16_t last_crc;
|
||||||
uint16_t idle_cnt;
|
uint16_t idle_cnt;
|
||||||
|
|
@ -623,18 +624,22 @@ void hsdaoh_process_frame(hsdaoh_dev_t *dev, uint8_t *data, int size)
|
||||||
metadata_t meta;
|
metadata_t meta;
|
||||||
hsdaoh_extract_metadata(data, &meta, dev->width);
|
hsdaoh_extract_metadata(data, &meta, dev->width);
|
||||||
|
|
||||||
if (le32toh(meta.magic) != 0xda7acab1)
|
if (le32toh(meta.magic) != 0xda7acab1) {
|
||||||
|
dev->stream_synced = false;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* drop duplicated frames */
|
/* drop duplicated frames */
|
||||||
if (meta.framecounter == dev->last_frame_cnt)
|
if (meta.framecounter == dev->last_frame_cnt)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dev->stream_synced) {
|
if (meta.framecounter != ((dev->last_frame_cnt + 1) & 0xffff)) {
|
||||||
if (meta.framecounter != ((dev->last_frame_cnt + 1) & 0xffff))
|
dev->in_order_cnt = 0;
|
||||||
|
if (dev->stream_synced)
|
||||||
printf("Missed at least one frame, fcnt %d, expected %d!\n",
|
printf("Missed at least one frame, fcnt %d, expected %d!\n",
|
||||||
meta.framecounter, ((dev->last_frame_cnt + 1) & 0xffff));
|
meta.framecounter, ((dev->last_frame_cnt + 1) & 0xffff));
|
||||||
}
|
} else
|
||||||
|
dev->in_order_cnt++;
|
||||||
|
|
||||||
dev->last_frame_cnt = meta.framecounter;
|
dev->last_frame_cnt = meta.framecounter;
|
||||||
|
|
||||||
|
|
@ -674,7 +679,7 @@ void hsdaoh_process_frame(hsdaoh_dev_t *dev, uint8_t *data, int size)
|
||||||
frame_payload_bytes += payload_len*2;
|
frame_payload_bytes += payload_len*2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->cb)
|
if (dev->cb && dev->stream_synced)
|
||||||
dev->cb(data, frame_payload_bytes, dev->cb_ctx);
|
dev->cb(data, frame_payload_bytes, dev->cb_ctx);
|
||||||
|
|
||||||
if (frame_errors && dev->stream_synced) {
|
if (frame_errors && dev->stream_synced) {
|
||||||
|
|
@ -683,7 +688,7 @@ void hsdaoh_process_frame(hsdaoh_dev_t *dev, uint8_t *data, int size)
|
||||||
} else
|
} else
|
||||||
dev->frames_since_error++;
|
dev->frames_since_error++;
|
||||||
|
|
||||||
if (!dev->stream_synced) {
|
if (!dev->stream_synced && !frame_errors && (dev->in_order_cnt > 4)) {
|
||||||
fprintf(stderr, "Syncronized to HDMI input stream\n");
|
fprintf(stderr, "Syncronized to HDMI input stream\n");
|
||||||
dev->stream_synced = true;
|
dev->stream_synced = true;
|
||||||
}
|
}
|
||||||
|
|
@ -747,7 +752,7 @@ int hsdaoh_start_stream(hsdaoh_dev_t *dev, hsdaoh_read_cb_t cb, void *ctx)
|
||||||
uvc_perror(res, "get_mode"); /* device doesn't provide a matching stream */
|
uvc_perror(res, "get_mode"); /* device doesn't provide a matching stream */
|
||||||
} else {
|
} else {
|
||||||
/* start the UVC stream */
|
/* start the UVC stream */
|
||||||
dev->discard_start_frames = 60;
|
dev->discard_start_frames = 30;
|
||||||
res = uvc_start_streaming(dev->uvc_devh, &ctrl, _uvc_callback, (void *)dev, 0);
|
res = uvc_start_streaming(dev->uvc_devh, &ctrl, _uvc_callback, (void *)dev, 0);
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue