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

📄 bitstream.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
 *
 *  XVID MPEG-4 VIDEO CODEC
 *  - Bitstream reader/writer -
 *
 *  Copyright (C) 2001-2003 Peter Ross <pross@xvid.org>
 *                     2003 Cristoph Lampert <gruel@web.de>
 *
 *  This program is free software ; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation ; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY ; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program ; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * $Id: bitstream.c,v 1.57 2007/04/16 19:01:28 Skal Exp $
 *
 ****************************************************************************/

#include <string.h>
#include <stdio.h>

#include "bitstream.h"
#include "zigzag.h"
#include "../quant/quant_matrix.h"
#include "mbcoding.h"


static const uint8_t log2_tab_16[16] =  { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
 
static uint32_t __inline log2bin(uint32_t value)
{
  int n = 0;
  if (value & 0xffff0000) {
    value >>= 16;
    n += 16;
  }
  if (value & 0xff00) {
    value >>= 8;
    n += 8;
  }
  if (value & 0xf0) {
    value >>= 4;
    n += 4;
  }
 return n + log2_tab_16[value];
}

static const uint32_t intra_dc_threshold_table[] = {
	32,							/* never use */
	13,
	15,
	17,
	19,
	21,
	23,
	1,
};


static void
bs_get_matrix(Bitstream * bs,
			  uint8_t * matrix)
{
	int i = 0;
	int last, value = 0;

	do {
		last = value;
		value = BitstreamGetBits(bs, 8);
		matrix[scan_tables[0][i++]] = value;
	}
	while (value != 0 && i < 64);

	if (value != 0) return;

	i--;
	while (i < 64) {
		matrix[scan_tables[0][i++]] = last;
	}
}



/*
 * for PVOP addbits == fcode - 1
 * for BVOP addbits == max(fcode,bcode) - 1
 * returns mbpos
 */
int
read_video_packet_header(Bitstream *bs,
						DECODER * dec,
						const int addbits,
						int * quant,
						int * fcode_forward,
						int  * fcode_backward,
						int * intra_dc_threshold)
{
	int startcode_bits = NUMBITS_VP_RESYNC_MARKER + addbits;
	int mbnum_bits = log2bin(dec->mb_width *  dec->mb_height - 1);
	int mbnum;
	int hec = 0;

	BitstreamSkip(bs, BitstreamNumBitsToByteAlign(bs));
	BitstreamSkip(bs, startcode_bits);

	DPRINTF(XVID_DEBUG_STARTCODE, "<video_packet_header>\n");

	if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR)
	{
		hec = BitstreamGetBit(bs);		/* header_extension_code */
		if (hec && !(dec->sprite_enable == SPRITE_STATIC /* && current_coding_type = I_VOP */))
		{
			BitstreamSkip(bs, 13);			/* vop_width */
			READ_MARKER();
			BitstreamSkip(bs, 13);			/* vop_height */
			READ_MARKER();
			BitstreamSkip(bs, 13);			/* vop_horizontal_mc_spatial_ref */
			READ_MARKER();
			BitstreamSkip(bs, 13);			/* vop_vertical_mc_spatial_ref */
			READ_MARKER();
		}
	}

	mbnum = BitstreamGetBits(bs, mbnum_bits);		/* macroblock_number */
	DPRINTF(XVID_DEBUG_HEADER, "mbnum %i\n", mbnum);

	if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY)
	{
		*quant = BitstreamGetBits(bs, dec->quant_bits);	/* quant_scale */
		DPRINTF(XVID_DEBUG_HEADER, "quant %i\n", *quant);
	}

	if (dec->shape == VIDOBJLAY_SHAPE_RECTANGULAR)
		hec = BitstreamGetBit(bs);		/* header_extension_code */


	DPRINTF(XVID_DEBUG_HEADER, "header_extension_code %i\n", hec);
	if (hec)
	{
		int time_base;
		int time_increment;
		int coding_type;

		for (time_base=0; BitstreamGetBit(bs)!=0; time_base++);		/* modulo_time_base */
		READ_MARKER();
		if (dec->time_inc_bits)
			time_increment = (BitstreamGetBits(bs, dec->time_inc_bits));	/* vop_time_increment */
		READ_MARKER();
		DPRINTF(XVID_DEBUG_HEADER,"time %i:%i\n", time_base, time_increment);

		coding_type = BitstreamGetBits(bs, 2);
		DPRINTF(XVID_DEBUG_HEADER,"coding_type %i\n", coding_type);

		if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR)
		{
			BitstreamSkip(bs, 1);	/* change_conv_ratio_disable */
			if (coding_type != I_VOP)
				BitstreamSkip(bs, 1);	/* vop_shape_coding_type */
		}

		if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY)
		{
			*intra_dc_threshold = intra_dc_threshold_table[BitstreamGetBits(bs, 3)];

			if (dec->sprite_enable == SPRITE_GMC && coding_type == S_VOP &&
				dec->sprite_warping_points > 0)
			{
				/* TODO: sprite trajectory */
			}
			if (dec->reduced_resolution_enable &&
				dec->shape == VIDOBJLAY_SHAPE_RECTANGULAR &&
				(coding_type == P_VOP || coding_type == I_VOP))
			{
				BitstreamSkip(bs, 1); /* XXX: vop_reduced_resolution */
			}

			if (coding_type != I_VOP && fcode_forward)
			{
				*fcode_forward = BitstreamGetBits(bs, 3);
				DPRINTF(XVID_DEBUG_HEADER,"fcode_forward %i\n", *fcode_forward);
			}

			if (coding_type == B_VOP && fcode_backward)
			{
				*fcode_backward = BitstreamGetBits(bs, 3);
				DPRINTF(XVID_DEBUG_HEADER,"fcode_backward %i\n", *fcode_backward);
			}
		}
	}

	if (dec->newpred_enable)
	{
		int vop_id;
		int vop_id_for_prediction;

		vop_id = BitstreamGetBits(bs, MIN(dec->time_inc_bits + 3, 15));
		DPRINTF(XVID_DEBUG_HEADER, "vop_id %i\n", vop_id);
		if (BitstreamGetBit(bs))	/* vop_id_for_prediction_indication */
		{
			vop_id_for_prediction = BitstreamGetBits(bs, MIN(dec->time_inc_bits + 3, 15));
			DPRINTF(XVID_DEBUG_HEADER, "vop_id_for_prediction %i\n", vop_id_for_prediction);
		}
		READ_MARKER();
	}

	return mbnum;
}




/* vol estimation header */
static void
read_vol_complexity_estimation_header(Bitstream * bs, DECODER * dec)
{
	ESTIMATION * e = &dec->estimation;

	e->method = BitstreamGetBits(bs, 2);	/* estimation_method */
	DPRINTF(XVID_DEBUG_HEADER,"+ complexity_estimation_header; method=%i\n", e->method);

	if (e->method == 0 || e->method == 1)
	{
		if (!BitstreamGetBit(bs))		/* shape_complexity_estimation_disable */
		{
			e->opaque = BitstreamGetBit(bs);		/* opaque */
			e->transparent = BitstreamGetBit(bs);		/* transparent */
			e->intra_cae = BitstreamGetBit(bs);		/* intra_cae */
			e->inter_cae = BitstreamGetBit(bs);		/* inter_cae */
			e->no_update = BitstreamGetBit(bs);		/* no_update */
			e->upsampling = BitstreamGetBit(bs);		/* upsampling */
		}

		if (!BitstreamGetBit(bs))	/* texture_complexity_estimation_set_1_disable */
		{
			e->intra_blocks = BitstreamGetBit(bs);		/* intra_blocks */
			e->inter_blocks = BitstreamGetBit(bs);		/* inter_blocks */
			e->inter4v_blocks = BitstreamGetBit(bs);		/* inter4v_blocks */
			e->not_coded_blocks = BitstreamGetBit(bs);		/* not_coded_blocks */
		}
	}

	READ_MARKER();

	if (!BitstreamGetBit(bs))		/* texture_complexity_estimation_set_2_disable */
	{
		e->dct_coefs = BitstreamGetBit(bs);		/* dct_coefs */
		e->dct_lines = BitstreamGetBit(bs);		/* dct_lines */
		e->vlc_symbols = BitstreamGetBit(bs);		/* vlc_symbols */
		e->vlc_bits = BitstreamGetBit(bs);		/* vlc_bits */
	}

	if (!BitstreamGetBit(bs))		/* motion_compensation_complexity_disable */
	{
		e->apm = BitstreamGetBit(bs);		/* apm */
		e->npm = BitstreamGetBit(bs);		/* npm */
		e->interpolate_mc_q = BitstreamGetBit(bs);		/* interpolate_mc_q */
		e->forw_back_mc_q = BitstreamGetBit(bs);		/* forw_back_mc_q */
		e->halfpel2 = BitstreamGetBit(bs);		/* halfpel2 */
		e->halfpel4 = BitstreamGetBit(bs);		/* halfpel4 */
	}

	READ_MARKER();

	if (e->method == 1)
	{
		if (!BitstreamGetBit(bs))	/* version2_complexity_estimation_disable */
		{
			e->sadct = BitstreamGetBit(bs);		/* sadct */
			e->quarterpel = BitstreamGetBit(bs);		/* quarterpel */
		}
	}
}


/* vop estimation header */
static void
read_vop_complexity_estimation_header(Bitstream * bs, DECODER * dec, int coding_type)
{
	ESTIMATION * e = &dec->estimation;

	if (e->method == 0 || e->method == 1)
	{
		if (coding_type == I_VOP) {
			if (e->opaque)		BitstreamSkip(bs, 8);	/* dcecs_opaque */
			if (e->transparent) BitstreamSkip(bs, 8);	/* */
			if (e->intra_cae)	BitstreamSkip(bs, 8);	/* */
			if (e->inter_cae)	BitstreamSkip(bs, 8);	/* */
			if (e->no_update)	BitstreamSkip(bs, 8);	/* */
			if (e->upsampling)	BitstreamSkip(bs, 8);	/* */
			if (e->intra_blocks) BitstreamSkip(bs, 8);	/* */
			if (e->not_coded_blocks) BitstreamSkip(bs, 8);	/* */
			if (e->dct_coefs)	BitstreamSkip(bs, 8);	/* */
			if (e->dct_lines)	BitstreamSkip(bs, 8);	/* */
			if (e->vlc_symbols) BitstreamSkip(bs, 8);	/* */
			if (e->vlc_bits)	BitstreamSkip(bs, 8);	/* */
			if (e->sadct)		BitstreamSkip(bs, 8);	/* */
		}

		if (coding_type == P_VOP) {
			if (e->opaque) BitstreamSkip(bs, 8);		/* */
			if (e->transparent) BitstreamSkip(bs, 8);	/* */
			if (e->intra_cae)	BitstreamSkip(bs, 8);	/* */
			if (e->inter_cae)	BitstreamSkip(bs, 8);	/* */
			if (e->no_update)	BitstreamSkip(bs, 8);	/* */
			if (e->upsampling) BitstreamSkip(bs, 8);	/* */
			if (e->intra_blocks) BitstreamSkip(bs, 8);	/* */
			if (e->not_coded_blocks)	BitstreamSkip(bs, 8);	/* */
			if (e->dct_coefs)	BitstreamSkip(bs, 8);	/* */
			if (e->dct_lines)	BitstreamSkip(bs, 8);	/* */
			if (e->vlc_symbols) BitstreamSkip(bs, 8);	/* */
			if (e->vlc_bits)	BitstreamSkip(bs, 8);	/* */
			if (e->inter_blocks) BitstreamSkip(bs, 8);	/* */
			if (e->inter4v_blocks) BitstreamSkip(bs, 8);	/* */
			if (e->apm)			BitstreamSkip(bs, 8);	/* */
			if (e->npm)			BitstreamSkip(bs, 8);	/* */
			if (e->forw_back_mc_q) BitstreamSkip(bs, 8);	/* */
			if (e->halfpel2)	BitstreamSkip(bs, 8);	/* */
			if (e->halfpel4)	BitstreamSkip(bs, 8);	/* */
			if (e->sadct)		BitstreamSkip(bs, 8);	/* */
			if (e->quarterpel)	BitstreamSkip(bs, 8);	/* */
		}
		if (coding_type == B_VOP) {
			if (e->opaque)		BitstreamSkip(bs, 8);	/* */
			if (e->transparent)	BitstreamSkip(bs, 8);	/* */
			if (e->intra_cae)	BitstreamSkip(bs, 8);	/* */
			if (e->inter_cae)	BitstreamSkip(bs, 8);	/* */
			if (e->no_update)	BitstreamSkip(bs, 8);	/* */
			if (e->upsampling)	BitstreamSkip(bs, 8);	/* */
			if (e->intra_blocks) BitstreamSkip(bs, 8);	/* */
			if (e->not_coded_blocks) BitstreamSkip(bs, 8);	/* */
			if (e->dct_coefs)	BitstreamSkip(bs, 8);	/* */
			if (e->dct_lines)	BitstreamSkip(bs, 8);	/* */
			if (e->vlc_symbols)	BitstreamSkip(bs, 8);	/* */
			if (e->vlc_bits)	BitstreamSkip(bs, 8);	/* */
			if (e->inter_blocks) BitstreamSkip(bs, 8);	/* */
			if (e->inter4v_blocks) BitstreamSkip(bs, 8);	/* */
			if (e->apm)			BitstreamSkip(bs, 8);	/* */
			if (e->npm)			BitstreamSkip(bs, 8);	/* */
			if (e->forw_back_mc_q) BitstreamSkip(bs, 8);	/* */
			if (e->halfpel2)	BitstreamSkip(bs, 8);	/* */
			if (e->halfpel4)	BitstreamSkip(bs, 8);	/* */
			if (e->interpolate_mc_q) BitstreamSkip(bs, 8);	/* */
			if (e->sadct)		BitstreamSkip(bs, 8);	/* */
			if (e->quarterpel)	BitstreamSkip(bs, 8);	/* */
		}

		if (coding_type == S_VOP && dec->sprite_enable == SPRITE_STATIC) {
			if (e->intra_blocks) BitstreamSkip(bs, 8);	/* */
			if (e->not_coded_blocks) BitstreamSkip(bs, 8);	/* */
			if (e->dct_coefs)	BitstreamSkip(bs, 8);	/* */
			if (e->dct_lines)	BitstreamSkip(bs, 8);	/* */
			if (e->vlc_symbols)	BitstreamSkip(bs, 8);	/* */
			if (e->vlc_bits)	BitstreamSkip(bs, 8);	/* */
			if (e->inter_blocks) BitstreamSkip(bs, 8);	/* */
			if (e->inter4v_blocks)	BitstreamSkip(bs, 8);	/* */
			if (e->apm)			BitstreamSkip(bs, 8);	/* */
			if (e->npm)			BitstreamSkip(bs, 8);	/* */
			if (e->forw_back_mc_q)	BitstreamSkip(bs, 8);	/* */
			if (e->halfpel2)	BitstreamSkip(bs, 8);	/* */
			if (e->halfpel4)	BitstreamSkip(bs, 8);	/* */
			if (e->interpolate_mc_q) BitstreamSkip(bs, 8);	/* */
		}
	}
}





/*
decode headers
returns coding_type, or -1 if error
*/

#define VIDOBJ_START_CODE_MASK		0x0000001f
#define VIDOBJLAY_START_CODE_MASK	0x0000000f

int
BitstreamReadHeaders(Bitstream * bs,
					 DECODER * dec,
					 uint32_t * rounding,
					 uint32_t * quant,
					 uint32_t * fcode_forward,
					 uint32_t * fcode_backward,
					 uint32_t * intra_dc_threshold,
					 WARPPOINTS *gmc_warp)
{
	uint32_t vol_ver_id;
	uint32_t coding_type;
	uint32_t start_code;
	uint32_t time_incr = 0;
	int32_t time_increment = 0;
	int resize = 0;

	while ((BitstreamPos(bs) >> 3) + 4 <= bs->length) {

		BitstreamByteAlign(bs);
		start_code = BitstreamShowBits(bs, 32);

		if (start_code == VISOBJSEQ_START_CODE) {

			int profile;

			DPRINTF(XVID_DEBUG_STARTCODE, "<visual_object_sequence>\n");

			BitstreamSkip(bs, 32);	/* visual_object_sequence_start_code */
			profile = BitstreamGetBits(bs, 8);	/* profile_and_level_indication */

			DPRINTF(XVID_DEBUG_HEADER, "profile_and_level_indication %i\n", profile);

		} else if (start_code == VISOBJSEQ_STOP_CODE) {

			BitstreamSkip(bs, 32);	/* visual_object_sequence_stop_code */

			DPRINTF(XVID_DEBUG_STARTCODE, "</visual_object_sequence>\n");

		} else if (start_code == VISOBJ_START_CODE) {

			DPRINTF(XVID_DEBUG_STARTCODE, "<visual_object>\n");

			BitstreamSkip(bs, 32);	/* visual_object_start_code */
			if (BitstreamGetBit(bs))	/* is_visual_object_identified */
			{
				dec->ver_id = BitstreamGetBits(bs, 4);	/* visual_object_ver_id */
				DPRINTF(XVID_DEBUG_HEADER,"visobj_ver_id %i\n", dec->ver_id);
				BitstreamSkip(bs, 3);	/* visual_object_priority */
			} else {
				dec->ver_id = 1;
			}

			if (BitstreamShowBits(bs, 4) != VISOBJ_TYPE_VIDEO)	/* visual_object_type */
			{
				DPRINTF(XVID_DEBUG_ERROR, "visual_object_type != video\n");
				return -1;
			}
			BitstreamSkip(bs, 4);

			/* video_signal_type */

			if (BitstreamGetBit(bs))	/* video_signal_type */
			{
				DPRINTF(XVID_DEBUG_HEADER,"+ video_signal_type\n");
				BitstreamSkip(bs, 3);	/* video_format */
				BitstreamSkip(bs, 1);	/* video_range */
				if (BitstreamGetBit(bs))	/* color_description */
				{
					DPRINTF(XVID_DEBUG_HEADER,"+ color_description");
					BitstreamSkip(bs, 8);	/* color_primaries */
					BitstreamSkip(bs, 8);	/* transfer_characteristics */
					BitstreamSkip(bs, 8);	/* matrix_coefficients */
				}
			}
		} else if ((start_code & ~VIDOBJ_START_CODE_MASK) == VIDOBJ_START_CODE) {

			DPRINTF(XVID_DEBUG_STARTCODE, "<video_object>\n");
			DPRINTF(XVID_DEBUG_HEADER, "vo id %i\n", start_code & VIDOBJ_START_CODE_MASK);

			BitstreamSkip(bs, 32);	/* video_object_start_code */

		} else if ((start_code & ~VIDOBJLAY_START_CODE_MASK) == VIDOBJLAY_START_CODE) {

			DPRINTF(XVID_DEBUG_STARTCODE, "<video_object_layer>\n");
			DPRINTF(XVID_DEBUG_HEADER, "vol id %i\n", start_code & VIDOBJLAY_START_CODE_MASK);

			BitstreamSkip(bs, 32);	/* video_object_layer_start_code */
			BitstreamSkip(bs, 1);	/* random_accessible_vol */

            BitstreamSkip(bs, 8);   /* video_object_type_indication */

			if (BitstreamGetBit(bs))	/* is_object_layer_identifier */
			{
				DPRINTF(XVID_DEBUG_HEADER, "+ is_object_layer_identifier\n");
				vol_ver_id = BitstreamGetBits(bs, 4);	/* video_object_layer_verid */
				DPRINTF(XVID_DEBUG_HEADER,"ver_id %i\n", vol_ver_id);
				BitstreamSkip(bs, 3);	/* video_object_layer_priority */
			} else {
				vol_ver_id = dec->ver_id;

⌨️ 快捷键说明

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