mp4_block.c
资源名称:VC++视频传输.rar [点击查看]
上传用户:hxb_1234
上传日期:2010-03-30
资源大小:8328k
文件大小:8k
源码类别:
VC书籍
开发平台:
Visual C++
- #include <math.h>
- #include <stdlib.h>
- #include <assert.h>
- #include "mp4_vars.h"
- #include "getbits.h"
- #include "clearblock.h"
- #include "mp4_iquant.h"
- #include "mp4_predict.h"
- #include "mp4_vld.h"
- #include "debug.h"
- #include "mp4_block.h"
- /**
- *
- **/
- static int getDCsizeLum();
- static int getDCsizeChr();
- static int getDCdiff();
- static void setDCscaler(int block_num);
- static int getACdir();
- /***/
- int block(int block_num, int coded)
- {
- int i;
- int dct_dc_size, dct_dc_diff;
- int intraFlag = ((mp4_state->hdr.derived_mb_type == INTRA) ||
- (mp4_state->hdr.derived_mb_type == INTRA_Q)) ? 1 : 0;
- event_t event;
- clearblock(ld->block);
- if (intraFlag)
- {
- setDCscaler(block_num);
- if (block_num < 4) {
- dct_dc_size = getDCsizeLum();
- if (dct_dc_size != 0)
- dct_dc_diff = getDCdiff(dct_dc_size);
- else
- dct_dc_diff = 0;
- if (dct_dc_size > 8)
- getbits1();
- }
- else {
- dct_dc_size = getDCsizeChr();
- if (dct_dc_size != 0)
- dct_dc_diff = getDCdiff(dct_dc_size);
- else
- dct_dc_diff = 0;
- if (dct_dc_size > 8)
- getbits1();
- }
- ld->block[0] = (short) dct_dc_diff;
- }
- if (intraFlag)
- {
- dc_recon(block_num, &ld->block[0]);
- }
- if (coded)
- {
- unsigned int * zigzag;
- if ((intraFlag) && (mp4_state->hdr.ac_pred_flag == 1)) {
- if (mp4_state->coeff_pred.predict_dir == TOP)
- zigzag = mp4_tables->alternate_horizontal_scan;
- else
- zigzag = mp4_tables->alternate_vertical_scan;
- }
- else {
- zigzag = mp4_tables->zig_zag_scan;
- }
- i = intraFlag ? 1 : 0;
- do
- {
- event = vld_event(intraFlag);
- i+= event.run;
- ld->block[zigzag[i]] = (short) event.level;
- i++;
- } while (! event.last);
- }
- if (intraFlag)
- {
- ac_recon(block_num, &ld->block[0]);
- }
- #ifdef _DEBUG_B_ACDC
- if (intraFlag)
- {
- int i;
- _Print("After AcDcRecon:n");
- _Print(" x ");
- for (i = 1; i < 64; i++) {
- if ((i != 0) && ((i % 8) == 0))
- _Print("n");
- _Print("%4d ", ld->block[i]);
- }
- _Print("n");
- }
- #endif // _DEBUG_ACDC
- if (mp4_state->hdr.quant_type == 0)
- {
- iquant(ld->block, intraFlag);
- }
- else
- {
- _Error("Error: MPEG-2 inverse quantization NOT implementedn");
- exit(110);
- }
- #ifdef _DEBUG_B_QUANT
- {
- int i;
- _Print("After IQuant:n");
- _Print(" x ");
- for (i = 1; i < 64; i++) {
- if ((i != 0) && ((i % 8) == 0))
- _Print("n");
- _Print("%4d ", ld->block[i]);
- }
- _Print("n");
- }
- #endif
- idct(ld->block);
- return 1;
- }
- /***/
- int blockIntra(int block_num, int coded)
- {
- int i;
- int dct_dc_size, dct_dc_diff;
- event_t event;
- clearblock(ld->block);
- setDCscaler(block_num);
- if (block_num < 4) {
- dct_dc_size = getDCsizeLum();
- if (dct_dc_size != 0)
- dct_dc_diff = getDCdiff(dct_dc_size);
- else
- dct_dc_diff = 0;
- if (dct_dc_size > 8)
- getbits1();
- }
- else {
- dct_dc_size = getDCsizeChr();
- if (dct_dc_size != 0)
- dct_dc_diff = getDCdiff(dct_dc_size);
- else
- dct_dc_diff = 0;
- if (dct_dc_size > 8)
- getbits1();
- }
- ld->block[0] = (short) dct_dc_diff;
- dc_recon(block_num, &ld->block[0]);
- if (coded)
- {
- unsigned int * zigzag;
- if (mp4_state->hdr.ac_pred_flag == 1) {
- if (mp4_state->coeff_pred.predict_dir == TOP)
- zigzag = mp4_tables->alternate_horizontal_scan;
- else
- zigzag = mp4_tables->alternate_vertical_scan;
- }
- else {
- zigzag = mp4_tables->zig_zag_scan;
- }
- i = 1;
- do
- {
- event = vld_intra_dct();
- i+= event.run;
- ld->block[zigzag[i]] = (short) event.level;
- i++;
- } while (! event.last);
- }
- mp4_state->hdr.intrablock_rescaled = ac_rescaling(block_num, &ld->block[0]);
- if (! mp4_state->hdr.intrablock_rescaled)
- {
- ac_recon(block_num, &ld->block[0]);
- }
- ac_store(block_num, &ld->block[0]);
- if (mp4_state->hdr.quant_type == 0)
- {
- iquant(ld->block, 1);
- }
- else
- {
- iquant_typefirst(ld->block);
- }
- idct(ld->block);
- return 1;
- }
- /***/
- int blockInter(int block_num, int coded)
- {
- event_t event;
- unsigned int * zigzag = mp4_tables->zig_zag_scan; // zigzag scan dir
- int i;
- clearblock(ld->block);
- if (mp4_state->hdr.quant_type == 0)
- {
- int q_scale = mp4_state->hdr.quantizer;
- int q_2scale = q_scale << 1;
- int q_add = (q_scale & 1) ? q_scale : (q_scale - 1);
- i = 0;
- do
- {
- event = vld_inter_dct();
- i+= event.run;
- if (event.level > 0) {
- ld->block[zigzag[i]] = (q_2scale * event.level) + q_add;
- }
- else {
- ld->block[zigzag[i]] = (q_2scale * event.level) - q_add;
- }
- i++;
- } while (! event.last);
- }
- else
- {
- int k, m = 0;
- i = 0;
- do
- {
- event = vld_inter_dct();
- i+= event.run;
- k = (event.level > 0) ? 1 : -1;
- assert(ld->block[zigzag[i]] < 2047);
- assert(ld->block[zigzag[i]] > -2048);
- ld->block[zigzag[i]] = ((2 * event.level + k) * mp4_state->hdr.quantizer *
- mp4_tables->nonintra_quant_matrix[zigzag[i]]) >> 4;
- assert(ld->block[zigzag[i]] < 2047);
- assert(ld->block[zigzag[i]] > -2048);
- m ^= ld->block[zigzag[i]];
- i++;
- } while (! event.last);
- if (!(m%2)) ld->block[63] ^= 1;
- }
- idct(ld->block);
- return 1;
- }
- static int getDCsizeLum()
- {
- int code;
- if (showbits(11) == 1) {
- flushbits(11);
- return 12;
- }
- if (showbits(10) == 1) {
- flushbits(10);
- return 11;
- }
- if (showbits(9) == 1) {
- flushbits(9);
- return 10;
- }
- if (showbits(8) == 1) {
- flushbits(8);
- return 9;
- }
- if (showbits(7) == 1) {
- flushbits(7);
- return 8;
- }
- if (showbits(6) == 1) {
- flushbits(6);
- return 7;
- }
- if (showbits(5) == 1) {
- flushbits(5);
- return 6;
- }
- if (showbits(4) == 1) {
- flushbits(4);
- return 5;
- }
- code = showbits(3);
- if (code == 1) {
- flushbits(3);
- return 4;
- } else if (code == 2) {
- flushbits(3);
- return 3;
- } else if (code == 3) {
- flushbits(3);
- return 0;
- }
- code = showbits(2);
- if (code == 2) {
- flushbits(2);
- return 2;
- } else if (code == 3) {
- flushbits(2);
- return 1;
- }
- return 0;
- }
- static int getDCsizeChr()
- {
- if (showbits(12) == 1) {
- flushbits(12);
- return 12;
- }
- if (showbits(11) == 1) {
- flushbits(11);
- return 11;
- }
- if (showbits(10) == 1) {
- flushbits(10);
- return 10;
- }
- if (showbits(9) == 1) {
- flushbits(9);
- return 9;
- }
- if (showbits(8) == 1) {
- flushbits(8);
- return 8;
- }
- if (showbits(7) == 1) {
- flushbits(7);
- return 7;
- }
- if (showbits(6) == 1) {
- flushbits(6);
- return 6;
- }
- if (showbits(5) == 1) {
- flushbits(5);
- return 5;
- }
- if (showbits(4) == 1) {
- flushbits(4);
- return 4;
- }
- if (showbits(3) == 1) {
- flushbits(3);
- return 3;
- }
- return (3 - getbits(2));
- }
- static int getDCdiff(int dct_dc_size)
- {
- int code = getbits(dct_dc_size);
- int msb = code >> (dct_dc_size - 1);
- if (msb == 0) {
- return (-1 * (code^((int) pow(2.0,(double) dct_dc_size) - 1)));
- }
- else {
- return code;
- }
- }
- static void setDCscaler(int block_num)
- {
- int type = (block_num < 4) ? 0 : 1;
- int quant = mp4_state->hdr.quantizer;
- if (type == 0) {
- if (quant > 0 && quant < 5)
- mp4_state->hdr.dc_scaler = 8;
- else if (quant > 4 && quant < 9)
- mp4_state->hdr.dc_scaler = (2 * quant);
- else if (quant > 8 && quant < 25)
- mp4_state->hdr.dc_scaler = (quant + 8);
- else
- mp4_state->hdr.dc_scaler = (2 * quant - 16);
- }
- else {
- if (quant > 0 && quant < 5)
- mp4_state->hdr.dc_scaler = 8;
- else if (quant > 4 && quant < 25)
- mp4_state->hdr.dc_scaler = ((quant + 13) / 2);
- else
- mp4_state->hdr.dc_scaler = (quant - 6);
- }
- }
- /***/