diff --git a/vp8/decoder/threading.c b/vp8/decoder/threading.c index 10e72ce2d..02edba2be 100644 --- a/vp8/decoder/threading.c +++ b/vp8/decoder/threading.c @@ -161,6 +161,8 @@ THREAD_FUNCTION vp8_thread_decoding_proc(void *p_data) while (1) { + int current_filter_level = 0; + if (pbi->b_multithreaded_rd == 0) break; @@ -279,6 +281,11 @@ THREAD_FUNCTION vp8_thread_decoding_proc(void *p_data) } } } + + // If |pbi->common.filter_level| is 0 the value can change in-between + // the sem_post and the check to call vp8_thread_loop_filter. + current_filter_level = pbi->common.filter_level; + // add this to each frame if ((mbrd->mb_row == pbi->common.mb_rows-1) || ((mbrd->mb_row == pbi->common.mb_rows-2) && (pbi->common.mb_rows % (pbi->decoding_thread_count+1))==1)) { @@ -286,7 +293,7 @@ THREAD_FUNCTION vp8_thread_decoding_proc(void *p_data) sem_post(&pbi->h_event_end_decoding); } - if ((pbi->b_multithreaded_lf) &&(pbi->common.filter_level)) + if ((pbi->b_multithreaded_lf) && (current_filter_level)) vp8_thread_loop_filter(pbi, mbrd, ithread); } diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c index 5cbd2a43e..a58b9b75d 100644 --- a/vp8/encoder/firstpass.c +++ b/vp8/encoder/firstpass.c @@ -2095,33 +2095,34 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) kf_group_intra_err += this_frame->intra_error; kf_group_coded_err += this_frame->coded_error; + // load a the next frame's stats vpx_memcpy(&last_frame, this_frame, sizeof(*this_frame)); + vp8_input_stats(cpi, this_frame); // Provided that we are not at the end of the file... - if (EOF != vp8_input_stats(cpi, this_frame)) + if (cpi->oxcf.auto_key + && lookup_next_frame_stats(cpi, &next_frame) != EOF) { - if (lookup_next_frame_stats(cpi, &next_frame) != EOF) - { - if (test_candidate_kf(cpi, &last_frame, this_frame, &next_frame)) - break; - } - } + if (test_candidate_kf(cpi, &last_frame, this_frame, &next_frame)) + break; - // Step on to the next frame - cpi->frames_to_key ++; - - // If we don't have a real key frame within the next two - // forcekeyframeevery intervals then break out of the loop. - if (cpi->frames_to_key >= 2 *(int)cpi->key_frame_frequency) - break; + // Step on to the next frame + cpi->frames_to_key ++; + // If we don't have a real key frame within the next two + // forcekeyframeevery intervals then break out of the loop. + if (cpi->frames_to_key >= 2 *(int)cpi->key_frame_frequency) + break; + } else + cpi->frames_to_key ++; } // If there is a max kf interval set by the user we must obey it. // We already breakout of the loop above at 2x max. // This code centers the extra kf if the actual natural // interval is between 1x and 2x - if ( cpi->frames_to_key > (int)cpi->key_frame_frequency ) + if (cpi->oxcf.auto_key + && cpi->frames_to_key > (int)cpi->key_frame_frequency ) { cpi->frames_to_key /= 2; @@ -2388,23 +2389,34 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) cpi->kf_bits = (3 * cpi->buffer_level) >> 2; } - // If the key frame is actually easier than the average for the kf group (which does sometimes happen... eg a blank intro frame) - // Then use an alternate calculation based on the kf error score which should give a smaller key frame. + // If the key frame is actually easier than the average for the + // kf group (which does sometimes happen... eg a blank intro frame) + // Then use an alternate calculation based on the kf error score + // which should give a smaller key frame. if (kf_mod_err < kf_group_err / cpi->frames_to_key) { - double alt_kf_grp_bits = ((double)cpi->bits_left * (kf_mod_err * (double)cpi->frames_to_key) / cpi->modified_total_error_left) ; + double alt_kf_grp_bits = + ((double)cpi->bits_left * + (kf_mod_err * (double)cpi->frames_to_key) / + DOUBLE_DIVIDE_CHECK(cpi->modified_total_error_left)); - alt_kf_bits = (int)((double)kf_boost * (alt_kf_grp_bits / (double)allocation_chunks)); + alt_kf_bits = (int)((double)kf_boost * + (alt_kf_grp_bits / (double)allocation_chunks)); if (cpi->kf_bits > alt_kf_bits) { cpi->kf_bits = alt_kf_bits; } } - // Else if it is much harder than other frames in the group make sure it at least receives an allocation in keeping with its relative error score + // Else if it is much harder than other frames in the group make sure + // it at least receives an allocation in keeping with its relative + // error score else { - alt_kf_bits = (int)((double)cpi->bits_left * (kf_mod_err / cpi->modified_total_error_left)); + alt_kf_bits = + (int)((double)cpi->bits_left * + (kf_mod_err / + DOUBLE_DIVIDE_CHECK(cpi->modified_total_error_left))); if (alt_kf_bits > cpi->kf_bits) { diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 99c434f52..fe83ae976 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -2818,24 +2818,18 @@ static int pick_frame_size(VP8_COMP *cpi) cm->frame_type = KEY_FRAME; } - // Auto key frames (Only two pass will enter here) + // Special case for forced key frames + // The frame sizing here is still far from ideal for 2 pass. + else if (cm->frame_flags & FRAMEFLAGS_KEY) + { + cm->frame_type = KEY_FRAME; + resize_key_frame(cpi); + vp8_calc_iframe_target_size(cpi); + } else if (cm->frame_type == KEY_FRAME) { vp8_calc_auto_iframe_target_size(cpi); } - // Forced key frames (by interval or an external signal) - else if ((cm->frame_flags & FRAMEFLAGS_KEY) || - (cpi->oxcf.auto_key && (cpi->frames_since_key % cpi->key_frame_frequency == 0))) - { - // Key frame from VFW/auto-keyframe/first frame - cm->frame_type = KEY_FRAME; - - resize_key_frame(cpi); - - // Compute target frame size - if (cpi->pass != 2) - vp8_calc_iframe_target_size(cpi); - } else { // INTER frame: compute target frame size diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c index d32808165..371272268 100644 --- a/vp8/encoder/ratectrl.c +++ b/vp8/encoder/ratectrl.c @@ -1444,6 +1444,9 @@ void vp8_adjust_key_frame_context(VP8_COMP *cpi) } else { + int last_kf_interval = + (cpi->frames_since_key > 0) ? cpi->frames_since_key : 1; + // reset keyframe context and calculate weighted average of last KEY_FRAME_CONTEXT keyframes for (i = 0; i < KEY_FRAME_CONTEXT; i++) { @@ -1454,8 +1457,8 @@ void vp8_adjust_key_frame_context(VP8_COMP *cpi) } else { - cpi->prior_key_frame_size[KEY_FRAME_CONTEXT - 1] = cpi->projected_frame_size; - cpi->prior_key_frame_distance[KEY_FRAME_CONTEXT - 1] = cpi->frames_since_key; + cpi->prior_key_frame_size[i] = cpi->projected_frame_size; + cpi->prior_key_frame_distance[i] = last_kf_interval; } av_key_frame_bits += prior_key_frame_weight[i] * cpi->prior_key_frame_size[i];