📄 vlc.cpp
字号:
#ifdef _MSC_VER
extern "C"
{
#endif
#include "global.h"
#ifdef _MSC_VER
}
#endif
//#define DUMP_RLE
#include <fstream.h>
// do not change this (it must occur _after_ your header)
#include "idb_streamc.hpp"
#include "vector.hpp"
int run(unsigned int val)
{
return val >> 16;
}
int sext(unsigned int val)
{
val &= 0xffff;
if (val & 0x8000)
return 0xffff0000 | val;
else
return val;
}
int get_cbp(int mb_idx, vector<unsigned int>& rl);
void slicehdr(int row, int q_scale);
void encode_stream(StreamSchedulerInterface& scd,
im_stream<im_half2> run_levels)
{
static int frame = 0;
#ifdef DUMP_RLE
String fname("frame");
fname = fname + String(frame, 10) + "mpeg_sc/rl.txt";
ofstream dbg(fname.char_ptr());
frame++;
#endif
vector<unsigned int> rl;
streamSaveVect(rl, run_levels);
int idx = 0;
int num_macroblocks = mb_height*mb_width;
int rl_min_length = num_macroblocks*2;
if (rl.size() < rl_min_length)
{
cerr << "Unexpected run/level stream length. Minimum: ";
cerr << rl_min_length << " Actual: " << rl.size() << endl;
return;
}
for (int row = 0; row < mb_height; row++)
{
int mb_increment = 1;
int mb_type = MB_INTRA;
// motion vector predictions
int pdx = 0;
int pdy = 0;
int sliceblocks = mb_width;
int pl, pcr, pcb; // dc predictors
for (int col = 0; col < mb_width; col++)
{
// encode macroblock
int q_scale = rl[idx++];
// luminance prediction
pl = (col == 0) ? (0x400 >> (3 - dc_prec)) / q_scale : pl;
// chromanance prediction
pcr = (col == 0) ? pl : pcr;
pcb = (col == 0) ? pl : pcb;
if ((col % sliceblocks) == 0)
{
slicehdr(row, q_scale);
pdx = 0;
pdy = 0;
}
// put macroblock increment
putaddrinc(mb_increment);
// macroblock type - hardwired for now, should get from im_stream?
if (pict_type == I_TYPE)
mb_type = MB_INTRA;
else if (pict_type == P_TYPE)
mb_type = MB_FORWARD | MB_PATTERN;
else
cerr << "INVALID 'pict_type'!!" << endl;
int cbp = rl[idx++];
if (!(mb_type & MB_PATTERN))
cbp = 0x3f;
if (cbp == 0)
mb_type &= ~MB_PATTERN;
// put macroblock type
putmbtype(pict_type, mb_type);
if (mb_type & MB_FORWARD)
{
int dx, dy;
// Get motion vectors
dx = sext(rl[idx]);
dy = sext(rl[idx] >> 16);
// put motion vectors
putmv(dx-pdx, forw_hor_f_code);
putmv(dy-pdy, forw_vert_f_code);
pdx = dx;
pdy = dy;
idx++;
}
if (mb_type & MB_PATTERN)
putcbp(cbp);
if (cbp != 0x3f)
cerr << "cbp: " << hex << cbp << dec << endl;
if ((mb_type & MB_INTRA)
|| (pict_type==P_TYPE && !(mb_type & MB_FORWARD)))
{
pdx = 0;
pdy = 0;
}
for (int i = 0; i < 6; i++)
{
bool valid_block = (cbp & (1<<(5-i))) != 0;
if (!valid_block)
{
while ((idx < rl.size()) && ((rl[idx] == -1) || (rl[idx] == -2)))
idx++;
continue;
}
#ifdef DUMP_RLE
if (pict_type == P_TYPE)
{
dbg << "**************************************************" << endl;
dbg << "row: " << row << " col: " << col << " block: " << i << endl;
dbg << "**************************************************" << endl;
}
#endif
int values = 0;
if (mb_type & MB_INTRA)
{
// DC coefficient
if (i < 4)
{
int val = sext(rl[idx]) - pl;
pl = sext(rl[idx]);
putDClum(val);
}
else
{
int val;
if (i == 4)
{
val = sext(rl[idx]) - pcb;
pcb = sext(rl[idx]);
}
else
{
val = sext(rl[idx]) - pcr;
pcr = sext(rl[idx]);
}
putDCchrom(val);
}
#ifdef DUMP_RLE
dbg << "DC level: " << sext(rl[idx]) << endl;
#endif
values++;
idx++;
// AC coefficients
while ((rl[idx] != -1) && (values <= 64))
{
putAC(run(rl[idx]), sext(rl[idx]), intravlc);
values += run(rl[idx]);
#ifdef DUMP_RLE
dbg << " run: " << run(rl[idx]);
dbg << " absolute: " << values;
dbg << " level: " << sext(rl[idx]) << endl;
#endif
values++;
idx++;
}
if (rl[idx] != -1)
cerr << "Block too long! run >= " << values << endl;
idx++;
// End of Block
if (intravlc)
putbits(6,4); /* 0110 (Table B-15) */
else
putbits(2,2); /* 10 (Table B-14) */
}
else
{
putACfirst(run(rl[idx]), sext(rl[idx]));
values += run(rl[idx]);
#ifdef DUMP_RLE
dbg << " run: " << run(rl[idx]);
dbg << " absolute: " << values;
dbg << " level: " << sext(rl[idx]) << endl;
#endif
values++;
idx++;
while ((rl[idx] != -1) && (values <= 64))
{
putAC(run(rl[idx]), sext(rl[idx]), 0);
values += run(rl[idx]);
#ifdef DUMP_RLE
dbg << " run: " << run(rl[idx]);
dbg << " absolute: " << values;
dbg << " level: " << sext(rl[idx]) << endl;
#endif
values++;
idx++;
}
if (rl[idx] != -1)
cerr << "Block too long! run >= " << values << endl;
idx++;
// End of Block
putbits(2,2);
}
if (values == 0)
cerr << "Outputting zero length block!" << endl;
while ((idx < rl.size()) && (rl[idx] == -2))
idx++;
}
}
}
cout << "Length of rle vector: " << idx << endl;
#ifdef DUMP_RLE
dbg.close();
#endif
}
int get_cbp(int mb_idx, vector<unsigned int>& rl)
{
int cbp = 0;
for (int blk = 0; blk < 6; blk++)
{
int valid_blk = 0;
for (int y = 0; y < 8; y++, mb_idx += 8)
{
for (int x = 0; x < 8; x++)
{
if (rl[mb_idx+x])
valid_blk = 1;
else
break;
}
}
cbp = (cbp << 1) | valid_blk;
}
return cbp;
}
void slicehdr(int row, int q_scale)
{
alignbits();
if (mpeg1 || vertical_size<=2800)
putbits(SLICE_MIN_START + row, 32);
else
{
putbits(SLICE_MIN_START + ( row & 127), 32);
putbits(row >> 7, 3);
}
// put quantization
putbits(q_scale, 5);
// putbits(0, 1); // intra_slice_flag ?? Should this be there ??
putbits(0, 1); // extra_bit_slice
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -