diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c index 071402fb51..e014466bb8 100644 --- a/src/libFLAC/stream_encoder.c +++ b/src/libFLAC/stream_encoder.c @@ -83,6 +83,11 @@ */ #undef ENABLE_RICE_PARAMETER_SEARCH +#ifdef local_abs64 +#undef local_abs64 +#endif +#define local_abs64(x) ((uint64_t)((x)<0? -(x) : (x))) + typedef struct { FLAC__int32 *data[FLAC__MAX_CHANNELS]; @@ -413,9 +418,6 @@ typedef struct FLAC__StreamEncoderPrivate { FLAC__real *window[FLAC__MAX_APODIZATION_FUNCTIONS]; /* the pre-computed floating-point window for each apodization function */ FLAC__real *window_unaligned[FLAC__MAX_APODIZATION_FUNCTIONS]; #endif - uint32_t loose_mid_side_stereo_frames; /* rounded number of frames the encoder will use before trying both independent and mid/side frames again */ - uint32_t loose_mid_side_stereo_frame_count; /* number of frames using the current channel assignment */ - FLAC__ChannelAssignment last_channel_assignment; FLAC__StreamMetadata streaminfo; /* scratchpad for STREAMINFO as it is built */ FLAC__StreamMetadata_SeekTable *seek_table; /* pointer into encoder->protected_->metadata_ where the seek table is */ uint32_t current_sample_number; @@ -737,9 +739,6 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( else if(!encoder->protected_->do_mid_side_stereo) encoder->protected_->loose_mid_side_stereo = false; - if(encoder->protected_->loose_mid_side_stereo && encoder->protected_->num_threads > 2) - encoder->protected_->num_threads = 2; - if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__MAX_BITS_PER_SAMPLE) return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE; @@ -921,20 +920,6 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( } encoder->private_->input_capacity = 0; -#ifndef FLAC__INTEGER_ONLY_LIBRARY - encoder->private_->loose_mid_side_stereo_frames = (uint32_t)((double)encoder->protected_->sample_rate * 0.4 / (double)encoder->protected_->blocksize + 0.5); -#else - /* 26214 is the approximate fixed-point equivalent to 0.4 (0.4 * 2^16) */ - /* sample rate can be up to 1048575 Hz, and thus use 20 bits, so we do the multiply÷ by hand */ - FLAC__ASSERT(FLAC__MAX_SAMPLE_RATE <= 1048575); - FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535); - FLAC__ASSERT(encoder->protected_->sample_rate <= 1048575); - FLAC__ASSERT(encoder->protected_->blocksize <= 65535); - encoder->private_->loose_mid_side_stereo_frames = (uint32_t)FLAC__fixedpoint_trunc((((FLAC__uint64)(encoder->protected_->sample_rate) * (FLAC__uint64)(26214)) << 16) / (encoder->protected_->blocksize<<16) + FLAC__FP_ONE_HALF); -#endif - if(encoder->private_->loose_mid_side_stereo_frames == 0) - encoder->private_->loose_mid_side_stereo_frames = 1; - encoder->private_->loose_mid_side_stereo_frame_count = 0; encoder->private_->current_sample_number = 0; encoder->private_->current_frame_number = 0; @@ -3513,42 +3498,35 @@ FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_block } else if(encoder->private_->num_started_threadtasks == encoder->private_->num_threadtasks) { /* If the first task in the queue is still running, check whether there is enough work - * left in the queue. If there is, start on some */ - if(encoder->protected_->loose_mid_side_stereo) { - pthread_mutex_lock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); - if(!encoder->private_->threadtask[encoder->private_->next_thread]->task_done) - pthread_cond_wait(&encoder->private_->threadtask[encoder->private_->next_thread]->cond_task_done, &encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); - } - else { - /* First, check whether the mutex for the next due task is locked or free. If it is free (and thus acquired now) and - * the task is done, proceed to the next bit (writing the bitbuffer). If it is either currently locked or not yet - * processed, choose between starting on some work (if there is enough work in the queue) or waiting for the task - * to finish. Either way, release the mutex first, so it doesn't get interlocked with the work queue mutex */ - int mutex_result = pthread_mutex_trylock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); - while(mutex_result || !encoder->private_->threadtask[encoder->private_->next_thread]->task_done) { - if(!mutex_result) - pthread_mutex_unlock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); - - pthread_mutex_lock(&encoder->private_->mutex_work_queue); - if(encoder->private_->num_available_threadtasks > (encoder->protected_->num_threads - 1)) { - FLAC__StreamEncoderThreadTask * task = NULL; - task = encoder->private_->threadtask[encoder->private_->next_threadtask]; - encoder->private_->num_available_threadtasks--; - encoder->private_->next_threadtask++; - if(encoder->private_->next_threadtask == encoder->private_->num_threadtasks) - encoder->private_->next_threadtask = 1; - pthread_mutex_unlock(&encoder->private_->mutex_work_queue); - pthread_mutex_lock(&task->mutex_this_task); - process_frame_thread_inner_(encoder, task); - mutex_result = pthread_mutex_trylock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); - } - else { - pthread_mutex_unlock(&encoder->private_->mutex_work_queue); - pthread_mutex_lock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); - while(!encoder->private_->threadtask[encoder->private_->next_thread]->task_done) - pthread_cond_wait(&encoder->private_->threadtask[encoder->private_->next_thread]->cond_task_done,&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); - mutex_result = 0; - } + * left in the queue. If there is, start on some + * First, check whether the mutex for the next due task is locked or free. If it is free (and thus acquired now) and + * the task is done, proceed to the next bit (writing the bitbuffer). If it is either currently locked or not yet + * processed, choose between starting on some work (if there is enough work in the queue) or waiting for the task + * to finish. Either way, release the mutex first, so it doesn't get interlocked with the work queue mutex */ + int mutex_result = pthread_mutex_trylock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); + while(mutex_result || !encoder->private_->threadtask[encoder->private_->next_thread]->task_done) { + if(!mutex_result) + pthread_mutex_unlock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); + + pthread_mutex_lock(&encoder->private_->mutex_work_queue); + if(encoder->private_->num_available_threadtasks > (encoder->protected_->num_threads - 1)) { + FLAC__StreamEncoderThreadTask * task = NULL; + task = encoder->private_->threadtask[encoder->private_->next_threadtask]; + encoder->private_->num_available_threadtasks--; + encoder->private_->next_threadtask++; + if(encoder->private_->next_threadtask == encoder->private_->num_threadtasks) + encoder->private_->next_threadtask = 1; + pthread_mutex_unlock(&encoder->private_->mutex_work_queue); + pthread_mutex_lock(&task->mutex_this_task); + process_frame_thread_inner_(encoder, task); + mutex_result = pthread_mutex_trylock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); + } + else { + pthread_mutex_unlock(&encoder->private_->mutex_work_queue); + pthread_mutex_lock(&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); + while(!encoder->private_->threadtask[encoder->private_->next_thread]->task_done) + pthread_cond_wait(&encoder->private_->threadtask[encoder->private_->next_thread]->cond_task_done,&encoder->private_->threadtask[encoder->private_->next_thread]->mutex_this_task); + mutex_result = 0; } } /* Task is finished, write bitbuffer */ @@ -3764,14 +3742,33 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderT */ if(encoder->protected_->do_mid_side_stereo) { if(encoder->protected_->loose_mid_side_stereo) { - FLAC__ASSERT(encoder->protected_->num_threads < 3); - if(encoder->private_->loose_mid_side_stereo_frame_count == 0) { + uint64_t sumAbsLR = 0, sumAbsMS = 0; + uint32_t i; + if(encoder->protected_->bits_per_sample < 25) { + for(i = 1; i < encoder->protected_->blocksize; i++) { + int32_t predictionLeft = threadtask->integer_signal[0][i] - threadtask->integer_signal[0][i-1]; + int32_t predictionRight = threadtask->integer_signal[1][i] - threadtask->integer_signal[1][i-1]; + sumAbsLR += abs(predictionLeft) + abs(predictionRight); + sumAbsMS += abs((predictionLeft + predictionRight) >> 1) + abs(predictionLeft - predictionRight); + } + } + else { /* bps 25 or higher */ + for(i = 1; i < encoder->protected_->blocksize; i++) { + int64_t predictionLeft = (int64_t)threadtask->integer_signal[0][i] - (int64_t)threadtask->integer_signal[0][i-1]; + int64_t predictionRight = (int64_t)threadtask->integer_signal[1][i] - (int64_t)threadtask->integer_signal[1][i-1]; + sumAbsLR += local_abs64(predictionLeft) + local_abs64(predictionRight); + sumAbsMS += local_abs64((predictionLeft + predictionRight) >> 1) + local_abs64(predictionLeft - predictionRight); + } + } + if(sumAbsLR < sumAbsMS) { do_independent = true; - do_mid_side = true; + do_mid_side = false; + frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; } else { - do_independent = (encoder->private_->last_channel_assignment == FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT); - do_mid_side = !do_independent; + do_independent = false; + do_mid_side = true; + frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE; } } else { @@ -3903,17 +3900,14 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderT /* * Compose the frame bitbuffer */ - if(do_mid_side) { + if((do_independent && do_mid_side) || encoder->protected_->loose_mid_side_stereo) { uint32_t left_bps = 0, right_bps = 0; /* initialized only to prevent superfluous compiler warning */ FLAC__Subframe *left_subframe = 0, *right_subframe = 0; /* initialized only to prevent superfluous compiler warning */ FLAC__ChannelAssignment channel_assignment; FLAC__ASSERT(encoder->protected_->channels == 2); - if(encoder->protected_->loose_mid_side_stereo && encoder->private_->loose_mid_side_stereo_frame_count > 0) { - channel_assignment = (encoder->private_->last_channel_assignment == FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT? FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT : FLAC__CHANNEL_ASSIGNMENT_MID_SIDE); - } - else { + if(!encoder->protected_->loose_mid_side_stereo) { uint32_t bits[4]; /* WATCHOUT - indexed by FLAC__ChannelAssignment */ uint32_t min_bits; int ca; @@ -3922,7 +3916,6 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderT FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE == 1); FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE == 2); FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_MID_SIDE == 3); - FLAC__ASSERT(do_independent && do_mid_side); /* We have to figure out which channel assignent results in the smallest frame */ bits[FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT] = threadtask->best_subframe_bits [0] + threadtask->best_subframe_bits [1]; @@ -3935,23 +3928,21 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderT /* When doing loose mid-side stereo, ignore left-side * and right-side options */ - ca = encoder->protected_->loose_mid_side_stereo ? 3 : 1; - for( ; ca <= 3; ca++) { + for(ca = 1; ca <= 3; ca++) { if(bits[ca] < min_bits) { min_bits = bits[ca]; channel_assignment = (FLAC__ChannelAssignment)ca; } } + frame_header.channel_assignment = channel_assignment; } - frame_header.channel_assignment = channel_assignment; - if(!FLAC__frame_add_header(&frame_header, threadtask->frame)) { encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; return false; } - switch(channel_assignment) { + switch(frame_header.channel_assignment) { case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: left_subframe = &threadtask->subframe_workspace [0][threadtask->best_subframe [0]]; right_subframe = &threadtask->subframe_workspace [1][threadtask->best_subframe [1]]; @@ -3972,7 +3963,7 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderT FLAC__ASSERT(0); } - switch(channel_assignment) { + switch(frame_header.channel_assignment) { case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: left_bps = threadtask->subframe_bps [0]; right_bps = threadtask->subframe_bps [1]; @@ -4000,6 +3991,7 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderT return false; } else { + FLAC__ASSERT(do_independent); if(!FLAC__frame_add_header(&frame_header, threadtask->frame)) { encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; return false; @@ -4013,13 +4005,6 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderT } } - if(encoder->protected_->loose_mid_side_stereo) { - encoder->private_->loose_mid_side_stereo_frame_count++; - if(encoder->private_->loose_mid_side_stereo_frame_count >= encoder->private_->loose_mid_side_stereo_frames) - encoder->private_->loose_mid_side_stereo_frame_count = 0; - encoder->private_->last_channel_assignment = frame_header.channel_assignment; - } - return true; }