vf_zrmjpeg.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,069 行 · 第 1/3 页

C
1,069
字号
	short int *dest;	unsigned char *source;	// The first Y, Y0	get_pixels(j->s->block[0], y*8*j->y_rs + 16*x + y_data, j->y_rs);	// The second Y, Y1	get_pixels(j->s->block[1], y*8*j->y_rs + 16*x + 8 + y_data, j->y_rs);	if (!j->bw && j->cheap_upsample) {		source = y * 4 * j->u_rs + 8*x + u_data;		dest = j->s->block[2];		for (i = 0; i < 4; i++) {			for (k = 0; k < 8; k++) {				dest[k] = source[k];   // First row				dest[k+8] = source[k]; // Duplicate to next row			}			dest += 16;			source += j->u_rs;		}		source = y * 4 * j->v_rs + 8*x + v_data;		dest = j->s->block[3];		for (i = 0; i < 4; i++) {			for (k = 0; k < 8; k++) {				dest[k] = source[k];				dest[k+8] = source[k];			}			dest += 16;			source += j->u_rs;		}	} else if (!j->bw && !j->cheap_upsample) {		// U		get_pixels(j->s->block[2], y*8*j->u_rs + 8*x + u_data, j->u_rs);		// V		get_pixels(j->s->block[3], y*8*j->v_rs + 8*x + v_data, j->v_rs);	}}/** * \brief initialize mjpeg encoder * * This routine is to set up the parameters and initialize the mjpeg encoder. * It does all the initializations needed of lower level routines. * The formats accepted by this encoder is YUV422P and YUV420 * * \param w width in pixels of the image to encode, must be a multiple of 16 * \param h height in pixels of the image to encode, must be a multiple of 8 * \param y_rsize size of each plane row Y component * \param y_rsize size of each plane row U component * \param v_rsize size of each plane row V component * \param cu "cheap upsample". Set to 0 for YUV422 format, 1 for YUV420 format *           when set to 1, the encoder will assume that there is only half th *           number of rows of chroma information, and every chroma row is *           duplicated. * \param q quality parameter for the mjpeg encode. Between 1 and 20 where 1 *	    is best quality and 20 is the worst quality. * \param b monochrome flag. When set to 1, the mjpeg output is monochrome. *          In that case, the colour information is omitted, and actually the *          colour planes are not touched. * * \returns an appropriately set up jpeg_enc_t structure * * The actual plane buffer addreses are passed by jpeg_enc_frame(). * * The encoder doesn't know anything about interlacing, the halve height * needs to be passed and the double rowstride. Which field gets encoded * is decided by what buffers are passed to mjpeg_encode_frame() */static jpeg_enc_t *jpeg_enc_init(int w, int h, int y_rsize,			  int u_rsize, int v_rsize,		int cu, int q, int b) {	jpeg_enc_t *j;	int i = 0;	VERBOSE("JPEG encoder init: %dx%d %d %d %d cu=%d q=%d bw=%d\n",			w, h, y_rsize, u_rsize, v_rsize, cu, q, b);	j = av_mallocz(sizeof(jpeg_enc_t));	if (j == NULL) return NULL;	j->s = av_mallocz(sizeof(MpegEncContext));	if (j->s == NULL) {		av_free(j);		return NULL;	}	/* info on how to access the pixels */	j->y_rs = y_rsize;	j->u_rs = u_rsize;	j->v_rs = v_rsize;	j->s->width = w;		// image width and height	j->s->height = h;	j->s->qscale = q;		// Encoding quality	j->s->out_format = FMT_MJPEG;	j->s->intra_only = 1;		// Generate only intra pictures for jpeg	j->s->encoding = 1;		// Set mode to encode	j->s->pict_type = I_TYPE;	j->s->y_dc_scale = 8;	j->s->c_dc_scale = 8;	/*	 * This sets up the MCU (Minimal Code Unit) number	 * of appearances of the various component	 * for the SOF0 table in the generated MJPEG.	 * The values are not used for anything else.	 * The current setup is simply YUV422, with two horizontal Y components	 * for every UV component.	 */	//FIXME j->s->mjpeg_write_tables = 1;	// setup to write tables	j->s->mjpeg_vsample[0] = 1;	// 1 appearance of Y vertically	j->s->mjpeg_vsample[1] = 1;	// 1 appearance of U vertically	j->s->mjpeg_vsample[2] = 1;	// 1 appearance of V vertically	j->s->mjpeg_hsample[0] = 2;	// 2 appearances of Y horizontally	j->s->mjpeg_hsample[1] = 1;	// 1 appearance of U horizontally	j->s->mjpeg_hsample[2] = 1;	// 1 appearance of V horizontally	j->cheap_upsample = cu;	j->bw = b;	// Is this needed?	/* if libavcodec is used by the decoder then we must not	 * initialize again, but if it is not initialized then we must	 * initialize it here. */	if (!avcodec_inited) {		avcodec_init();		avcodec_register_all();		avcodec_inited=1;	}	// Build mjpeg huffman code tables, setting up j->s->mjpeg_ctx	if (ff_mjpeg_encode_init(j->s) < 0) {		av_free(j->s);		av_free(j);		return NULL;	}	/* alloc bogus avctx to keep MPV_common_init from segfaulting */	j->s->avctx = avcodec_alloc_context();	if (j->s->avctx == NULL) {		av_free(j->s);		av_free(j);		return NULL;	}	// Set some a minimum amount of default values that are needed	// Indicates that we should generated normal MJPEG	j->s->avctx->codec_id = CODEC_ID_MJPEG;	// Which DCT method to use. AUTO will select the fastest one	j->s->avctx->dct_algo = FF_DCT_AUTO;	j->s->intra_quant_bias= 1<<(QUANT_BIAS_SHIFT-1); //(a + x/2)/x	j->s->avctx->thread_count = 1;	/* make MPV_common_init allocate important buffers, like s->block	 * Also initializes dsputil */	if (MPV_common_init(j->s) < 0) {		av_free(j->s);		av_free(j);		return NULL;	}	/* correct the value for sc->mb_height. MPV_common_init put other	 * values there */	j->s->mb_height = j->s->height/8;	j->s->mb_intra = 1;	// Init q matrix	j->s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0];	for (i = 1; i < 64; i++)		j->s->intra_matrix[i] = av_clip_uint8(			(ff_mpeg1_default_intra_matrix[i]*j->s->qscale) >> 3);	// precompute matrix	convert_matrix(j->s, j->s->q_intra_matrix, j->s->q_intra_matrix16,			j->s->intra_matrix, j->s->intra_quant_bias, 8, 8);	/* Pick up the selection of the optimal get_pixels() routine	 * to use, which was done in  MPV_common_init() */	get_pixels = j->s->dsp.get_pixels;	return j;}/** * \brief mjpeg encode an image * * This routine will take a 3-plane YUV422 image and encoded it with MJPEG * base line format, as suitable as input for the Zoran hardare MJPEG chips. * * It requires that the \a j parameter points the structure set up by the * jpeg_enc_init() routine. * * \param j pointer to jpeg_enc_t structure as created by jpeg_enc_init() * \param y_data pointer to Y component plane, packed one byte/pixel * \param u_data pointer to U component plane, packed one byte per every *		 other pixel * \param v_data pointer to V component plane, packed one byte per every *		 other pixel * \param bufr pointer to the buffer where the mjpeg encoded code is stored * * \returns the number of bytes stored into \a bufr * * If \a j->s->mjpeg_write_tables is set, it will also emit the mjpeg tables, * otherwise it will just emit the data. The \a j->s->mjpeg_write_tables * variable will be reset to 0 by the routine. */static int jpeg_enc_frame(jpeg_enc_t *j, uint8_t *y_data,		   uint8_t *u_data, uint8_t *v_data, uint8_t *bufr) {	int mb_x, mb_y, overflow;	/* initialize the buffer */	init_put_bits(&j->s->pb, bufr, 1024*256);	// Emit the mjpeg header blocks	ff_mjpeg_encode_picture_header(j->s);	j->s->header_bits = put_bits_count(&j->s->pb);	j->s->last_dc[0] = 128;	j->s->last_dc[1] = 128;	j->s->last_dc[2] = 128;	for (mb_y = 0; mb_y < j->s->mb_height; mb_y++) {		for (mb_x = 0; mb_x < j->s->mb_width; mb_x++) {			/*			 * Fill one DCT block (8x8 pixels) from			 * 2 Y macroblocks and one U and one V			 */			fill_block(j, mb_x, mb_y, y_data, u_data, v_data);			emms_c(); /* is this really needed? */			j->s->block_last_index[0] =				j->s->dct_quantize(j->s, j->s->block[0],						0, 8, &overflow);			if (overflow) clip_coeffs(j->s, j->s->block[0],					j->s->block_last_index[0]);			j->s->block_last_index[1] =				j->s->dct_quantize(j->s, j->s->block[1],						1, 8, &overflow);			if (overflow) clip_coeffs(j->s, j->s->block[1],					j->s->block_last_index[1]);			if (!j->bw) {				j->s->block_last_index[4] =					j->s->dct_quantize(j->s, j->s->block[2],							4, 8, &overflow);				if (overflow) clip_coeffs(j->s, j->s->block[2],						j->s->block_last_index[2]);				j->s->block_last_index[5] =					j->s->dct_quantize(j->s, j->s->block[3],							5, 8, &overflow);				if (overflow) clip_coeffs(j->s, j->s->block[3],						j->s->block_last_index[3]);			}			zr_mjpeg_encode_mb(j);		}	}	emms_c();	ff_mjpeg_encode_picture_trailer(j->s);	flush_put_bits(&j->s->pb);	//FIXME	//if (j->s->mjpeg_write_tables == 1)	//	j->s->mjpeg_write_tables = 0;	return pbBufPtr(&(j->s->pb)) - j->s->pb.buf;}/// the real uninit routine/** * This is the real routine that does the uninit of the ZRMJPEG filter * * \param j pointer to jpeg_enc structure */static void jpeg_enc_uninit(jpeg_enc_t *j) {	ff_mjpeg_encode_close(j->s);	av_free(j->s);	av_free(j);}/// Private structure for ZRMJPEG filterstruct vf_priv_s {	jpeg_enc_t *j;	unsigned char buf[256*1024];	int bw, fd, hdec, vdec;	int fields;	int y_stride;	int c_stride;	int quality;	int maxwidth;	int maxheight;};/// vf CONFIGURE entry point for the ZRMJPEG filter/** * \param vf video filter instance pointer * \param width image source width in pixels * \param height image source height in pixels * \param d_width width of requested window, just a hint * \param d_height height of requested window, just a hint * \param flags vf filter flags * \param outfmt * * \returns returns 0 on error * * This routine will make the necessary hardware-related decisions for * the ZRMJPEG filter, do the initialization of the MJPEG encoder, and * then select one of the ZRJMJPEGIT or ZRMJPEGNI filters and then * arrange to dispatch to the config() entry pointer for the one * selected. */static int config(struct vf_instance_s* vf, int width, int height, int d_width,		int d_height, unsigned int flags, unsigned int outfmt){	struct vf_priv_s *priv = vf->priv;	float aspect_decision;	int stretchx, stretchy, err = 0, maxstretchx = 4;	priv->fields = 1;	VERBOSE("config() called\n");	if (priv->j) {		VERBOSE("re-configuring, resetting JPEG encoder\n");		jpeg_enc_uninit(priv->j);		priv->j = NULL;	}	aspect_decision = ((float)d_width/(float)d_height)/		((float)width/(float)height);	if (aspect_decision > 1.8 && aspect_decision < 2.2) {		VERBOSE("should correct aspect by stretching x times 2, %d %d\n", 2*width, priv->maxwidth);		if (2*width <= priv->maxwidth) {			d_width = 2*width;			d_height = height;			maxstretchx = 2;		} else {			WARNING("unable to correct aspect by stretching, because resulting X will be too large, aspect correction by decimating y not yet implemented\n");			d_width = width;			d_height = height;		}		/* prestretch movie */	} else {		/* uncorrecting output for now */		d_width = width;		d_height = height;	}	/* make the scaling decision	 * we are capable of stretching the image in the horizontal	 * direction by factors 1, 2 and 4	 * we can stretch the image in the vertical direction by a	 * factor of 1 and 2 AND we must decide about interlacing */	if (d_width > priv->maxwidth/2 || height > priv->maxheight/2			|| maxstretchx == 1) {		stretchx = 1;		stretchy = 1;		priv->fields = 2;

⌨️ 快捷键说明

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