📄 divx4.c
字号:
encore(void *handle, int opt, void *param1, void *param2){ int xerr; switch (opt) { case ENC_OPT_INIT: { EINST *ecur; ENC_PARAM *eparam = (ENC_PARAM *) param1; XVID_INIT_PARAM xinit; XVID_ENC_PARAM xparam; /* Init XviD which will detect host cpu features */ xinit.cpu_flags = 0; xvid_init(NULL, 0, &xinit, NULL); /* Settings are copied to the XviD encoder structure */ xparam.width = eparam->x_dim; xparam.height = eparam->y_dim; if ((eparam->framerate - (int) eparam->framerate) == 0) { xparam.fincr = 1; xparam.fbase = (int) eparam->framerate; } else { xparam.fincr = FRAMERATE_INCR; xparam.fbase = (int) (FRAMERATE_INCR * eparam->framerate); } xparam.rc_bitrate = eparam->bitrate; xparam.rc_reaction_delay_factor = 16; xparam.rc_averaging_period = 100; xparam.rc_buffer = 100; xparam.min_quantizer = eparam->min_quantizer; xparam.max_quantizer = eparam->max_quantizer; xparam.max_key_interval = eparam->max_key_interval; /* Create the encoder session */ xerr = encoder_create(&xparam); eparam->handle = xparam.handle; /* Create an encoder instance in the chainlist */ if ((ecur = einst_find(xparam.handle)) == NULL) { ecur = einst_add(xparam.handle); if (ecur == NULL) { encoder_destroy((Encoder *) xparam.handle); return ENC_MEMORY; } } ecur->quality = eparam->quality; if (ecur->quality < 0) ecur->quality = 0; if (ecur->quality > 6) ecur->quality = 6; break; } case ENC_OPT_RELEASE: { EINST *ecur; if ((ecur = einst_find(handle)) == NULL) { return ENC_FAIL; } einst_remove(handle); xerr = encoder_destroy((Encoder *) handle); break; } case ENC_OPT_ENCODE: case ENC_OPT_ENCODE_VBR: { EINST *ecur; ENC_FRAME *eframe = (ENC_FRAME *) param1; ENC_RESULT *eresult = (ENC_RESULT *) param2; XVID_ENC_FRAME xframe; XVID_ENC_STATS xstats; if ((ecur = einst_find(handle)) == NULL) { return ENC_FAIL; } /* Copy the divx4 info into the xvid structure */ xframe.bitstream = eframe->bitstream; xframe.length = eframe->length; xframe.motion = divx4_motion_presets[ecur->quality]; xframe.general = divx4_general_presets[ecur->quality]; xframe.image = eframe->image; xframe.colorspace = xvid_to_opendivx_enc_csp(eframe->colorspace); if (opt == ENC_OPT_ENCODE_VBR) { xframe.intra = eframe->intra; xframe.quant = eframe->quant; } else { xframe.intra = -1; xframe.quant = 0; } /* Encode the frame */ xerr = encoder_encode((Encoder *) handle, &xframe, (eresult ? &xstats : NULL)); /* Copy back the xvid structure to the divx4 one */ if (eresult) { eresult->is_key_frame = xframe.intra; eresult->quantizer = xstats.quant; eresult->total_bits = xframe.length * 8; eresult->motion_bits = xstats.hlength * 8; eresult->texture_bits = eresult->total_bits - eresult->motion_bits; } eframe->length = xframe.length; break; } default: return ENC_FAIL; } /* XviD Error code -> Divx4 error code */ switch (xerr) { case XVID_ERR_OK: return ENC_OK; case XVID_ERR_MEMORY: return ENC_MEMORY; case XVID_ERR_FORMAT: return ENC_BAD_FORMAT; default: return ENC_FAIL; }}/************************************************************************** * Local Functions *************************************************************************//*************************************** * DINST chainlist helper functions * ***************************************//* Find an element in the chainlist according to its key value */static DINST *dinst_find(unsigned long key){ DINST *dcur = dhead; while (dcur) { if (dcur->key == key) { return dcur; } dcur = dcur->next; } return NULL;}/* Add an element to the chainlist */static DINST *dinst_add(unsigned long key){ DINST *dnext = dhead; dhead = malloc(sizeof(DINST)); if (dhead == NULL) { dhead = dnext; return NULL; } dhead->key = key; dhead->next = dnext; return dhead;}/* Remove an elmement from the chainlist */static voiddinst_remove(unsigned long key){ DINST *dcur = dhead; if (dhead == NULL) { return; } if (dcur->key == key) { dhead = dcur->next; free(dcur); return; } while (dcur->next) { if (dcur->next->key == key) { DINST *tmp = dcur->next; dcur->next = tmp->next; free(tmp); return; } dcur = dcur->next; }}/*************************************** * EINST chainlist helper functions * ***************************************//* Find an element in the chainlist according to its handle */static EINST *einst_find(void *handle){ EINST *ecur = ehead; while (ecur) { if (ecur->handle == handle) { return ecur; } ecur = ecur->next; } return NULL;}/* Add an element to the chainlist */static EINST *einst_add(void *handle){ EINST *enext = ehead; ehead = malloc(sizeof(EINST)); if (ehead == NULL) { ehead = enext; return NULL; } ehead->handle = handle; ehead->next = enext; return ehead;}/* Remove an elmement from the chainlist */static voideinst_remove(void *handle){ EINST *ecur = ehead; if (ehead == NULL) { return; } if (ecur->handle == handle) { ehead = ecur->next; free(ecur); return; } while (ecur->next) { if (ecur->next->handle == handle) { EINST *tmp = ecur->next; ecur->next = tmp->next; free(tmp); return; } ecur = ecur->next; }}/*************************************** * Colorspace code converter * ***************************************/static intxvid_to_opendivx_dec_csp(int csp){ switch (csp) { case DEC_YV12: return XVID_CSP_YV12; case DEC_420: return XVID_CSP_I420; case DEC_YUY2: return XVID_CSP_YUY2; case DEC_UYVY: return XVID_CSP_UYVY; case DEC_RGB32: return XVID_CSP_VFLIP | XVID_CSP_RGB32; case DEC_RGB24: return XVID_CSP_VFLIP | XVID_CSP_RGB24; case DEC_RGB565: return XVID_CSP_VFLIP | XVID_CSP_RGB565; case DEC_RGB555: return XVID_CSP_VFLIP | XVID_CSP_RGB555; case DEC_RGB32_INV: return XVID_CSP_RGB32; case DEC_RGB24_INV: return XVID_CSP_RGB24; case DEC_RGB565_INV: return XVID_CSP_RGB565; case DEC_RGB555_INV: return XVID_CSP_RGB555; case DEC_USER: return XVID_CSP_USER; default: return -1; }}static intxvid_to_opendivx_enc_csp(int csp){ switch (csp) { case ENC_CSP_RGB24: return XVID_CSP_VFLIP | XVID_CSP_RGB24; case ENC_CSP_YV12: return XVID_CSP_YV12; case ENC_CSP_YUY2: return XVID_CSP_YUY2; case ENC_CSP_UYVY: return XVID_CSP_UYVY; case ENC_CSP_I420: return XVID_CSP_I420; default: return -1; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -