/*图像分辨率大小发生变化,释放已申请的内存,并重新申请*/ static int decoder_resize(DECODER * dec) { /*释放存在的图像空间*/ image_destroy(&dec->cur, dec->edged_width, dec->edged_height); image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height); image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height); image_destroy(&dec->tmp, dec->edged_width, dec->edged_height); /*所有图像指针清零*/ image_null(&dec->cur); //当前解码帧的空间y/u/v指针清空 image_null(&dec->refn[0]); //参考帧0的空间y/u/v指针清空 image_null(&dec->refn[1]); //参考帧1的空间y/u/v指针清空 image_null(&dec->tmp); //tmp临时空间的y/u/v指针清空 xvid_free(dec->last_mbs); //释放宏块结构空间 xvid_free(dec->mbs); //释放宏块结构空间 dec->last_mbs = NULL; //指针清空 dec->mbs = NULL; //指针清空 /*重新申请内存*/ dec->mb_width = (dec->width + 15) / 16; /*图像帧宏块宽度,16的倍数*/ dec->mb_height = (dec->height + 15) / 16; /*图像帧宏块高度,16的倍数*/ dec->edged_width = 16 * dec->mb_width + 2 * EDGE_SIZE;/*图像边扩展了的图像宽度*/ dec->edged_height = 16 * dec->mb_height + 2 * EDGE_SIZE;/*图像边扩展了的图像高度*/ /*申请图像空间*/ if ( image_create(&dec->cur, dec->edged_width, dec->edged_height) || image_create(&dec->refn[0], dec->edged_width, dec->edged_height) || image_create(&dec->refn[1], dec->edged_width, dec->edged_height) || image_create(&dec->tmp, dec->edged_width, dec->edged_height)) goto memory_error; //申请失败 /*申请所有宏块的解码信息*/ dec->mbs = xvid_malloc(sizeof(MACROBLOCK) * dec-> mb_width * dec->mb_height, CACHE_LINE); if (dec->mbs == NULL) goto memory_error; //申请失败 memset(dec->mbs, 0, sizeof(MACROBLOCK) * dec-> mb_width * dec->mb_height); /*清空*/ /* 解码B帧时,用到的宏块解码信息 */ dec->last_mbs=xvid_malloc(sizeof(MACROBLOCK)*dec-> mb_width * dec->mb_height, CACHE_LINE); if (dec->last_mbs == NULL) goto memory_error; //申请失败 memset(dec->last_mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height); return 0; memory_error: /*释放图像空间、结构体,指针置空 */ xvid_free(dec->mbs); image_destroy(&dec->cur, dec->edged_width, dec->edged_height); //释放当前解码帧空间 image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height); //释放参考帧0空间 image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height); //释放参考帧1空间 image_destroy(&dec->tmp, dec->edged_width, dec->edged_height); //释放临时帧空间 /*释放解码器句柄*/ xvid_free(dec); return XVID_ERR_MEMORY; } /*创建编码器实例*/ int decoder_create(xvid_dec_create_t * create) { DECODER *dec; dec = xvid_malloc(sizeof(DECODER), CACHE_LINE); /*创建并初始化解码器句柄,使句柄完 全可控*/ if (dec == NULL) return XVID_ERR_MEMORY; memset(dec, 0, sizeof(DECODER)); create->handle = dec; /*获取解码输入的参数*/ dec->width = create->width; dec->height = create->height; image_null(&dec->cur); /*图像空间指针清零*/ image_null(&dec->refn[0]); image_null(&dec->refn[1]); image_null(&dec->tmp); dec->mbs = NULL; dec->last_mbs = NULL; init_postproc(&dec->postproc); /*支持图像后处理,如滤波、去块效应*/ dec->frames = 0; /*支持B帧解码,用来保存参考帧的时间*/ dec->time = dec->time_base = dec->last_time_base = 0; dec->low_delay = 0; dec->packed_mode = 0; dec->time_inc_resolution = 1; /* 直到VOL头更改为其他数据 */ /*创建解码器时,已知图像宽度和高度*/ dec->fixed_dimensions = (dec->width > 0 && dec->height > 0); if (dec->fixed_dimensions) return decoder_resize(dec); else return 0; } |