int enc_create(xvid_enc_create_t * create) { Encoder *pEnc; /* 创建编码器指针,注意内存对齐*/ pEnc = (Encoder *) xvid_malloc(sizeof(Encoder), CACHE_LINE); if (pEnc == NULL) return XVID_ERR_MEMORY; memset(pEnc, 0, sizeof(Encoder)); /*初始化编码器句柄,所有指针清空*/ pEnc->mbParam.profile = create->profile; pEnc->mbParam.global_flags = create->global; /*编码器全局参数标志 */ pEnc->mbParam.width = create->width; /*视频图像的宽、高 */ pEnc->mbParam.height = create->height; pEnc->mbParam.mb_width = (pEnc->mbParam. width + 15) / 16; /*图像的宏块宽度*/ pEnc->mbParam.mb_height = (pEnc->mbParam. height + 15) / 16;/*图像的宏块高度*/ /*扩展后的视频图像大小 */ pEnc->mbParam.edged_width = 16 * pEnc-> mbParam.mb_width + 2 * EDGE_SIZE; pEnc->mbParam.edged_height = 16 * pEnc-> mbParam.mb_height + 2 * EDGE_SIZE; pEnc->mbParam.fincr = MAX(create->fincr, 0); /*帧率递增模式*/ pEnc->mbParam.fbase = create->fincr <= 0 ? 25 : create->fbase; /*帧率大小*/ pEnc->mbParam.frame_drop_ratio = MAX (create->frame_drop_ratio, 0);/*丢帧率*/ /*最大关键帧间隔,即I帧间的最大间隔,如果没有设置则默认250*/ pEnc->mbParam.iMaxKeyInterval = create->max_ key_interval <= 0 ? (10 * (int)pEnc->mbParam.fbase) / (int)pEnc->mbParam.fincr : create->max_key_interval; /*分配当前编码帧和参考帧空间 */ pEnc->current = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE); pEnc->reference = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE); if (pEnc->current == NULL || pEnc->reference == NULL) goto xvid_err_memory1; /* 为当前帧和参考帧的所有宏块结构分配空间 */ pEnc->current->mbs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE); pEnc->reference->mbs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE); if (pEnc->current->mbs == NULL || pEnc->reference->mbs == NULL) goto xvid_err_memory2; /*图像指针清空*/ image_null(&pEnc->current->image); image_null(&pEnc->reference->image); image_null(&pEnc->vInterH); image_null(&pEnc->vInterV); image_null(&pEnc->vInterHV); /* 创建当前视频帧图像空间 */ if (image_create(&pEnc->current->image, pEnc->mbParam. edged_width,pEnc->mbParam. edged_height) < 0) goto xvid_err_memory3; /* 创建参考视频帧图像空间 */ if(image_create(&pEnc->reference->image,pEnc->mbParam. edged_width,pEnc-> mbParam.edged_height)< 0) goto xvid_err_memory3; /* 创建vInterH参考帧图像空间 */ if (image_create(&pEnc->vInterH, pEnc->mbParam. edged_width, pEnc->mbParam. edged_height) < 0) goto xvid_err_memory3; /* 创建vInterV参考帧图像空间 */ if (image_create(&pEnc->vInterV, pEnc->mbParam. edged_width, pEnc->mbParam. edged_height) < 0) goto xvid_err_memory3; /* 创建vInterHV参考帧图像空间 */ if (image_create(&pEnc->vInterHV, pEnc->mbParam. edged_width, pEnc->mbParam. edged_height) < 0) goto xvid_err_memory3; /* 初始化B帧编码序列参数*/ pEnc->queue_head = 0; pEnc->queue_tail = 0; pEnc->queue_size = 0; pEnc->queue = xvid_malloc((1) * sizeof(QUEUEINFO),CACHE_LINE); /* 图像编码序列 */ if(image_create(&pEnc->queue[0].image,pEnc->mbParam. edged_width,pEnc-> mbParam.edged_height) < 0) goto xvid_err_memory5; /*时间戳清零*/ pEnc->mbParam.m_stamp = 0; pEnc->current->stamp = 0; pEnc->reference->stamp = 0; pEnc->iFrameNum = 0; /*编码图像帧数计数器清零*/ create->handle = (void *) pEnc; /*返回编码器的句柄 */ return 0; /* ok */ /*如果出错的话,释放以前分配的内存*/ xvid_err_memory5: image_destroy(&pEnc->queue[0].image,pEnc->mbParam. edged_width,pEnc->mbParam.edged_height); xvid_free(pEnc->queue); /* 释放图像空间*/ image_destroy(&pEnc->current->image, pEnc->mbParam. edged_width,pEnc->mbParam. edged_height); image_destroy(&pEnc->reference->image, pEnc->mbParam. edged_width,pEnc->mbParam. edged_height); image_destroy(&pEnc->vInterH, pEnc->mbParam. edged_width,pEnc->mbParam.edged_ height); image_destroy(&pEnc->vInterV, pEnc->mbParam. edged_width,pEnc->mbParam.edged_ height); image_destroy(&pEnc->vInterHV, pEnc->mbParam. edged_width,pEnc->mbParam.edged_ height); xvid_err_memory2: /* 释放当前帧和参考帧的mbs宏块内存*/ xvid_free(pEnc->current->mbs); xvid_free(pEnc->reference->mbs); xvid_err_memory1: /* 释放当前帧和参考帧的内存*/ xvid_free(pEnc->current); xvid_free(pEnc->reference); /* 释放编码器*/ xvid_free(pEnc); xvid_err_memory3: create->handle = NULL; return XVID_ERR_MEMORY; } |