From e49cc4039d755c8cbc50d040e07ac439502940ee Mon Sep 17 00:00:00 2001 From: Lukas Hejtmanek Date: Fri, 5 Feb 2010 22:38:09 +0100 Subject: [PATCH] testcard cleanum. hdstatation fixes - segfault and cleanup. --- ultragrid/src/main.c | 2 +- ultragrid/src/video_capture/hdstation.c | 58 ++++-------- ultragrid/src/video_capture/testcard.c | 120 ++++++++++++------------ 3 files changed, 78 insertions(+), 102 deletions(-) diff --git a/ultragrid/src/main.c b/ultragrid/src/main.c index c225bba06..4b867301e 100644 --- a/ultragrid/src/main.c +++ b/ultragrid/src/main.c @@ -256,7 +256,7 @@ static void *ihdtv_reciever_thread(void *arg) while (!should_exit) { if (ihdtv_recieve - (connection, frame_buffer->data, hd_size_x * hd_size_y * 3)) + (connection, frame_buffer->data, frame_buffer->data_len)) return 0; // we've got some error. probably empty buffer display_put_frame(display_device, frame_buffer->data); frame_buffer = display_get_frame(display_device); diff --git a/ultragrid/src/video_capture/hdstation.c b/ultragrid/src/video_capture/hdstation.c index 938567882..e485eaabe 100644 --- a/ultragrid/src/video_capture/hdstation.c +++ b/ultragrid/src/video_capture/hdstation.c @@ -73,7 +73,6 @@ struct vidcap_hdstation_state { sv_fifo_buffer *dma_buffer; char *rtp_buffer; char *tmp_buffer; - int buffer_size; pthread_t thread_id; pthread_mutex_t lock; pthread_cond_t boss_cv; @@ -85,7 +84,7 @@ struct vidcap_hdstation_state { int bufs_index; codec_t codec; uint32_t hd_video_mode; - double bpp; + struct video_frame frame; }; static void *vidcap_hdstation_grab_thread(void *arg) @@ -108,7 +107,7 @@ static void *vidcap_hdstation_grab_thread(void *arg) } s->bufs_index = (s->bufs_index + 1) % 2; s->dma_buffer->dma.addr = s->bufs[s->bufs_index]; - s->dma_buffer->dma.size = s->buffer_size; + s->dma_buffer->dma.size = s->frame.data_len; res = sv_fifo_putbuffer(s->sv, s->fifo, s->dma_buffer, NULL); if (res != SV_OK) { @@ -140,25 +139,12 @@ static void *vidcap_hdstation_grab_thread(void *arg) struct vidcap_type *vidcap_hdstation_probe(void) { struct vidcap_type *vt; - sv_handle *sv; - - sv = sv_open(""); - if (sv == NULL) { - debug_msg("Cannot probe HDTV capture device\n"); - return NULL; - } - sv_close(sv); - - hd_size_x = 1920; - hd_size_y = 1080; vt = (struct vidcap_type *)malloc(sizeof(struct vidcap_type)); if (vt != NULL) { vt->id = VIDCAP_HDSTATION_ID; vt->name = "hdtv"; vt->description = "DVS HDstation (SMPTE 274M/25i)"; - vt->width = hd_size_x; - vt->height = hd_size_y; } return vt; } @@ -170,6 +156,13 @@ void *vidcap_hdstation_init(char *fmt) int i; int res; + s = (struct vidcap_hdstation_state *) + malloc(sizeof(struct vidcap_hdstation_state)); + if (s == NULL) { + debug_msg("Unable to allocate HDstation state\n"); + return NULL; + } + if (fmt != NULL) { if (strcmp(fmt, "help") == 0) { printf("hdstation options:\n"); @@ -195,7 +188,7 @@ void *vidcap_hdstation_init(char *fmt) for (i = 0; codec_info[i].name != NULL; i++) { if (strcmp(tmp, codec_info[i].name) == 0) { s->codec = codec_info[i].codec; - s->bpp = codec_info[i].bpp; + s->frame.src_bpp = codec_info[i].bpp; } } if (s->codec == 0xffffffff) { @@ -220,16 +213,9 @@ void *vidcap_hdstation_init(char *fmt) return 0; } - hd_size_x = 1920; - hd_size_y = 1080; - hd_color_spc = s->codec; - - s = (struct vidcap_hdstation_state *) - malloc(sizeof(struct vidcap_hdstation_state)); - if (s == NULL) { - debug_msg("Unable to allocate HDstation state\n"); - return NULL; - } + s->frame.width = 1920; + s->frame.height = 1080; + s->frame.color_spec = s->codec; s->sv = sv_open(""); if (s->sv == NULL) { @@ -260,16 +246,17 @@ void *vidcap_hdstation_init(char *fmt) pthread_cond_init(&(s->boss_cv), NULL); pthread_cond_init(&(s->worker_cv), NULL); - s->buffer_size = s->bpp * hd_size_x * hd_size_y; + s->frame.data_len = s->frame.src_bpp * s->frame.width * s->frame.height; s->rtp_buffer = NULL; s->dma_buffer = NULL; s->tmp_buffer = NULL; s->boss_waiting = FALSE; s->worker_waiting = FALSE; s->work_to_do = FALSE; - s->bufs[0] = malloc(s->buffer_size); - s->bufs[1] = malloc(s->buffer_size); + s->bufs[0] = malloc(s->frame.data_len); + s->bufs[1] = malloc(s->frame.data_len); s->bufs_index = 0; + s->frame.state = s; if (pthread_create (&(s->thread_id), NULL, vidcap_hdstation_grab_thread, s) != 0) { @@ -300,7 +287,6 @@ struct video_frame *vidcap_hdstation_grab(void *state) { struct vidcap_hdstation_state *s = (struct vidcap_hdstation_state *)state; - struct video_frame *vf; pthread_mutex_lock(&(s->lock)); @@ -323,14 +309,8 @@ struct video_frame *vidcap_hdstation_grab(void *state) pthread_mutex_unlock(&(s->lock)); if (s->rtp_buffer != NULL) { - vf = (struct video_frame *)malloc(sizeof(struct video_frame)); - if (vf != NULL) { - vf->width = hd_size_x; - vf->height = hd_size_y; - vf->data = s->rtp_buffer; - vf->data_len = hd_size_x * hd_size_y * s->bpp; - } - return vf; + s->frame.data = s->rtp_buffer; + return &s->frame; } return NULL; } diff --git a/ultragrid/src/video_capture/testcard.c b/ultragrid/src/video_capture/testcard.c index 3c929f9d1..ab795b56f 100644 --- a/ultragrid/src/video_capture/testcard.c +++ b/ultragrid/src/video_capture/testcard.c @@ -75,14 +75,11 @@ struct testcard_state { struct timeval last_frame_time; int fps; int count; - unsigned int width; - unsigned int height; int size; - char *frame; - int linesize; int pan; SDL_Surface *surface; struct timeval t0; + struct video_frame frame; }; const int rect_colors[] = { @@ -267,7 +264,7 @@ void *vidcap_testcard_init(char *fmt) struct stat sb; unsigned int i, j; unsigned int rect_size = COL_NUM; - codec_t codec; + codec_t codec=0; int aligned_x; if (strcmp(fmt, "help") == 0) { @@ -290,17 +287,16 @@ void *vidcap_testcard_init(char *fmt) free(s); return NULL; } - s->width = atoi(tmp); + s->frame.width = atoi(tmp); tmp = strtok(NULL, ":"); if (!tmp) { fprintf(stderr, "Wrong format for testcard '%s'\n", fmt); free(s); return NULL; } - s->height = atoi(tmp); + s->frame.height = atoi(tmp); tmp = strtok(NULL, ":"); if (!tmp) { - free(s->frame); free(s); fprintf(stderr, "Wrong format for testcard '%s'\n", fmt); return NULL; @@ -310,7 +306,6 @@ void *vidcap_testcard_init(char *fmt) tmp = strtok(NULL, ":"); if (!tmp) { - free(s->frame); free(s); fprintf(stderr, "Wrong format for testcard '%s'\n", fmt); return NULL; @@ -328,20 +323,25 @@ void *vidcap_testcard_init(char *fmt) } } - aligned_x = s->width; + if(bpp == 0) { + fprintf(stderr, "Unknown codec '%s'\n", tmp); + return NULL; + } + + aligned_x = s->frame.width; if (h_align) { aligned_x = (aligned_x + h_align - 1) / h_align * h_align; } - rect_size = (s->width + rect_size - 1) / rect_size; + rect_size = (s->frame.width + rect_size - 1) / rect_size; - s->linesize = aligned_x * bpp; + s->frame.src_linesize = aligned_x * bpp; - s->size = aligned_x * s->height * bpp; + s->size = aligned_x * s->frame.height * bpp; filename = strtok(NULL, ":"); if (filename && strcmp(filename, "p") != 0) { - s->frame = malloc(s->size); + s->frame.data = malloc(s->size); if (stat(filename, &sb)) { perror("stat"); free(s); @@ -354,14 +354,14 @@ void *vidcap_testcard_init(char *fmt) fprintf(stderr, "Error wrong file size for selected " "resolution and codec. File size %d, " "computed size %d\n", (int)sb.st_size, s->size); - free(s->frame); + free(s->frame.data); free(s); return NULL; } - if (!in || fread(s->frame, sb.st_size, 1, in) == 0) { + if (!in || fread(s->frame.data, sb.st_size, 1, in) == 0) { fprintf(stderr, "Cannot read file %s\n", filename); - free(s->frame); + free(s->frame.data); free(s); return NULL; } @@ -371,17 +371,17 @@ void *vidcap_testcard_init(char *fmt) SDL_Rect r; int col_num = 0; s->surface = - SDL_CreateRGBSurface(SDL_SWSURFACE, aligned_x, s->height, + SDL_CreateRGBSurface(SDL_SWSURFACE, aligned_x, s->frame.height, 32, 0xff, 0xff00, 0xff0000, 0xff000000); if (filename && filename[0] == 'p') { s->pan = 48; } - for (j = 0; j < s->height; j += rect_size) { + for (j = 0; j < s->frame.height; j += rect_size) { int grey = 0xff010101; if (j == rect_size * 2) { - r.w = s->width; + r.w = s->frame.width; r.h = rect_size / 4; r.x = 0; r.y = j; @@ -389,7 +389,7 @@ void *vidcap_testcard_init(char *fmt) r.y = j + rect_size * 3 / 4; SDL_FillRect(s->surface, &r, 0); } - for (i = 0; i < s->width; i += rect_size) { + for (i = 0; i < s->frame.width; i += rect_size) { r.w = rect_size; r.h = rect_size; r.x = i; @@ -407,20 +407,20 @@ void *vidcap_testcard_init(char *fmt) } } } - s->frame = s->surface->pixels; + s->frame.data = s->surface->pixels; if (codec == UYVY || codec == v210 || codec == Vuy2) { - rgb2yuv422((unsigned char *)s->frame, s->width, - s->height); + rgb2yuv422((unsigned char *)s->frame.data, s->frame.width, + s->frame.height); } if (codec == v210) { - s->frame = - (char *)tov210((unsigned char *)s->frame, s->width, - aligned_x, s->height, bpp); + s->frame.data = + (char *)tov210((unsigned char *)s->frame.data, s->frame.width, + aligned_x, s->frame.height, bpp); } if (codec == R10k) { - toR10k((unsigned char *)s->frame, s->width, s->height); + toR10k((unsigned char *)s->frame.data, s->frame.width, s->frame.height); } } @@ -434,7 +434,10 @@ void *vidcap_testcard_init(char *fmt) s->count = 0; gettimeofday(&(s->last_frame_time), NULL); - printf("Testcard set to %dx%d, bpp %f\n", s->width, s->width, bpp); + printf("Testcard set to %dx%d, bpp %f\n", s->frame.width, s->frame.width, bpp); + + s->frame.state = s; + s->frame.data_len = s->size; return s; } @@ -442,8 +445,8 @@ void *vidcap_testcard_init(char *fmt) void vidcap_testcard_done(void *state) { struct testcard_state *s = state; - if (s->frame != s->surface->pixels) - free(s->frame); + if (s->frame.data != s->surface->pixels) + free(s->frame.data); if (s->surface) SDL_FreeSurface(s->surface); free(s); @@ -453,7 +456,6 @@ struct video_frame *vidcap_testcard_grab(void *arg) { struct timeval curr_time; struct testcard_state *state; - struct video_frame *vf; state = (struct testcard_state *)arg; @@ -472,37 +474,31 @@ struct video_frame *vidcap_testcard_grab(void *arg) state->count = 0; } - vf = (struct video_frame *)malloc(sizeof(struct video_frame)); - if (vf != NULL) { - char line[state->linesize * 2 + state->pan]; - unsigned int i; - vf->width = state->width; - vf->height = state->height; - vf->data = state->frame; - vf->data_len = state->size; - memcpy(line, state->frame, - state->linesize * 2 + state->pan); - for (i = 0; i < hd_size_y - 3; i++) { - memcpy(state->frame + i * state->linesize, - state->frame + (i + - 2) * state->linesize + - state->pan, state->linesize); - } - memcpy(state->frame + i * state->linesize, - state->frame + (i + 2) * state->linesize + - state->pan, state->linesize - state->pan); - memcpy(state->frame + - (hd_size_y - 2) * state->linesize - state->pan, - line, state->linesize * 2 + state->pan); - /*if(!(state->count % 2)) { - unsigned int *p = state->frame; - for(i=0; i < state->linesize*hd_size_y/4; i++) { - *p = *p ^ 0x00ffffffL; - p++; - } - } */ + char line[state->frame.src_linesize * 2 + state->pan]; + unsigned int i; + memcpy(line, state->frame.data, + state->frame.src_linesize * 2 + state->pan); + for (i = 0; i < state->frame.height - 3; i++) { + memcpy(state->frame.data + i * state->frame.src_linesize, + state->frame.data + (i + 2) * state->frame.src_linesize + + state->pan, state->frame.src_linesize); } - return vf; + memcpy(state->frame.data + i * state->frame.src_linesize, + state->frame.data + (i + 2) * state->frame.src_linesize + + state->pan, state->frame.src_linesize - state->pan); + memcpy(state->frame.data + + (state->frame.height - 2) * state->frame.src_linesize - state->pan, + line, state->frame.src_linesize * 2 + state->pan); +#ifdef USE_EPILEPSY + if(!(state->count % 2)) { + unsigned int *p = state->frame.data; + for(i=0; i < state->frame.src_linesize*state->frame.height/4; i++) { + *p = *p ^ 0x00ffffffL; + p++; + } + } +#endif + return &state->frame; } return NULL; }