예제 #1
0
static void dxt_glsl_compress_done(struct module *mod)
{
        struct state_video_compress_rtdxt *s = (struct state_video_compress_rtdxt *) mod->priv_data;
        int i, x;
        
        if(s->out[0]) {
                for(int i = 0; i < (int) s->out[0]->tile_count; ++i) {
                        if(s->encoder[i])
                                dxt_encoder_destroy(s->encoder[i]);
                }
        }

        for (i = 0; i < 2; ++i) {
                if(s->out[i]) {
                        for (x = 0; x < (int) s->out[i]->tile_count; ++x) {
                                free(s->out[i]->tiles[x].data);
                        }
                }
                vf_free(s->out[i]);
        }

        free(s->decoded);

        destroy_gl_context(&s->gl_context);

        free(s);
}
예제 #2
0
static void vidcap_testcard_done(void *state)
{
        struct testcard_state *s = (struct testcard_state *) state;
        free(s->data);
        if (s->tiled) {
                int i;
                for (i = 0; i < s->tiles_cnt_horizontal; ++i) {
                        free(s->tiles_data[i]);
                }
                vf_free(s->tiled);
        }
        vf_free(s->frame);
        if(s->audio_data) {
                free(s->audio_data);
        }
        delete s;
}
예제 #3
0
/**
 * Compresses video frame with tiles API
 *
 * @param[in]     s             compress state
 * @param[in]     frame         uncompressed frame
 * @param         buffer_index  0 or 1 - driver should have 2 output buffers, filling the selected one.
 *                Returned video frame should stay valid until requesting compress with the
 *                same index.
 * @param         parent        parent module (for the case when there is a need to reconfigure)
 * @return                      compressed video frame, may be NULL if compression failed
 */
static struct video_frame *compress_frame_tiles(struct compress_state_real *s, struct video_frame *frame,
        int buffer_index, struct module *parent)
{
    if(frame->tile_count != s->state_count) {
        s->state = realloc(s->state, frame->tile_count * sizeof(struct module *));
        for(unsigned int i = s->state_count; i < frame->tile_count; ++i) {
            char compress_options[1024];
            strncpy(compress_options, s->compress_options, sizeof(compress_options));
            compress_options[sizeof(compress_options) - 1] = '\0';
            s->state[i] = s->handle->init_func(parent, compress_options);
            if(!s->state[i]) {
                fprintf(stderr, "Compression initialization failed\n");
                return NULL;
            }
        }
        for(int i = 0; i < 2; ++i) {
            vf_free(s->out_frame[i]);
            s->out_frame[i] = vf_alloc(frame->tile_count);
        }
        s->state_count = frame->tile_count;
    }

    task_result_handle_t task_handle[frame->tile_count];

    struct compress_worker_data data_tile[frame->tile_count];
    for(unsigned int i = 0; i < frame->tile_count; ++i) {
        struct compress_worker_data *data = &data_tile[i];
        data->state = s->state[i];
        data->tile = &frame->tiles[i];
        data->desc = video_desc_from_frame(frame);
        data->desc.tile_count = 1;
        data->buffer_index = buffer_index;;
        data->callback = s->handle->compress_tile_func;

        task_handle[i] = task_run_async(compress_tile_callback, data);
    }

    for(unsigned int i = 0; i < frame->tile_count; ++i) {
        struct compress_worker_data *data = wait_task(task_handle[i]);

        if(i == 0) { // update metadata from first tile
            data->desc.tile_count = frame->tile_count;
            vf_write_desc(s->out_frame[buffer_index], data->desc);
        }

        if(data->ret) {
            memcpy(&s->out_frame[buffer_index]->tiles[i], data->ret, sizeof(struct tile));
        } else {
            return NULL;
        }
    }

    return s->out_frame[buffer_index];
}
예제 #4
0
파일: v4l2.c 프로젝트: k4rtik/ultragrid
static void vidcap_v4l2_dispose_video_frame(struct video_frame *frame) {
        struct v4l2_dispose_deq_buffer_data *data =
                (struct v4l2_dispose_deq_buffer_data *) frame->dispose_udata;
        if (data) {
                if (ioctl(data->fd, VIDIOC_QBUF, &data->buf) != 0) {
                        perror("Unable to enqueue buffer");
                };
                free(data);
        } else {
                free(frame->tiles[0].data);
        }

        vf_free(frame);
}
예제 #5
0
파일: sage.cpp 프로젝트: k4rtik/ultragrid
static void display_sage_done(void *state)
{
        struct state_sage *s = (struct state_sage *)state;

        assert(s->magic == MAGIC_SAGE);

        sem_destroy(&s->semaphore);
        pthread_cond_destroy(&s->buffer_writable_cond);
        pthread_mutex_destroy(&s->buffer_writable_lock);
        vf_free(s->frame);
        if (s->sage_state)
                s->sage_state->shutdown();
        //delete s->sage_state;
        free(s);
}
예제 #6
0
void
vidcap_aggregate_done(void *state)
{
	struct vidcap_aggregate_state *s = (struct vidcap_aggregate_state *) state;

	assert(s != NULL);

	if (s != NULL) {
                int i;
		for (i = 0; i < s->devices_cnt; ++i) {
                         vidcap_done(s->devices[i]);
		}
	}
        
        vf_free(s->frame);
}
예제 #7
0
static void cleanup_state(struct state_video_compress_jpeg *s)
{
        int frame_idx;
        
        for (frame_idx = 0; frame_idx < 2; frame_idx++) {
                if(s->out[frame_idx]) {
                        int x;
                        for (x = 0; x < (int) s->out[frame_idx]->tile_count; ++x) {
                                free(s->out[frame_idx]->tiles[x].data);
                        }
                }
                vf_free(s->out[frame_idx]);
        }
        if(s->encoder)
                gpujpeg_encoder_destroy(s->encoder);
}
예제 #8
0
static void display_deltacast_done(void *state)
{
        struct state_deltacast *s = (struct state_deltacast *)state;

        if(s->initialized) {
                if(s->SlotHandle)
                        VHD_UnlockSlotHandle(s->SlotHandle);
                VHD_StopStream(s->StreamHandle);
                VHD_CloseStreamHandle(s->StreamHandle);
                VHD_SetBoardProperty(s->BoardHandle,VHD_CORE_BP_BYPASS_RELAY_0,TRUE);
                VHD_CloseBoardHandle(s->BoardHandle);
        }

        vf_free(s->frame);
        free(s);
}
예제 #9
0
static int vidcap_testcard_init(const struct vidcap_params *params, void **state)
{
        struct testcard_state *s;
        char *filename;
        const char *strip_fmt = NULL;
        FILE *in = NULL;
        unsigned int i, j;
        unsigned int rect_size = COL_NUM;
        codec_t codec = RGBA;
        int aligned_x;
        char *save_ptr = NULL;

        if (vidcap_params_get_fmt(params) == NULL || strcmp(vidcap_params_get_fmt(params), "help") == 0) {
                printf("testcard options:\n");
                printf("\t-t testcard:<width>:<height>:<fps>:<codec>[:filename=<filename>][:p][:s=<X>x<Y>][:i|:sf][:still][:pattern=bars|blank|noise]\n");
                printf("\t<filename> - use file named filename instead of default bars\n");
                printf("\tp - pan with frame\n");
                printf("\ts - split the frames into XxY separate tiles\n");
                printf("\ti|sf - send as interlaced or segmented frame (if none of those is set, progressive is assumed)\n");
                printf("\tstill - send still image\n");
                printf("\tpattern - pattern to use\n");
                show_codec_help("testcard", codecs_8b, codecs_10b);
                return VIDCAP_INIT_NOERR;
        }

        s = new testcard_state();
        if (!s)
                return VIDCAP_INIT_FAIL;

        s->frame = vf_alloc(1);

        char *fmt = strdup(vidcap_params_get_fmt(params));
        char *tmp;
        int h_align = 0;
        double bpp = 0;

        if (strlen(fmt) == 0) {
                free(fmt);
                fmt = strdup(DEFAULT_FORMAT);
        }

        tmp = strtok_r(fmt, ":", &save_ptr);
        if (!tmp) {
                fprintf(stderr, "Wrong format for testcard '%s'\n", fmt);
                goto error;
        }
        vf_get_tile(s->frame, 0)->width = atoi(tmp);
        tmp = strtok_r(NULL, ":", &save_ptr);
        if (!tmp) {
                fprintf(stderr, "Wrong format for testcard '%s'\n", fmt);
                goto error;
        }
        vf_get_tile(s->frame, 0)->height = atoi(tmp);
        tmp = strtok_r(NULL, ":", &save_ptr);
        if (!tmp) {
                fprintf(stderr, "Wrong format for testcard '%s'\n", fmt);
                goto error;
        }

        s->frame->fps = atof(tmp);

        tmp = strtok_r(NULL, ":", &save_ptr);
        if (!tmp) {
                fprintf(stderr, "Wrong format for testcard '%s'\n", fmt);
                goto error;
        }

        codec = get_codec_from_name(tmp);
        if (codec == VIDEO_CODEC_NONE) {
                fprintf(stderr, "Unknown codec '%s'\n", tmp);
                goto error;
        }
        {
                const codec_t *sets[] = {codecs_8b, codecs_10b};
                bool supported = false;
                for (int i = 0; i < 2; ++i) {
                        const codec_t *it = sets[i];
                        while (*it != VIDEO_CODEC_NONE) {
                                if (codec == *it++) {
                                        supported = true;
                                }
                        }
                }
                if (!supported) {
                        log_msg(LOG_LEVEL_ERROR, "Unsupported codec '%s'\n", tmp);
                        goto error;
                }
        }
        h_align = get_halign(codec);
        bpp = get_bpp(codec);

        s->frame->color_spec = codec;
        s->still_image = FALSE;

        if(bpp == 0) {
                fprintf(stderr, "Unsupported codec '%s'\n", tmp);
                goto error;
        }

        aligned_x = vf_get_tile(s->frame, 0)->width;
        if (h_align) {
                aligned_x = (aligned_x + h_align - 1) / h_align * h_align;
        }

        rect_size = (vf_get_tile(s->frame, 0)->width + rect_size - 1) / rect_size;

        s->frame_linesize = aligned_x * bpp;
        s->frame->interlacing = PROGRESSIVE;
        s->size = aligned_x * vf_get_tile(s->frame, 0)->height * bpp;

        filename = NULL;

        tmp = strtok_r(NULL, ":", &save_ptr);
        while (tmp) {
                if (strcmp(tmp, "p") == 0) {
                        s->pan = 48;
                } else if (strncmp(tmp, "filename=", strlen("filename=")) == 0) {
                        filename = tmp + strlen("filename=");
                        in = fopen(filename, "r");
                        if (!in) {
                                perror("fopen");
                                goto error;
                        }
                        fseek(in, 0L, SEEK_END);
                        long filesize = ftell(in);
                        assert(filesize >= 0);
                        fseek(in, 0L, SEEK_SET);

                        s->data = (char *) malloc(s->size * bpp * 2);

                        if (s->size != filesize) {
                                fprintf(stderr, "Error wrong file size for selected "
                                                "resolution and codec. File size %ld, "
                                                "computed size %d\n", filesize, s->size);
                                goto error;
                        }

                        if (!in || fread(s->data, filesize, 1, in) == 0) {
                                fprintf(stderr, "Cannot read file %s\n", filename);
                                goto error;
                        }

                        fclose(in);
                        in = NULL;

                        memcpy(s->data + s->size, s->data, s->size);
                        vf_get_tile(s->frame, 0)->data = s->data;
                } else if (strncmp(tmp, "s=", 2) == 0) {
                        strip_fmt = tmp;
                } else if (strcmp(tmp, "i") == 0) {
                        s->frame->interlacing = INTERLACED_MERGED;
                } else if (strcmp(tmp, "sf") == 0) {
                        s->frame->interlacing = SEGMENTED_FRAME;
                } else if (strcmp(tmp, "still") == 0) {
                        s->still_image = TRUE;
                } else if (strncmp(tmp, "pattern=", strlen("pattern=")) == 0) {
                        const char *pattern = tmp + strlen("pattern=");
                        if (strcmp(pattern, "bars") == 0) {
                                s->pattern = image_pattern::BARS;
                        } else if (strcmp(pattern, "blank") == 0) {
                                s->pattern = image_pattern::BLANK;
                        } else if (strcmp(pattern, "noise") == 0) {
                                s->pattern = image_pattern::NOISE;
                        } else {
                                fprintf(stderr, "[testcard] Unknown pattern!\n");;
                                goto error;
                        }
                } else {
                        fprintf(stderr, "[testcard] Unknown option: %s\n", tmp);
                        goto error;
                }
                tmp = strtok_r(NULL, ":", &save_ptr);
        }

        if (!filename) {
                struct testcard_rect r;
                int col_num = 0;
                s->pixmap.w = aligned_x;
                s->pixmap.h = vf_get_tile(s->frame, 0)->height * 2;
                int pixmap_len = s->pixmap.w * s->pixmap.h * 4; // maximal size (RGBA/r10k - has 4 bpp)
                s->pixmap.data = malloc(pixmap_len);

                if (s->pattern == image_pattern::BLANK) {
                        memset(s->pixmap.data, 0, pixmap_len);
                } else if (s->pattern == image_pattern::NOISE) {
                        uint8_t *sample = (uint8_t *) s->pixmap.data;
                        for (int i = 0; i < pixmap_len; ++i) {
                                *sample++ = rand() % 0xff;
                        }
                } else {
                        assert (s->pattern == image_pattern::BARS);
                        for (j = 0; j < vf_get_tile(s->frame, 0)->height; j += rect_size) {
                                int grey = 0xff010101;
                                if (j == rect_size * 2) {
                                        r.w = vf_get_tile(s->frame, 0)->width;
                                        r.h = rect_size / 4;
                                        r.x = 0;
                                        r.y = j;
                                        testcard_fillRect(&s->pixmap, &r, 0xffffffff);
                                        r.h = rect_size - (rect_size * 3 / 4);
                                        r.y = j + rect_size * 3 / 4;
                                        testcard_fillRect(&s->pixmap, &r, 0xff000000);
                                }
                                for (i = 0; i < vf_get_tile(s->frame, 0)->width; i += rect_size) {
                                        r.w = rect_size;
                                        r.h = rect_size;
                                        r.x = i;
                                        r.y = j;
                                        printf("Fill rect at %d,%d\n", r.x, r.y);
                                        if (j != rect_size * 2) {
                                                testcard_fillRect(&s->pixmap, &r,
                                                                rect_colors[col_num]);
                                                col_num = (col_num + 1) % COL_NUM;
                                        } else {
                                                r.h = rect_size / 2;
                                                r.y += rect_size / 4;
                                                testcard_fillRect(&s->pixmap, &r, grey);
                                                grey += 0x00010101 * (255 / COL_NUM);
                                        }
                                }
                        }
                }
                s->data = (char *) s->pixmap.data;
                if (codec == UYVY || codec == v210) {
                        rgb2yuv422((unsigned char *) s->data, aligned_x,
                                   vf_get_tile(s->frame, 0)->height);
                }

                if (codec == v210) {
                        s->data =
                            (char *)tov210((unsigned char *) s->data, aligned_x,
                                           aligned_x, vf_get_tile(s->frame, 0)->height, bpp);
                        free(s->pixmap.data);
                }

                if (codec == R10k) {
                        toR10k((unsigned char *) s->data, vf_get_tile(s->frame, 0)->width,
                                        vf_get_tile(s->frame, 0)->height);
                }

                if(codec == RGB) {
                        s->data =
                            (char *)toRGB((unsigned char *) s->data, vf_get_tile(s->frame, 0)->width,
                                           vf_get_tile(s->frame, 0)->height);
                        free(s->pixmap.data);
                }

                tmp = filename;

                vf_get_tile(s->frame, 0)->data = (char *) malloc(2 * s->size);

                memcpy(vf_get_tile(s->frame, 0)->data, s->data, s->size);
                memcpy(vf_get_tile(s->frame, 0)->data + s->size, vf_get_tile(s->frame, 0)->data, s->size);

                free(s->data);
                s->data = vf_get_tile(s->frame, 0)->data;
        }

        s->count = 0;
        s->last_frame_time = std::chrono::steady_clock::now();

        printf("Testcard capture set to %dx%d, bpp %f\n", vf_get_tile(s->frame, 0)->width,
                        vf_get_tile(s->frame, 0)->height, bpp);

        vf_get_tile(s->frame, 0)->data_len = s->size;

        if(strip_fmt != NULL) {
                if(configure_tiling(s, strip_fmt) != 0) {
                        goto error;
                }
        }

        if(vidcap_params_get_flags(params) & VIDCAP_FLAG_AUDIO_EMBEDDED) {
                s->grab_audio = TRUE;
                if(configure_audio(s) != 0) {
                        s->grab_audio = FALSE;
                        fprintf(stderr, "[testcard] Disabling audio output. "
                                        "SDL-mixer missing, running on Mac or other problem.\n");
                }
        } else {
                s->grab_audio = FALSE;
        }

        free(fmt);

        *state = s;
        return VIDCAP_INIT_OK;

error:
        free(fmt);
        free(s->data);
        vf_free(s->frame);
        if (in)
                fclose(in);
        delete s;
        return VIDCAP_INIT_FAIL;
}
예제 #10
0
static void *display_deltacast_init(struct module *parent, const char *fmt, unsigned int flags)
{
        UNUSED(parent);
        struct state_deltacast *s;
        ULONG             Result,DllVersion,NbBoards,ChnType;
        ULONG             BrdId = 0;

        s = (struct state_deltacast *)calloc(1, sizeof(struct state_deltacast));
        s->magic = DELTACAST_MAGIC;
        
        s->frame = vf_alloc(1);
        s->tile = vf_get_tile(s->frame, 0);
        s->frames = 0;
        
        gettimeofday(&s->tv, NULL);
        
        s->initialized = FALSE;
        if(flags & DISPLAY_FLAG_AUDIO_EMBEDDED) {
                s->play_audio = TRUE;
        } else {
                s->play_audio = FALSE;
        }
        
        s->BoardHandle = s->StreamHandle = s->SlotHandle = NULL;
        s->audio_configured = FALSE;

        if(fmt && strcmp(fmt, "help") == 0) {
                show_help();
                vf_free(s->frame);
                free(s);
                return &display_init_noerr;
        }
        
        if(fmt)
        {
                char *tmp = strdup(fmt);
                char *save_ptr = NULL;
                char *tok;
                
                tok = strtok_r(tmp, ":", &save_ptr);
                if(!tok)
                {
                        free(tmp);
                        show_help();
                        goto error;
                }
                if (strncasecmp(tok, "board=", strlen("board=")) == 0) {
                        BrdId = atoi(tok + strlen("board="));
                } else {
                        fprintf(stderr, "Unknown option: %s\n\n", tok);
                        free(tmp);
                        show_help();
                        goto error;
                }
                free(tmp);
        }

        /* Query VideoMasterHD information */
        Result = VHD_GetApiInfo(&DllVersion,&NbBoards);
        if (Result != VHDERR_NOERROR) {
                fprintf(stderr, "[DELTACAST] ERROR : Cannot query VideoMasterHD"
                                " information. Result = 0x%08X\n",
                                Result);
                goto error;
        }
        if (NbBoards == 0) {
                fprintf(stderr, "[DELTACAST] No DELTA board detected, exiting...\n");
                goto error;
        }
        
        if(BrdId >= NbBoards) {
                fprintf(stderr, "[DELTACAST] Wrong index %d. Found %d cards.\n", BrdId, NbBoards);
                goto error;
        }

        /* Open a handle on first DELTA-hd/sdi/codec board */
        Result = VHD_OpenBoardHandle(BrdId,&s->BoardHandle,NULL,0);
        if (Result != VHDERR_NOERROR)
        {
                fprintf(stderr, "[DELTACAST] ERROR : Cannot open DELTA board %u handle. Result = 0x%08X\n",BrdId,Result);
                goto error;
        }
        VHD_GetBoardProperty(s->BoardHandle, VHD_CORE_BP_TX0_TYPE, &ChnType);
        if((ChnType!=VHD_CHNTYPE_SDSDI)&&(ChnType!=VHD_CHNTYPE_HDSDI)&&(ChnType!=VHD_CHNTYPE_3GSDI)) {
                fprintf(stderr, "[DELTACAST] ERROR : The selected channel is not an SDI one\n");
                goto bad_channel;
        }
        
        /* Disable RX0-TX0 by-pass relay loopthrough */
        VHD_SetBoardProperty(s->BoardHandle,VHD_CORE_BP_BYPASS_RELAY_0,FALSE);
        
        /* Select a 1/1 clock system */
        VHD_SetBoardProperty(s->BoardHandle,VHD_SDI_BP_CLOCK_SYSTEM,VHD_CLOCKDIV_1);

        pthread_mutex_init(&s->lock, NULL);
                  
	return s;

bad_channel:
        VHD_CloseBoardHandle(s->BoardHandle);
error:
        vf_free(s->frame);
        free(s);
        return NULL;
}