📄 yuvscaler_resample.c
字号:
{ // This function gathers code that are speed enhanced due to specific downscaling ratios unsigned int line_index; unsigned int local_output_active_height = output_active_height >> half; unsigned int local_input_width = input_width >> half; unsigned int local_output_width = output_width >> half; unsigned int local_output_active_width = output_active_width >> half; unsigned int local_out_nb_col_slice = out_nb_col_slice >> half; unsigned int local_out_nb_line_slice = out_nb_line_slice >> half; unsigned int number,in_line_offset,out_line_offset; // specific==1, 4 uint8_t temp_uint8_t; uint8_t *in_line_p; uint8_t *out_line_p; unsigned int *W_var, *W; int j, nb_W; unsigned int out_col_slice, out_col; int treatment = 0; unsigned long int value = 0, value1 = 0, value2 = 0, value3 = 0; // Specific==2 uint8_t *in_first_line_p, *in_second_line_p; unsigned int out_line; // specific=3 unsigned char *u_c_p; unsigned int in_line; uint8_t *input_line_p[input_height_slice]; // specific=5 unsigned int *H_var, *H; unsigned int nb_H, first_line, last_line, current_line; unsigned int out_line_slice; uint8_t *output_line_p[output_height_slice]; //Init mjpeg_debug ("Start of average_specific %u", specific); //End of INIT if (specific == 1) { treatment = 1; mjpeg_debug ("Non interlaced and/or interlaced treatment"); // We just take the average along the width, not the height, line per line // Infered from average, with input_height_slice=output_height_slice=1; for (line_index = 0; line_index < local_output_active_height; line_index++) { in_line_p = input + line_index * local_input_width; out_line_p = output + line_index * local_output_width; for (out_col_slice = 0; out_col_slice < local_out_nb_col_slice; out_col_slice++) { W = width_coeff; for (out_col = 0; out_col < output_width_slice; out_col++) { nb_W = *W; value = 0; W_var = W + 1; for (j = 0; j < nb_W - 1; j++) value += (*W_var++) * (*in_line_p++); value += (*W_var) * (*in_line_p); *(out_line_p++) = divide[value]; W += nb_W + 1; } in_line_p++; } } } if (specific == 2) { treatment = 2; // SPECIAL FAST Full_size to VCD downscaling : 2to1 for width and height // Since 2 to 1 height dowscaling, no need for line switching // Drawback: slight distortion on width if (interlaced == Y4M_ILACE_NONE) { mjpeg_debug ("Non-interlaced downscaling"); for (out_line = 0; out_line < local_output_active_height; out_line++) { in_first_line_p = input + out_line * (local_input_width << 1); in_second_line_p = in_first_line_p + local_input_width; out_line_p = output + out_line * local_output_width; for (out_col = 0; out_col < local_output_active_width; out_col++) { // Division of integers is always made by default. This results in a systematic drift towards smaller values. // What we really need, // is a division that takes the nearest integer. // So, we add 1/2 of the divider to the value to be divided// *(out_line_p++) =// (2 + *(in_first_line_p) + *(in_first_line_p + 1) +// *(in_second_line_p) + *(in_second_line_p + 1)) >> 2; *(out_line_p++) = divide[*(in_first_line_p) + *(in_first_line_p + 1) + *(in_second_line_p) + *(in_second_line_p + 1)]; in_first_line_p += 2; in_second_line_p += 2; } } } else { mjpeg_debug ("Interlaced downscaling"); for (line_index = 0; line_index < local_output_active_height; line_index++) { in_first_line_p = input + (((line_index & ~(unsigned int) 1) << 1) + (line_index % 2)) * local_input_width; in_second_line_p = in_first_line_p + (local_input_width << 1); out_line_p = output + line_index * local_output_width; for (out_col = 0; out_col < local_output_active_width; out_col++) {/* *(out_line_p++) = (2 + *(in_first_line_p) + *(in_first_line_p + 1) + *(in_second_line_p) + *(in_second_line_p + 1)) >> 2;*/ *(out_line_p++) = divide[*(in_first_line_p) + *(in_first_line_p + 1) + * (in_second_line_p) + * (in_second_line_p + 1)]; in_first_line_p += 2; in_second_line_p += 2; } } } } if (specific == 3) { treatment = 3; // input_height_slice=2, output_height_slice=1 => input lines will be summed together. // infered from average with output_height_slice=1 and explicity writting of the for(in_line=0;in_line<input_height_slice;in_line++) // Special VCD downscaling without width distortion if (interlaced == Y4M_ILACE_NONE) { mjpeg_debug ("Non-interlaced downscaling"); for (out_line = 0; out_line < local_output_active_height; out_line++) { input_line_p[0] = input + out_line * input_height_slice * local_input_width; input_line_p[1] = input_line_p[0] + local_input_width; out_line_p = output + out_line * local_output_width; for (out_col_slice = 0; out_col_slice < local_out_nb_col_slice; out_col_slice++) { W = width_coeff; for (out_col = 0; out_col < output_width_slice; out_col++) { nb_W = *W; value = 0; W_var = W + 1; for (j = 0; j < nb_W - 1; j++) value += (*W_var++) * ((*input_line_p[0]++) + (*input_line_p[1]++)); value += (*W_var) * (*input_line_p[0] + *input_line_p[1]); *(out_line_p++) = divide[value]; W += nb_W + 1; } input_line_p[0]++; input_line_p[1]++; } } } else { mjpeg_debug ("Interlaced downscaling"); for (line_index = 0; line_index < local_output_active_height; line_index++) { input_line_p[0] = input + (input_height_slice * (line_index & ~(unsigned int) 1) + line_index % 2) * local_input_width; input_line_p[1] = input_line_p[0] + 2 * local_input_width; out_line_p = output + line_index * local_output_width; for (out_col_slice = 0; out_col_slice < (out_nb_col_slice >> half); out_col_slice++) { W = width_coeff; for (out_col = 0; out_col < output_width_slice; out_col++) { nb_W = *W; value = 0; W_var = W + 1; for (j = 0; j < nb_W - 1; j++) value += (*W_var++) * ((*input_line_p[0]++) + (*input_line_p[1]++)); value += (*W_var) * (*input_line_p[0] + *input_line_p[1]); *(out_line_p++) = divide[value]; W += nb_W + 1; } input_line_p[0]++; input_line_p[1]++; } } } } if (specific == 4) { // just a copy: we copy line per line (warning! these lines are output_width long BUT we only copy output_active_width length of them) treatment = 4; mjpeg_debug ("Non-interlaced or interlaced downscaling"); for (line_index = 0; line_index < local_output_active_height; line_index++)// ; memcpy (output + line_index * local_output_width, input + line_index * local_input_width, local_output_active_width); } if (specific == 5) { // We downscale only lines along the height, not the width treatment = 5; if (interlaced == Y4M_ILACE_NONE) { mjpeg_debug ("Non-interlaced downscaling"); for (out_line_slice = 0; out_line_slice < local_out_nb_line_slice; out_line_slice++) { for (in_line = 0; in_line < input_height_slice; in_line++) { number = out_line_slice * input_height_slice + in_line; input_line_p[in_line] = input + number * local_input_width; } u_c_p = output + out_line_slice * output_height_slice * local_output_width; for (out_line = 0; out_line < output_height_slice; out_line++) { output_line_p[out_line] = u_c_p; u_c_p += local_output_width; } for (out_col = 0; out_col < local_output_active_width; out_col++) { H = height_coeff; first_line = 0; for (out_line = 0; out_line < output_height_slice; out_line++) { nb_H = *H; H_var = H + 1; value = 0; last_line = first_line + nb_H; for (current_line = first_line; current_line < last_line; current_line++) value += (*H_var++) * (*input_line_p[current_line]); *(output_line_p[out_line]++) = divide[value]; H += nb_H + 1; first_line += nb_H - 1; } for (in_line = 0; in_line < input_height_slice; in_line++) input_line_p[in_line]++; } } } else { mjpeg_debug ("Interlaced downscaling"); for (out_line_slice = 0; out_line_slice < local_out_nb_line_slice; out_line_slice++) { u_c_p = input + ((out_line_slice & ~(unsigned int) 1) * input_height_slice + out_line_slice % 2) * local_input_width; for (in_line = 0; in_line < input_height_slice; in_line++) { input_line_p[in_line] = u_c_p; u_c_p += 2 * local_input_width; } u_c_p = output + ((out_line_slice & ~(unsigned int) 1) * output_height_slice + out_line_slice % 2) * local_output_width; for (out_line = 0; out_line < output_height_slice; out_line++) { output_line_p[out_line] = u_c_p; u_c_p += 2 * local_output_width; } for (out_col = 0; out_col < local_output_active_width; out_col++) { H = height_coeff; first_line = 0; for (out_line = 0; out_line < output_height_slice; out_line++) { nb_H = *H; H_var = H + 1; value = 0; last_line = first_line + nb_H; for (current_line = first_line; current_line < last_line; current_line++) value += (*H_var++) * (*input_line_p[current_line]); *(output_line_p[out_line]++) = divide[value]; H += nb_H + 1; first_line += nb_H - 1; } for (in_line = 0; in_line < input_height_slice; in_line++) input_line_p[in_line]++; } } } } if (specific == 6) { // Dedicated SVCD: we downscale 3 for 2 on width, and 1 to 1 on height. Infered from specific=1 // For width, W points are "2 2 1 2 1 2" => we can explicitely write down the calculs of value treatment = 6; mjpeg_debug ("Non interlaced and/or interlaced treatment"); in_line_offset = local_input_width - local_out_nb_col_slice * 3; out_line_offset = local_output_width - local_out_nb_col_slice * 2; in_line_p = input; out_line_p = output; for (line_index = 0; line_index < local_output_active_height; line_index++) {// in_line_p = input + line_index * local_input_width;// out_line_p = output + line_index * local_output_width; for (out_col_slice = 0; out_col_slice < local_out_nb_col_slice; out_col_slice++) { temp_uint8_t = in_line_p[1];// *(out_line_p++) = divide[((*in_line_p) << 1) + temp_uint8_t]; *(out_line_p++) = (((*in_line_p) << 1) + temp_uint8_t + 1) / 3; in_line_p += 2;// *(out_line_p++) = divide[temp_uint8_t + ((*in_line_p++) << 1)]; *(out_line_p++) = (temp_uint8_t + ((*in_line_p++) << 1) + 1) / 3; } in_line_p += in_line_offset; out_line_p += out_line_offset; } } if (specific == 7) { // Dedicated to WIDE2STD alone downscaling: 4 to 3 on height, width not downscaled // For the height, H is equal to 2 3 1 2 2 2 2 1 3 // Infered from specific=5 treatment = 7;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -