⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yuvscaler_resample.c

📁 Motion JPEG编解码器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <math.h>#include <signal.h>#include "yuv4mpeg.h"#include "mjpeg_types.h"#include "yuvscaler.h"// From outide MAIN : global variablesextern unsigned int input_width;extern unsigned int output_width;// Downscaling ratiosextern unsigned int input_height_slice;extern unsigned int output_height_slice;extern unsigned int input_width_slice;extern unsigned int output_width_slice;extern int interlaced; extern unsigned int output_active_width;extern unsigned int output_active_height;extern int line_switching;extern unsigned int specific;extern unsigned int out_nb_col_slice, out_nb_line_slice;extern uint8_t *divide;// From inside MAIN function// *************************************************************************************intaverage_coeff (unsigned int input_length, unsigned int output_length,	       unsigned int *coeff){  // This function calculates multiplicative coeeficients to average an input (vector of) length  // input_length into an output (vector of) length output_length;  // We sequentially store the number-of-non-zero-coefficients, followed by the coefficients  // themselvesc, and that, output_length time  int last_coeff = 0, remaining_coeff, still_to_go = 0, in, out, non_zero =    0, nb;  unsigned int *non_zero_p = NULL;  unsigned int *pointer;  if ((output_length > input_length) || (input_length == 0)      || (output_length == 0) || (coeff == NULL))    {      mjpeg_error ("Function average_coeff : arguments are wrong");      mjpeg_error ("input length = %d, output length = %d, input = %p",		   input_length, output_length, coeff);      exit (1);    }#ifdef DEBUG  mjpeg_debug    ("Function average_coeff : input length = %d, output length = %d, input = %p",     input_length, output_length, coeff);#endif  pointer = coeff;  if (output_length == 1)    {      *pointer = input_length;      pointer++;      for (in = 0; in < input_length; in++)	{	  *pointer = 1;	  pointer++;	}    }  else    {      for (in = 0; in < output_length; in++)	{	  non_zero = 0;	  non_zero_p = pointer;	  pointer++;	  still_to_go = input_length;	  if (last_coeff > 0)	    {	      remaining_coeff = output_length - last_coeff;	      *pointer = remaining_coeff;	      pointer++;	      non_zero++;	      still_to_go -= remaining_coeff;	    }	  nb = (still_to_go / output_length);#ifdef DEBUG	  mjpeg_debug ("in=%d,nb=%d,stgo=%d ol=%d", in, nb, still_to_go,		       output_length);#endif	  for (out = 0; out < nb; out++)	    {	      *pointer = output_length;	      pointer++;	    }	  still_to_go -= nb * output_length;	  non_zero += nb;	  if ((last_coeff = still_to_go) != 0)	    {	      *pointer = last_coeff;#ifdef DEBUG	      mjpeg_debug ("non_zero=%d,last_coeff=%d", non_zero,			   last_coeff);#endif	      pointer++;	// now pointer points onto the next number-of-non_zero-coefficients	      non_zero++;	      *non_zero_p = non_zero;	    }	  else	    {	      if (in != output_length - 1)		{		  mjpeg_error		    ("There is a common divider between %d and %d\n This should not be the case",		     input_length, output_length);		  exit (1);		}	    }	}      *non_zero_p = non_zero;      if (still_to_go != 0)	{	  mjpeg_error	    ("Function average_coeff : calculus doesn't stop right : %d",	     still_to_go);	}    }#ifdef DEBUG  if (verbose == 2)    {      int i, j;      for (i = 0; i < output_length; i++)	{	  mjpeg_debug ("line=%d", i);	  non_zero = *coeff;	  coeff++;	  mjpeg_debug (" ");	  for (j = 0; j < non_zero; j++)	    {	      fprintf (stderr, "%d : %d ", j, *coeff);	      coeff++;	    }	  fprintf (stderr, "\n");	}    }#endif   return (0);}// *************************************************************************************// *************************************************************************************intaverage (uint8_t * input, uint8_t * output, unsigned int *height_coeff,	 unsigned int *width_coeff, unsigned int half){  // This function average an input matrix of name input and of size local_input_width*(local_out_nb_line_slice*input_height_slice)  // into an output matrix of name output and of size local_output_width*(local_out_nb_line_slice+output_height_slice)  // input and output images are interleaved  // if half==1 => we are dealing with an U or V component => height and width are / 2 => for speed sake, we use >>half  unsigned int local_input_width = input_width >> half;  unsigned int local_output_width = output_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;  uint8_t *input_line_p[input_height_slice];  uint8_t *output_line_p[output_height_slice];  unsigned int *H_var, *W_var, *H, *W;  uint8_t *u_c_p;  int j, nb_H, nb_W, in_line, first_line, out_line;  int out_col_slice, out_col;  int out_line_slice;  int current_line, last_line;  unsigned long int value = 0;  //Init  mjpeg_debug ("Start of average");  //End of INIT  if (interlaced == Y4M_ILACE_NONE)    {      mjpeg_debug ("Non-interlaced downscaling");      // output frames are not interlaced => averaging will generate output lines is growing order,       // output_height_slice lines per output_height_slice lines.       // More important is the following question :      // is input frames CONTENT interlaced or not (input frames are then said progressives). If content is interlaced (odd lines corresponds to time t       // and even lines to another time t+dt with dt=1/(2*frame_rate)), then input frames should be DEINTERLACED prior to averaging      // So, if input frames are interlaced, we will suppose they are progressives      // TO BE PROGRAMMED, cf. FlaskMPEG      for (out_line_slice = 0; out_line_slice < local_out_nb_line_slice;	   out_line_slice++)	{	  u_c_p = input +	    out_line_slice * input_height_slice * 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 += 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_slice = 0; out_col_slice < local_out_nb_col_slice;	       out_col_slice++)	    {	      H = height_coeff;	      first_line = 0;	      for (out_line = 0; out_line < output_height_slice; out_line++)		{		  nb_H = *H;		  W = width_coeff;		  for (out_col = 0; out_col < output_width_slice; out_col++)		    {		      H_var = H + 1;		      nb_W = *W;		      value = 0;		      last_line = first_line + nb_H;		      for (current_line = first_line;			   current_line < last_line; current_line++)			{			  W_var = W + 1;			  // we average nb_W columns of input : we increment input_line_p[current_line] and W_var each time, except for the last value where 			  // input_line_p[current_line] and W_var do not need to be incremented, but H_var does			  for (j = 0; j < nb_W - 1; j++)			    value +=			      (*H_var) * (*W_var++) *			      (*input_line_p[current_line]++);			  value +=			    (*H_var++) * (*W_var) *			    (*input_line_p[current_line]);			}		      //                Straiforward implementation is 		      //                *(output_line_p[out_line]++)=value/diviseur;		      //                round_off_error=value%diviseur;		      //                Here, we speed up things but using the pretabulated nearest integral parts		      *(output_line_p[out_line]++) = divide[value];		      W += nb_W + 1;		    }		  H += nb_H + 1;		  first_line += nb_H - 1;		  input_line_p[first_line] -= input_width_slice - 1;		  // If last line of input is to be reused in next loop, 		  // make the pointer points at the correct place		}	      input_line_p[first_line] += input_width_slice - 1;	      for (in_line = 0; in_line < input_height_slice; in_line++)		input_line_p[in_line]++;	    }	}    }  else    {      // output frames are interlaced, line numbers gioes from 0 to n-1.       // Therefore, downscaling is done between odd lines, then between even lines, but we do not mix odd and even lines.      // So, we have to calculate the even and odd part of out_line_slice.       // If the odd part is naturally out_line_slice % 2, the even part is (out_line_slice/2)*2. For speed reason,       // the even part will be xritten as out_line_slice & ~(unsigned int) 1      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_slice = 0; out_col_slice < local_out_nb_col_slice;	       out_col_slice++)	    {	      H = height_coeff;	      first_line = 0;	      for (out_line = 0; out_line < output_height_slice; out_line++)		{		  nb_H = *H;		  W = width_coeff;		  for (out_col = 0; out_col < output_width_slice; out_col++)		    {		      H_var = H + 1;		      nb_W = *W;		      value = 0;		      last_line = first_line + nb_H;		      for (current_line = first_line;			   current_line < last_line; current_line++)			{			  W_var = W + 1;			  // we average nb_W columns of input : we increment input_line_p[current_line] and W_var each time, except for the last value where 			  // input_line_p[current_line] and W_var do not need to be incremented, but H_var does			  for (j = 0; j < nb_W - 1; j++)			    value +=			      (*H_var) * (*W_var++) *			      (*input_line_p[current_line]++);			  value +=			    (*H_var++) * (*W_var) *			    (*input_line_p[current_line]);			}		      //                Straiforward implementation is 		      //                *(output_line_p[out_line]++)=value/diviseur;		      //                round_off_error=value%diviseur;		      //                Here, we speed up things but using the pretabulated integral parts		      *(output_line_p[out_line]++) = divide[value];		      W += nb_W + 1;		    }		  H += nb_H + 1;		  first_line += nb_H - 1;		  input_line_p[first_line] -= input_width_slice - 1;		  // If last line of input is to be reused in next loop, 		  // make the pointer points at the correct place		}	      input_line_p[first_line] += input_width_slice - 1;	      for (in_line = 0; in_line < input_height_slice; in_line++)		input_line_p[in_line]++;	    }	}    }  mjpeg_debug ("End of average");  return (0);}// *************************************************************************************// *************************************************************************************intaverage_specific (uint8_t * input, uint8_t * output,		  unsigned int *height_coeff, unsigned int *width_coeff,		  unsigned int half)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -