Пример #1
0
void fastdxt_done(void *args)
{
        struct video_compress *compress = (struct video_compress *)args;
        int x;
        
        pthread_mutex_lock(&(compress->lock)); /* wait for fastdxt_compress if running */
        fastdxt_should_exit = TRUE;
        
        for (x = 0; x < compress->num_threads; x++) {
                platform_sem_post(&compress->thread_compress[x]);
        }

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

        pthread_mutex_unlock(&(compress->lock));
        
        pthread_mutex_destroy(&(compress->lock));
        
        for (x = 0; x < compress->num_threads; ++x)
                free(compress->buffer[x]);
        free(compress);
                
        
}
Пример #2
0
static void compress_thread(void *args)
{
        struct video_compress *compress = (struct video_compress *)args;
        int myId, range, my_range, x;
        int my_height;
        unsigned char *retv;

        pthread_mutex_lock(&(compress->lock));
        myId = compress->thread_count;
        compress->thread_count++;
        pthread_mutex_unlock(&(compress->lock));

        fprintf(stderr, "Compress thread %d online.\n", myId);

        while (1) {
                platform_sem_wait(&compress->thread_compress[myId]);
                if(fastdxt_should_exit) break;

                my_height = (compress->tile[compress->buffer_idx]->height / compress->num_threads) / 4 * 4;
                range = my_height * compress->tile[compress->buffer_idx]->width; /* for all threads except the last */

                if(myId == compress->num_threads - 1) {
                        my_height = compress->tile[compress->buffer_idx]->height - my_height /* "their height" */ * myId;
                }
                my_range = my_height * compress->tile[compress->buffer_idx]->width;

                if(!compress->rgb)
                {
                        unsigned char *input;
                        input = (compress->output_data) + myId
                                * range * 2;
                        retv = compress->buffer[myId];
                        /* Repack the data to YUV 4:4:4 Format */
                        for (x = 0; x < my_range; x += 2) {
                                retv[4 * x] = input[2 * x + 1]; //Y1
                                retv[4 * x + 1] = input[2 * x]; //U1
                                retv[4 * x + 2] = input[2 * x + 2];     //V1
                                retv[4 * x + 3] = 255;  //Alpha

                                retv[4 * x + 4] = input[2 * x + 3];     //Y2
                                retv[4 * x + 5] = input[2 * x]; //U1
                                retv[4 * x + 6] = input[2 * x + 2];     //V1
                                retv[4 * x + 7] = 255;  //Alpha
                        }
                } else {
                        retv = (compress->output_data) + myId * range * 4;
                }

                DirectDXT1(retv,
                               ((unsigned char *) compress->tile[compress->buffer_idx]->data) + myId * range / 2,
                               compress->tile[compress->buffer_idx]->width, my_height);

                platform_sem_post(&compress->thread_done[myId]);
        }
        
        platform_sem_post(&compress->thread_done[myId]);
}
Пример #3
0
static void *video_export_thread(void *arg)
{
        struct video_export *s = (struct video_export *) arg;

        while(1) {
                platform_sem_wait(&s->semaphore);
                struct output_entry *current;

                pthread_mutex_lock(&s->lock);
                {
                        current = s->head;
                        s->head = s->head->next;
                        s->queue_len -= 1;
                }
                pthread_mutex_unlock(&s->lock);

                assert((current->data == NULL && current->data_len == 0) ||
                                (current->data != NULL && current->data_len != 0));

                // poison
                if(current->data == NULL) {
                        return NULL;
                }

                FILE *out = fopen(current->filename, "wb");
                assert (out != NULL);
                if (fwrite(current->data, current->data_len, 1, out) != 1) {
                        perror("fwrite");
                }
                fclose(out);
                free(current->data);
                free(current->filename);
                free(current);
        }

        // never get here
}
Пример #4
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;
}