Пример #1
0
static void configure_with(struct state_decompress *decompressor, struct video_desc desc)
{
        enum dxt_type type;

#ifndef HAVE_MACOSX
        printf("[RTDXT] Trying OpenGL 3.1 context first.\n");
        decompressor->gl_context = glx_init(MK_OPENGL_VERSION(3,1));
        decompressor->legacy = FALSE;
        if(!decompressor->gl_context) {
                fprintf(stderr, "[RTDXT] OpenGL 3.1 profile failed to initialize, falling back to legacy profile.\n");
                decompressor->gl_context = glx_init(OPENGL_VERSION_UNSPECIFIED);
                decompressor->legacy = TRUE;
        }
        glx_validate(decompressor->gl_context);
#else
        decompressor->gl_context = NULL;
        if(get_mac_kernel_version_major() >= 11) {
                printf("[RTDXT] Mac 10.7 or latter detected. Trying OpenGL 3.2 Core profile first.\n");
                decompressor->gl_context = mac_gl_init(MAC_GL_PROFILE_3_2);
                if(!decompressor->gl_context) {
                        fprintf(stderr, "[RTDXT] OpenGL 3.2 Core profile failed to initialize, falling back to legacy profile.\n");
                } else {
                        decompressor->legacy = FALSE;
                }
        }

        if(!decompressor->gl_context) {
                decompressor->gl_context = mac_gl_init(MAC_GL_PROFILE_LEGACY);
                decompressor->legacy = TRUE;
        }
#endif
        if(!decompressor->gl_context) {
                fprintf(stderr, "[RTDXT decompress] Failed to create GL context.");
                exit_uv(128);
                decompressor->compressed_len = 0;
                return;
        }

        if(desc.color_spec == DXT5) {
                type = DXT_TYPE_DXT5_YCOCG;
        } else if(desc.color_spec == DXT1) {
                type = DXT_TYPE_DXT1;
        } else if(desc.color_spec == DXT1_YUV) {
                type = DXT_TYPE_DXT1_YUV;
        } else {
                fprintf(stderr, "Wrong compressiong to decompress.\n");
                return;
        }
        
        decompressor->desc = desc;

        decompressor->decoder = dxt_decoder_create(type, desc.width,
                        desc.height, decompressor->out_codec == RGBA ? DXT_FORMAT_RGBA : DXT_FORMAT_YUV422, decompressor->legacy);

        assert(decompressor->decoder != NULL);
        
        decompressor->compressed_len = dxt_get_size(desc.width, desc.height, type);
        decompressor->configured = TRUE;
}
Пример #2
0
static void display_sage_run(void *arg)
{
        struct state_sage *s = (struct state_sage *)arg;
        s->magic = MAGIC_SAGE;

        while (!s->should_exit) {
                display_sage_handle_events();

                sem_wait(&s->semaphore);
                if (s->should_exit)
                        break;

                if (s->deinterlace) {
                        vc_deinterlace((unsigned char *) s->tile->data, vc_get_linesize(s->tile->width,
                                                s->frame->color_spec), s->tile->height);
                }

                s->sage_state->swapBuffer(SAGE_NON_BLOCKING);
                sageMessage msg;
                if (s->sage_state->checkMsg(msg, false) > 0) {
                        switch (msg.getCode()) {
                        case APP_QUIT:
                                sage::printLog("Ultragrid: QUIT message");
                                exit_uv(1);
                                break;
                        }
                }

                s->tile->data = (char *) s->sage_state->getBuffer();

                pthread_mutex_lock(&s->buffer_writable_lock);
                s->buffer_writable = 1;
                if(s->grab_waiting) {
                        pthread_cond_broadcast(&s->buffer_writable_cond);
                }
                pthread_mutex_unlock(&s->buffer_writable_lock);

                s->frames++;

                gettimeofday(&s->t, NULL);
                double seconds = tv_diff(s->t, s->t0);
                if (seconds >= 5) {
                        float fps = s->frames / seconds;
                        log_msg(LOG_LEVEL_INFO, "[SAGE] %d frames in %g seconds = %g FPS\n",
                                s->frames, seconds, fps);
                        s->t0 = s->t;
                        s->frames = 0;
                }
        }
}
Пример #3
0
struct video_frame * fastdxt_compress(void *args, struct video_frame *tx, int buffer_idx)
{
        /* This thread will be called from main.c and handle the compress_threads */
        struct video_compress *compress = (struct video_compress *)args;
        unsigned int x;
        unsigned char *line1, *line2;
        struct video_frame *out = compress->out[buffer_idx];
        struct tile *out_tile = &out->tiles[0];

        assert(tx->tile_count == 1);
        assert(vf_get_tile(tx, 0)->width % 4 == 0);
        
        pthread_mutex_lock(&(compress->lock));

        if(vf_get_tile(tx, 0)->width != out_tile->width ||
                        vf_get_tile(tx, 0)->height != out_tile->height ||
                        tx->interlacing != compress->interlacing_source ||
                        tx->color_spec != compress->tx_color_spec)
        {
                int ret;
                ret = reconfigure_compress(compress, vf_get_tile(tx, 0)->width, vf_get_tile(tx, 0)->height, tx->color_spec, tx->interlacing, tx->fps);
                if(!ret)
                        return NULL;
        }

        line1 = (unsigned char *) tx->tiles[0].data;
        line2 = compress->output_data;

        for (x = 0; x < out_tile->height; ++x) {
                int src_linesize = vc_get_linesize(out_tile->width, compress->tx_color_spec);
                compress->decoder(line2, line1, out_tile->linesize,
                                0, 8, 16);
                line1 += src_linesize;
                line2 += out_tile->linesize;
        }

        if(tx->interlacing != INTERLACED_MERGED && tx->interlacing != PROGRESSIVE) {
                fprintf(stderr, "Unsupported interlacing format.\n");
                exit_uv(1);
        }

        if(tx->interlacing == INTERLACED_MERGED) {
                vc_deinterlace(compress->output_data, out_tile->linesize,
                                out_tile->height);
        }

        compress->buffer_idx = buffer_idx;

        for (x = 0; x < (unsigned int) compress->num_threads; x++) {
                platform_sem_post(&compress->thread_compress[x]);
        }

        for (x = 0; x < (unsigned int) compress->num_threads; x++) {
                platform_sem_wait(&compress->thread_done[x]);
        }

        out_tile->data_len = out_tile->width * compress->dxt_height / 2;
        
        pthread_mutex_unlock(&(compress->lock));

        return out;
}
Пример #4
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;
}
Пример #5
0
int reconfigure_compress(struct video_compress *compress, int width, int height, codec_t codec, enum interlacing_t interlacing, double fps)
{
        int x;
        int i;

        fprintf(stderr, "Compression reinitialized for %ux%u video.\n", 
                        width, height);
        /* Store original attributes to allow format change detection */
        for(i = 0; i < 2; ++i) {
                compress->tile[i]->width = width;
                compress->tile[i]->height = height;
                compress->out[i]->color_spec = codec;
                compress->out[i]->fps = fps;
                
                if(interlacing == INTERLACED_MERGED) {
                        fprintf(stderr, "[FastDXT] Warning: deinterlacing input prior to compress!\n");
                        compress->out[i]->interlacing = PROGRESSIVE;
                } else {
                        compress->out[i]->interlacing = interlacing;
                }
        }
        compress->tx_color_spec = codec;
        compress->interlacing_source = interlacing;

        compress->dxt_height = (compress->tile[0]->height + 3) / 4 * 4;

        switch (codec) {
                case RGB:
                        compress->decoder = (decoder_t) vc_copylineRGBtoRGBA;
                        compress->rgb = TRUE;
                        break;
                case RGBA:
                        compress->decoder = (decoder_t) memcpy;
                        compress->rgb = TRUE;
                        break;
                case R10k:
                        compress->decoder = (decoder_t) vc_copyliner10k;
                        compress->rgb = TRUE;
                        break;
                case UYVY:
                case Vuy2:
                case DVS8:
                        compress->decoder = (decoder_t) memcpy;
                        compress->rgb = FALSE;
                        break;
                case v210:
                        compress->decoder = (decoder_t) vc_copylinev210;
                        compress->rgb = FALSE;
                        break;
                case DVS10:
                        compress->decoder = (decoder_t) vc_copylineDVS10;
                        compress->rgb = FALSE;
                        break;
                case DPX10:        
                        compress->decoder = (decoder_t) vc_copylineDPX10toRGBA;
                        compress->rgb = FALSE;
                        break;
                default:
                        fprintf(stderr, "Unknown codec %d!", codec);
                        exit_uv(128);
                        return FALSE;
        }
        
        int h_align = 0;

        for(i = 0; codec_info[i].name != NULL; ++i) {
                if(codec == codec_info[i].codec) {
                        h_align = codec_info[i].h_align;
                }
        }
        assert(h_align != 0);

        for(i = 0; i < 2; ++i) {
                compress->tile[i]->linesize = vf_get_tile(compress->out[i], 0)->width * 
                        (compress->rgb ? 4 /*RGBA*/: 2/*YUV 422*/);

                if(compress->rgb) {
                        compress->out[i]->color_spec = DXT1;
                } else {
                        compress->out[i]->color_spec = DXT1_YUV;
                }
        }
        

        for (x = 0; x < compress->num_threads; x++) {
                int my_height = (compress->dxt_height / compress->num_threads) / 4 * 4;
                if(x == compress->num_threads - 1) {
                        my_height = compress->dxt_height - my_height /* "their height" */ * x;
                }
                compress->buffer[x] =
                    (unsigned char *)malloc(width * my_height * 4);
        }

#ifdef HAVE_MACOSX
        compress->output_data = (unsigned char *)malloc(width * compress->dxt_height * 4);
        for(i = 0; i < 2; ++i) {
                compress->tile[i]->data = (char *)malloc(width * compress->dxt_height * 4);
        }
#else
        /*
         *  memalign doesn't exist on Mac OS. malloc always returns 16  
         *  bytes aligned memory
         *
         *  see: http://www.mythtv.org/pipermail/mythtv-dev/2006-January/044309.html
         */
        compress->output_data = (unsigned char *)memalign(16, width * compress->dxt_height * 4);
        for(i = 0; i < 2; ++i) {
                compress->tile[i]->data = (char *)memalign(16, width * compress->dxt_height * 4);
        }
#endif                          /* HAVE_MACOSX */
        memset(compress->output_data, 0, width * compress->dxt_height * 4);
        for(i = 0; i < 2; ++i) {
                memset(compress->tile[i]->data, 0, width * compress->dxt_height * 4 / 8);
        }

        return TRUE;
}
Пример #6
0
static int configure_with(struct compress_jpeg_state *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;
                /* TODO: enable (we need R10k -> RGB)
                 * case R10k:
                        s->decoder = (decoder_t) vc_copyliner10k;
                        s->rgb = TRUE;
                        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;

        if(s->rgb) {
                s->encoder_param.interleaved = 0;
                s->encoder_param.restart_interval = 8;
                /* 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 = 2;
                /* 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);
                                vf_get_tile(s->out[frame_idx], x)->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;
}