Ejemplo n.º 1
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];
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
static int configure_tiling(struct testcard_state *s, const char *fmt)
{
        char *tmp, *token, *saveptr = NULL;
        int tile_cnt;
        int x;

        int grid_w, grid_h;

        if(fmt[1] != '=') return 1;

        tmp = strdup(&fmt[2]);
        token = strtok_r(tmp, "x", &saveptr);
        grid_w = atoi(token);
        token = strtok_r(NULL, "x", &saveptr);
        grid_h = atoi(token);
        free(tmp);

        s->tiled = vf_alloc(grid_w * grid_h);
        s->tiles_cnt_horizontal = grid_w;
        s->tiles_cnt_vertical = grid_h;
        s->tiled->color_spec = s->frame->color_spec;
        s->tiled->fps = s->frame->fps;
        s->tiled->interlacing = s->frame->interlacing;

        tile_cnt = grid_w *
                                grid_h;
        assert(tile_cnt >= 1);

        s->tiles_data = (char **) malloc(tile_cnt *
                        sizeof(char *));
        /* split only horizontally!!!!!! */
        vf_split(s->tiled, s->frame, grid_w,
                        1, 1 /*prealloc*/);
        /* for each row, make the tile data correct.
         * .data pointers of same row point to same block,
         * but different row */
        for(x = 0; x < grid_w; ++x) {
                int y;

                s->tiles_data[x] = s->tiled->tiles[x].data;

                s->tiled->tiles[x].width = s->frame->tiles[0].width/ grid_w;
                s->tiled->tiles[x].height = s->frame->tiles[0].height / grid_h;
                s->tiled->tiles[x].data_len = s->frame->tiles[0].data_len / (grid_w * grid_h);

                s->tiled->tiles[x].data =
                        s->tiles_data[x] = (char *) realloc(s->tiled->tiles[x].data,
                                s->tiled->tiles[x].data_len * grid_h * 2);


                memcpy(s->tiled->tiles[x].data + s->tiled->tiles[x].data_len  * grid_h,
                                s->tiled->tiles[x].data, s->tiled->tiles[x].data_len * grid_h);
                /* recopy tiles vertically */
                for(y = 1; y < grid_h; ++y) {
                        memcpy(&s->tiled->tiles[y * grid_w + x],
                                        &s->tiled->tiles[x], sizeof(struct tile));
                        /* make the pointers correct */
                        s->tiles_data[y * grid_w + x] =
                                s->tiles_data[x] +
                                y * s->tiled->tiles[x].height *
                                vc_get_linesize(s->tiled->tiles[x].width, s->tiled->color_spec);

                        s->tiled->tiles[y * grid_w + x].data =
                                s->tiles_data[x] +
                                y * s->tiled->tiles[x].height *
                                vc_get_linesize(s->tiled->tiles[x].width, s->tiled->color_spec);
                }
        }

        return 0;
}
Ejemplo n.º 4
0
static int configure_with(struct state_video_compress_rtdxt *s, struct video_frame *frame)
{
        unsigned int x;
        enum dxt_format format;
        int i;
        
        for (i = 0; i < 2; ++i) {
                s->out[i] = vf_alloc(frame->tile_count);
        }
        
        for (x = 0; x < frame->tile_count; ++x) {
                if (vf_get_tile(frame, x)->width != vf_get_tile(frame, 0)->width ||
                                vf_get_tile(frame, x)->width != vf_get_tile(frame, 0)->width) {

                        fprintf(stderr,"[RTDXT] Requested to compress tiles of different size!");
                        //exit_uv(128);
                        return FALSE;
                }
        }
        
        for (i = 0; i < 2; ++i) {
                s->out[i]->fps = frame->fps;
                s->out[i]->color_spec = s->color_spec;

                for (x = 0; x < frame->tile_count; ++x) {
                        vf_get_tile(s->out[i], x)->width = vf_get_tile(frame, 0)->width;
                        vf_get_tile(s->out[i], x)->height = vf_get_tile(frame, 0)->height;
                }
        }

        switch (frame->color_spec) {
                case RGB:
                        s->decoder = (decoder_t) memcpy;
                        format = DXT_FORMAT_RGB;
                        break;
                case RGBA:
                        s->decoder = (decoder_t) memcpy;
                        format = DXT_FORMAT_RGBA;
                        break;
                case R10k:
                        s->decoder = (decoder_t) vc_copyliner10k;
                        format = DXT_FORMAT_RGBA;
                        break;
                case YUYV:
                        s->decoder = (decoder_t) vc_copylineYUYV;
                        format = DXT_FORMAT_YUV422;
                        break;
                case UYVY:
                case Vuy2:
                case DVS8:
                        s->decoder = (decoder_t) memcpy;
                        format = DXT_FORMAT_YUV422;
                        break;
                case v210:
                        s->decoder = (decoder_t) vc_copylinev210;
                        format = DXT_FORMAT_YUV422;
                        break;
                case DVS10:
                        s->decoder = (decoder_t) vc_copylineDVS10;
                        format = DXT_FORMAT_YUV422;
                        break;
                case DPX10:        
                        s->decoder = (decoder_t) vc_copylineDPX10toRGBA;
                        format = DXT_FORMAT_RGBA;
                        break;
                default:
                        fprintf(stderr, "[RTDXT] Unknown codec: %d\n", frame->color_spec);
                        //exit_uv(128);
                        return FALSE;
        }

        /* We will deinterlace the output frame */
        if(frame->interlacing  == INTERLACED_MERGED) {
                for (i = 0; i < 2; ++i) {
                        s->out[i]->interlacing = PROGRESSIVE;
                }
                s->interlaced_input = TRUE;
                fprintf(stderr, "[DXT compress] Enabling automatic deinterlacing.\n");
        } else {
                for (i = 0; i < 2; ++i) {
                        s->out[i]->interlacing = frame->interlacing;
                }
                s->interlaced_input = FALSE;
        }
        
        int data_len = 0;

        s->encoder = malloc(frame->tile_count * sizeof(struct dxt_encoder *));
        if(s->out[0]->color_spec == DXT1) {
                for(int i = 0; i < (int) frame->tile_count; ++i) {
                        s->encoder[i] =
                                dxt_encoder_create(DXT_TYPE_DXT1, s->out[0]->tiles[0].width, s->out[0]->tiles[0].height, format,
                                                s->gl_context.legacy);
                }
                data_len = dxt_get_size(s->out[0]->tiles[0].width, s->out[0]->tiles[0].height, DXT_TYPE_DXT1);
        } else if(s->out[0]->color_spec == DXT5){
                for(int i = 0; i < (int) frame->tile_count; ++i) {
                        s->encoder[i] =
                                dxt_encoder_create(DXT_TYPE_DXT5_YCOCG, s->out[0]->tiles[0].width, s->out[0]->tiles[0].height, format,
                                                s->gl_context.legacy);
                }
                data_len = dxt_get_size(s->out[0]->tiles[0].width, s->out[0]->tiles[0].height, DXT_TYPE_DXT5_YCOCG);
        }

        for(int i = 0; i < (int) frame->tile_count; ++i) {
                if(s->encoder[i] == NULL) {
                        fprintf(stderr, "[RTDXT] Unable to create decoder.\n");
                        //exit_uv(128);
                        return FALSE;
                }
        }

        s->encoder_input_linesize = s->out[0]->tiles[0].width;
        switch(format) { 
                case DXT_FORMAT_RGBA:
                        s->encoder_input_linesize *= 4;
                        break;
                case DXT_FORMAT_RGB:
                        s->encoder_input_linesize *= 3;
                        break;
                case DXT_FORMAT_YUV422:
                        s->encoder_input_linesize *= 2;
                        break;
                case DXT_FORMAT_YUV:
                        /* not used - just not compilator to complain */
                        abort();
                        break;
        }

        assert(data_len > 0);
        assert(s->encoder_input_linesize > 0);

        for (i = 0; i < 2; ++i) {
                for (x = 0; x < frame->tile_count; ++x) {
                        vf_get_tile(s->out[i], x)->data_len = data_len;
                        vf_get_tile(s->out[i], x)->data = (char *) malloc(data_len);
                }
        }
        
        s->decoded = malloc(4 * s->out[0]->tiles[0].width * s->out[0]->tiles[0].height);
        
        s->configured = TRUE;
        return TRUE;
}
Ejemplo n.º 5
0
void *
vidcap_aggregate_init(char *init_fmt, unsigned int flags)
{
	struct vidcap_aggregate_state *s;
        char *save_ptr = NULL;
        char *item;
        char *parse_string;
        char *tmp;
        int i;

	printf("vidcap_aggregate_init\n");


        s = (struct vidcap_aggregate_state *) calloc(1, sizeof(struct vidcap_aggregate_state));
	if(s == NULL) {
		printf("Unable to allocate aggregate capture state\n");
		return NULL;
	}

        s->frames = 0;
        gettimeofday(&s->t0, NULL);

        if(!init_fmt || strcmp(init_fmt, "help") == 0) {
                show_help();
                return NULL;
        }


        s->devices_cnt = 0;
        tmp = parse_string = strdup(init_fmt);
        while(strtok_r(tmp, "#", &save_ptr)) {
                s->devices_cnt++;
                tmp = NULL;
        }
        free(parse_string);

        s->devices = calloc(1, s->devices_cnt * sizeof(struct vidcap *));
        i = 0;
        tmp = parse_string = strdup(init_fmt);
        while((item = strtok_r(tmp, "#", &save_ptr))) {
                char *device;
                char *config = strdup(item);
                char *save_ptr_dev = NULL;
                char *device_cfg;
                unsigned int dev_flags = 0u;
                device = strtok_r(config, ":", &save_ptr_dev);
                device_cfg = save_ptr_dev;
                if(i == 0) {
                        dev_flags = flags;
                } else { // do not grab from second and other devices
                        dev_flags = flags & ~(VIDCAP_FLAG_AUDIO_EMBEDDED | VIDCAP_FLAG_AUDIO_AESEBU | VIDCAP_FLAG_AUDIO_ANALOG);
                }

                s->devices[i] = initialize_video_capture(device,
                                               device_cfg, dev_flags);
                free(config);
                if(!s->devices[i]) {
                        fprintf(stderr, "[aggregate] Unable to initialize device %d (%s:%s).\n", i, device, device_cfg);
                        goto error;
                }
                ++i;
                tmp = NULL;
        }
        free(parse_string);

        s->frame = vf_alloc(s->devices_cnt);
        
	return s;

error:
        if(s->devices) {
                int i;
                for (i = 0u; i < s->devices_cnt; ++i) {
                        if(s->devices[i]) {
                                 vidcap_done(s->devices[i]);
                        }
                }
        }
        free(s);
        return NULL;
}
Ejemplo n.º 6
0
static void *display_sage_init(struct module *parent, const char *fmt, unsigned int flags)
{
        UNUSED(fmt);
        UNUSED(flags);
        UNUSED(parent);
        struct state_sage *s;

        s = (struct state_sage *) calloc(1, sizeof(struct state_sage));
        assert(s != NULL);

        s->confName = NULL;

        if(fmt) {
                if(strcmp(fmt, "help") == 0) {
                        printf("SAGE usage:\n");
                        printf("\tuv -t sage[:config=<config_file>|:fs=<fsIP>][:codec=<fcc>][:d]\n");
                        printf("\t                      <config_file> - SAGE app config file, default \"ultragrid.conf\"\n");
                        printf("\t                      <fsIP> - FS manager IP address\n");
                        printf("\t                      <fcc> - FourCC of codec that will be used to transmit to SAGE\n");
                        printf("\t                              Supported options are UYVY, RGBA, RGB or DXT1\n");
                        printf("\t                      d - deinterlace output\n");
                        return &display_init_noerr;
                } else {
                        char *tmp, *parse_str;
                        tmp = parse_str = strdup(fmt);
                        char *save_ptr = NULL;
                        char *item;

                        while((item = strtok_r(parse_str, ":", &save_ptr))) {
                                parse_str = NULL;
                                if(strncmp(item, "config=", strlen("config=")) == 0) {
                                        s->confName = item + strlen("config=");
                                } else if(strncmp(item, "codec=", strlen("codec=")) == 0) {
                                         uint32_t fourcc;
                                         if(strlen(item + strlen("codec=")) != sizeof(fourcc)) {
                                                 fprintf(stderr, "Malformed FourCC code (wrong length).\n");
                                                 free(s); return NULL;
                                         }
                                         memcpy((void *) &fourcc, item + strlen("codec="), sizeof(fourcc));
                                         s->requestedDisplayCodec = get_codec_from_fcc(fourcc);
                                         if(s->requestedDisplayCodec == VIDEO_CODEC_NONE) {
                                                 fprintf(stderr, "Codec not found according to FourCC.\n");
                                                 free(s); return NULL;
                                         }
                                         if(s->requestedDisplayCodec != UYVY &&
                                                         s->requestedDisplayCodec != RGBA &&
                                                         s->requestedDisplayCodec != RGB &&
                                                         s->requestedDisplayCodec != DXT1
#ifdef SAGE_NATIVE_DXT5YCOCG
                                                         && s->requestedDisplayCodec != DXT5
#endif // SAGE_NATIVE_DXT5YCOCG
                                                         ) {
                                                 fprintf(stderr, "Entered codec is not nativelly supported by SAGE.\n");
                                                 free(s); return NULL;
                                         }
                                } else if(strcmp(item, "tx") == 0) {
                                        s->is_tx = true;
                                } else if(strncmp(item, "fs=", strlen("fs=")) == 0) {
                                        s->fsIP = item + strlen("fs=");
                                } else if(strcmp(item, "d") == 0) {
                                        s->deinterlace = true;
                                } else {
                                        fprintf(stderr, "[SAGE] unrecognized configuration: %s\n",
                                                        item);
                                        free(s);
                                        return NULL;
                                }
                        }
                        free(tmp);
                }
        }

        if (!s->is_tx) {
                // read config file only if we are in dispaly mode (not sender mode)
                struct stat sb;
                if(s->confName) {
                        if(stat(s->confName, &sb)) {
                                perror("Unable to use SAGE config file");
                                free(s);
                                return NULL;
                        }
                } else if(stat("ultragrid.conf", &sb) == 0) {
                        s->confName = "ultragrid.conf";
                }
                if(s->confName) {
                        printf("[SAGE] Using config file %s.\n", s->confName);
                }
        }

        if(s->confName == NULL && s->fsIP == NULL) {
                fprintf(stderr, "[SAGE] Unable to locate FS manager address. "
                                "Set either in config file or from command line.\n");
                free(s);
                return NULL;
        }

        s->magic = MAGIC_SAGE;

        gettimeofday(&s->t0, NULL);

        s->frames = 0;
        s->frame = vf_alloc(1);
        s->tile = vf_get_tile(s->frame, 0);
        
        /* sage init */
        //FIXME sem se musi propasovat ty spravne parametry argc argv
        s->appID = 0;
        s->nodeID = 1;

        s->sage_state = NULL;

        /* thread init */
        sem_init(&s->semaphore, 0, 0);

        s->buffer_writable = 1;
        s->grab_waiting = 1;
        pthread_mutex_init(&s->buffer_writable_lock, 0);
        pthread_cond_init(&s->buffer_writable_cond, NULL);

        /*if (pthread_create
            (&(s->thread_id), NULL, display_thread_sage, (void *)s) != 0) {
                perror("Unable to create display thread\n");
                return NULL;
        }*/

        debug_msg("Window initialized %p\n", s);

        return (void *)s;
}
Ejemplo n.º 7
0
static int
vidcap_aggregate_init(const struct vidcap_params *params, void **state)
{
	struct vidcap_aggregate_state *s;

	printf("vidcap_aggregate_init\n");


        s = (struct vidcap_aggregate_state *) calloc(1, sizeof(struct vidcap_aggregate_state));
	if(s == NULL) {
		printf("Unable to allocate aggregate capture state\n");
		return VIDCAP_INIT_FAIL;
	}

        s->audio_source_index = -1;
        s->frames = 0;
        gettimeofday(&s->t0, NULL);

        if(vidcap_params_get_fmt(params) && strcmp(vidcap_params_get_fmt(params), "") != 0) {
                show_help();
                free(s);
                return VIDCAP_INIT_NOERR;
        }


        s->devices_cnt = 0;
        const struct vidcap_params *tmp = params;
        while((tmp = vidcap_params_get_next(tmp))) {
                if (vidcap_params_get_driver(tmp) != NULL)
                        s->devices_cnt++;
                else
                        break;
        }

        s->devices = calloc(s->devices_cnt, sizeof(struct vidcap *));
        tmp = params;
        for (int i = 0; i < s->devices_cnt; ++i) {
                tmp = vidcap_params_get_next(tmp);

                int ret = initialize_video_capture(NULL, (struct vidcap_params *) tmp, &s->devices[i]);
                if(ret != 0) {
                        fprintf(stderr, "[aggregate] Unable to initialize device %d (%s:%s).\n",
                                        i, vidcap_params_get_driver(tmp),
                                        vidcap_params_get_fmt(tmp));
                        goto error;
                }
        }

        s->captured_frames = calloc(s->devices_cnt, sizeof(struct video_frame *));

        s->frame = vf_alloc(s->devices_cnt);
        
        *state = s;
	return VIDCAP_INIT_OK;

error:
        if(s->devices) {
                int i;
                for (i = 0u; i < s->devices_cnt; ++i) {
                        if(s->devices[i]) {
                                 vidcap_done(s->devices[i]);
                        }
                }
        }
        free(s);
        return VIDCAP_INIT_FAIL;
}
Ejemplo n.º 8
0
/**
 * @brief This is compression initialization function that really does the stuff.
 * @param[in] parent        parent module
 * @param[in] config_string configuration (in format <driver>:<options>)
 * @param[out] state        created state
 * @retval     0            if state created sucessfully
 * @retval    <0            if error occured
 * @retval    >0            finished successfully, no state created (eg. displayed help)
 */
static int compress_init_real(struct module *parent, char *config_string, struct compress_state_real **state)
{
    struct compress_state_real *s;
    char *compress_options = NULL;

    if(!config_string)
        return -1;

    if(strcmp(config_string, "help") == 0)
    {
        show_compress_help();
        return 1;
    }

    pthread_once(&compression_list_initialized, init_compressions);

    s = (struct compress_state_real *) calloc(1, sizeof(struct compress_state_real));
    s->state_count = 1;
    int i;
    for(i = 0; i < compress_modules_count; ++i) {
        if(strncasecmp(config_string, available_compress_modules[i]->name,
                       strlen(available_compress_modules[i]->name)) == 0) {
            s->handle = available_compress_modules[i];
            if(config_string[strlen(available_compress_modules[i]->name)] == ':')
                compress_options = config_string +
                                   strlen(available_compress_modules[i]->name) + 1;
            else
                compress_options = "";
        }
    }
    if(!s->handle) {
        fprintf(stderr, "Unknown compression: %s\n", config_string);
        free(s);
        return -1;
    }
    strncpy(s->compress_options, compress_options, sizeof(s->compress_options) - 1);
    s->compress_options[sizeof(s->compress_options) - 1] = '\0';
    if(s->handle->init_func) {
        s->state = calloc(1, sizeof(struct module *));
        char compress_options[1024];
        strncpy(compress_options, s->compress_options, sizeof(compress_options) - 1);
        compress_options[sizeof(compress_options) - 1] = '\0';
        s->state[0] = s->handle->init_func(parent, compress_options);
        if(!s->state[0]) {
            fprintf(stderr, "Compression initialization failed: %s\n", config_string);
            free(s->state);
            free(s);
            return -1;
        }
        if(s->state[0] == &compress_init_noerr) {
            free(s->state);
            free(s);
            return 1;
        }
        for(int i = 0; i < 2; ++i) {
            s->out_frame[i] = vf_alloc(1);
        }
    } else {
        return -1;
    }

    *state = s;
    return 0;
}
Ejemplo n.º 9
0
static int configure_with(struct state_video_compress_jpeg *s, struct video_frame *frame)
{
        unsigned int x;
        int frame_idx;

        s->saved_desc.width = frame->tiles[0].width;
        s->saved_desc.height = frame->tiles[0].height;
        s->saved_desc.color_spec = frame->color_spec;
        s->saved_desc.fps = frame->fps;
        s->saved_desc.interlacing = frame->interlacing;
        s->saved_desc.tile_count = frame->tile_count;
        
        for (frame_idx = 0; frame_idx < 2; frame_idx++) {
                s->out[frame_idx] = vf_alloc(frame->tile_count);
        }
        
        for (x = 0; x < frame->tile_count; ++x) {
                if (vf_get_tile(frame, x)->width != vf_get_tile(frame, 0)->width ||
                                vf_get_tile(frame, x)->width != vf_get_tile(frame, 0)->width) {
                        fprintf(stderr,"[JPEG] Requested to compress tiles of different size!");
                        //exit_uv(129);
                        return FALSE;
                }
        }
        
        for (frame_idx = 0; frame_idx < 2; frame_idx++) {
                for (x = 0; x < frame->tile_count; ++x) {
                        vf_get_tile(s->out[frame_idx], x)->width = vf_get_tile(frame, 0)->width;
                        vf_get_tile(s->out[frame_idx], x)->height = vf_get_tile(frame, 0)->height;
                }
                s->out[frame_idx]->interlacing = frame->interlacing;
                s->out[frame_idx]->fps = frame->fps;
                s->out[frame_idx]->color_spec = s->color_spec;
                s->out[frame_idx]->color_spec = JPEG;
        }

        switch (frame->color_spec) {
                case RGB:
                        s->decoder = (decoder_t) memcpy;
                        s->rgb = TRUE;
                        break;
                case RGBA:
                        s->decoder = (decoder_t) vc_copylineRGBAtoRGB;
                        s->rgb = TRUE;
                        break;
                case BGR:
                        s->decoder = (decoder_t) vc_copylineBGRtoRGB;
                        s->rgb = TRUE;
                        break;
                /* TODO: enable (we need R10k -> RGB)
                 * case R10k:
                        s->decoder = (decoder_t) vc_copyliner10k;
                        s->rgb = TRUE;
                        break;*/
                case YUYV:
                        s->decoder = (decoder_t) vc_copylineYUYV;
                        s->rgb = FALSE;
                        break;
                case UYVY:
                case Vuy2:
                case DVS8:
                        s->decoder = (decoder_t) memcpy;
                        s->rgb = FALSE;
                        break;
                case v210:
                        s->decoder = (decoder_t) vc_copylinev210;
                        s->rgb = FALSE;
                        break;
                case DVS10:
                        s->decoder = (decoder_t) vc_copylineDVS10;
                        s->rgb = FALSE;
                        break;
                case DPX10:        
                        s->decoder = (decoder_t) vc_copylineDPX10toRGB;
                        s->rgb = TRUE;
                        break;
                default:
                        fprintf(stderr, "[JPEG] Unknown codec: %d\n", frame->color_spec);
                        //exit_uv(128);
                        return FALSE;
        }

	s->encoder_param.verbose = 0;
	s->encoder_param.segment_info = 1;

        if(s->rgb) {
                s->encoder_param.interleaved = 0;
                s->encoder_param.restart_interval = s->restart_interval == -1 ? 8
                        : s->restart_interval;
                /* LUMA */
                s->encoder_param.sampling_factor[0].horizontal = 1;
                s->encoder_param.sampling_factor[0].vertical = 1;
                /* Cb and Cr */
                s->encoder_param.sampling_factor[1].horizontal = 1;
                s->encoder_param.sampling_factor[1].vertical = 1;
                s->encoder_param.sampling_factor[2].horizontal = 1;
                s->encoder_param.sampling_factor[2].vertical = 1;
        } else {
                s->encoder_param.interleaved = 1;
                s->encoder_param.restart_interval = s->restart_interval == -1 ? 2
                        : s->restart_interval;
                /* LUMA */
                s->encoder_param.sampling_factor[0].horizontal = 2;
                s->encoder_param.sampling_factor[0].vertical = 1;
                /* Cb and Cr */
                s->encoder_param.sampling_factor[1].horizontal = 1;
                s->encoder_param.sampling_factor[1].vertical = 1;
                s->encoder_param.sampling_factor[2].horizontal = 1;
                s->encoder_param.sampling_factor[2].vertical = 1;
        }

        
        struct gpujpeg_image_parameters param_image;
        gpujpeg_image_set_default_parameters(&param_image);

        param_image.width = s->out[0]->tiles[0].width;
        param_image.height = s->out[0]->tiles[0].height;
        
        param_image.comp_count = 3;
        if(s->rgb) {
                param_image.color_space = GPUJPEG_RGB;
                param_image.sampling_factor = GPUJPEG_4_4_4;
        } else {
                param_image.color_space = GPUJPEG_YCBCR_BT709;
                param_image.sampling_factor = GPUJPEG_4_2_2;
        }
        
        s->encoder = gpujpeg_encoder_create(&s->encoder_param, &param_image);
        
        for (frame_idx = 0; frame_idx < 2; frame_idx++) {
                for (x = 0; x < frame->tile_count; ++x) {
                                vf_get_tile(s->out[frame_idx], x)->data = (char *) malloc(s->out[frame_idx]->tiles[0].width * s->out[frame_idx]->tiles[0].height * 3);

                }
        }
        s->encoder_input_linesize = s->out[frame_idx]->tiles[0].width *
                (param_image.color_space == GPUJPEG_RGB ? 3 : 2);
        
        if(!s->encoder) {
                fprintf(stderr, "[DXT GLSL] Failed to create encoder.\n");
                //exit_uv(128);
                return FALSE;
        }
        
        s->decoded = malloc(4 * s->out[0]->tiles[0].width * s->out[0]->tiles[0].height);
        return TRUE;
}
Ejemplo n.º 10
0
void *fastdxt_init(char *num_threads_str)
{
        /* This function does the following:
         * 1. Allocate memory for buffers 
         * 2. Spawn compressor threads
         */
        int x;
        int i;
        struct video_compress *compress;

        if(num_threads_str && strcmp(num_threads_str, "help") == 0) {
                printf("FastDXT usage:\n");
                printf("\t-FastDXT[:<num_threads>]\n");
                printf("\t\t<num_threads> - count of compress threads (default %d)\n", NUM_THREADS_DEFAULT);
                return NULL;
        }

        compress = calloc(1, sizeof(struct video_compress));
        /* initial values */
        compress->num_threads = 0;
        if(num_threads_str == NULL)
                compress->num_threads = NUM_THREADS_DEFAULT;
        else
                compress->num_threads = atoi(num_threads_str);
        assert (compress->num_threads >= 1 && compress->num_threads <= MAX_THREADS);

        for(i = 0; i < 2; ++i) {
                compress->out[i] = vf_alloc(1);
                compress->tile[i] = vf_get_tile(compress->out[i], 0);
        }
        
        for(i = 0; i < 2; ++i) {
                compress->tile[i]->width = 0;
                compress->tile[i]->height = 0;
        }

        compress->thread_count = 0;
        if (pthread_mutex_init(&(compress->lock), NULL)) {
                perror("Error initializing mutex!");
                return NULL;
        }

        for (x = 0; x < compress->num_threads; x++) {
                platform_sem_init(&compress->thread_compress[x], 0, 0);
                platform_sem_init(&compress->thread_done[x], 0, 0);
        }

        pthread_mutex_lock(&(compress->lock));

        for (x = 0; x < compress->num_threads; x++) {
                if (pthread_create
                    (&(compress->thread_ids[x]), NULL, (void *)compress_thread,
                     (void *)compress)) {
                        perror("Unable to create compressor thread!");
                        exit_uv(x);
                        return NULL;
                }
        }
        pthread_mutex_unlock(&(compress->lock));
        
        while(compress->num_threads != compress->thread_count) /* wait for all threads online */
                ;
        fprintf(stderr, "All compression threads are online.\n");
        
        return compress;
}
Ejemplo n.º 11
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;
}