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); }
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]); }
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 }
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; }