int decoder_decode(DECODER * dec, xvid_dec_frame_t * frame, xvid_dec_stats_t * stats) { uint32_t rounding; /*图像饱和 类型,在插值时四舍五入的饱和大小*/ uint32_t reduced_resolution; uint32_t quant = 2; /*默认的量化步长初始化*/ uint32_t fcode_forward; /*运动估计中搜索窗口的大小,前向*/ uint32_t fcode_backward; /*运动估计中搜索窗口的大小,后向*/ uint32_t intra_dc_threshold; /*Intra块的直流DC阈值*/ WARPPOINTS gmc_warp; int coding_type; /*当前编码帧类型*/ if (frame->length < 0) return XVID_ERR_END; /*检测输入码流长度的合法性*/ BitstreamInit(&g_bs, frame->bitstream, frame->length); /*初始化码流结构体*/ /*解析视频码流头结构、信息*/ repeat: coding_type = BitstreamReadHeaders(&g_bs, dec, &rounding, &reduced_resolution, &quant, &fcode_forward, &fcode_backward, &intra_dc_threshold, &gmc_warp); if (coding_type == -1) { /* 继续解析头信息,直到解析到图像数据 */ goto repeat; } if (coding_type == -2 || coding_type == -3) {/* 当前是VOL头或需要修改图像空间大小 */ if (coding_type == -3) decoder_resize(dec); if (stats) goto repeat; /* 继续解析头信息,直到解析到图像数据 */ } /*确保解码的第一帧是I帧,如果不是I帧则继续解析后续码流*/ if(dec->frames == 0 && coding_type != I_VOP) goto repeat; if (coding_type != B_VOP) { switch(coding_type) { case I_VOP : /*I帧解码*/ decoder_iframe(dec, &g_bs, reduced_resolution, quant, intra_dc_ threshold); break; case P_VOP : /*P帧解码*/ decoder_pframe(dec, &g_bs, rounding, reduced_resolution, quant, fcode_forward, intra_dc_threshold, NULL); break; case S_VOP : /*S帧解码*/ decoder_pframe(dec, &g_bs, rounding, reduced_resolution, quant, fcode_forward, intra_dc_threshold, &gmc_warp); break; } dec_image_swap(&dec->refn[0], &dec->refn[1]); /*交换两个参考帧的指针*/ dec_image_swap(&dec->cur, &dec->refn[0]); /*交换当前图像和参考帧的指针*/ dec->last_reduced_resolution = reduced_resolution; dec->last_coding_type = coding_type; /*保存当前帧类型*/ dec->frames++; /*解码帧计数器*/ } done : return (BitstreamPos(&g_bs) + 7) / 8; /*已解码的码流,单位B*/ }
|