📄 vc1.c
字号:
srcU = s->last_picture.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
srcV = s->last_picture.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
|| (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
|| (unsigned)uvsrc_y > (s->v_edge_pos >> 1) - 9){
ff_emulated_edge_mc(s->edge_emu_buffer , srcU, s->uvlinesize, 8+1, 8+1,
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
ff_emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize, 8+1, 8+1,
uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
srcU = s->edge_emu_buffer;
srcV = s->edge_emu_buffer + 16;
/* if we deal with range reduction we need to scale source blocks */
if(v->rangeredfrm) {
int i, j;
uint8_t *src, *src2;
src = srcU; src2 = srcV;
for(j = 0; j < 9; j++) {
for(i = 0; i < 9; i++) {
src[i] = ((src[i] - 128) >> 1) + 128;
src2[i] = ((src2[i] - 128) >> 1) + 128;
}
src += s->uvlinesize;
src2 += s->uvlinesize;
}
}
/* if we deal with intensity compensation we need to scale source blocks */
if(v->mv_mode == MV_PMODE_INTENSITY_COMP) {
int i, j;
uint8_t *src, *src2;
src = srcU; src2 = srcV;
for(j = 0; j < 9; j++) {
for(i = 0; i < 9; i++) {
src[i] = v->lutuv[src[i]];
src2[i] = v->lutuv[src2[i]];
}
src += s->uvlinesize;
src2 += s->uvlinesize;
}
}
}
/* Chroma MC always uses qpel bilinear */
uvdxy = ((uvmy & 3) << 2) | (uvmx & 3);
uvmx = (uvmx&3)<<1;
uvmy = (uvmy&3)<<1;
if(!v->rnd){
dsp->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
dsp->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
}else{
dsp->put_no_rnd_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
dsp->put_no_rnd_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
}
}
static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb);
/**
* Decode Simple/Main Profiles sequence header
* @see Figure 7-8, p16-17
* @param avctx Codec context
* @param gb GetBit context initialized from Codec context extra_data
* @return Status
*/
static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb)
{
VC1Context *v = avctx->priv_data;
av_log(avctx, AV_LOG_DEBUG, "Header: %0X\n", show_bits(gb, 32));
v->profile = get_bits(gb, 2);
if (v->profile == PROFILE_COMPLEX)
{
av_log(avctx, AV_LOG_ERROR, "WMV3 Complex Profile is not fully supported\n");
}
if (v->profile == PROFILE_ADVANCED)
{
return decode_sequence_header_adv(v, gb);
}
else
{
v->res_sm = get_bits(gb, 2); //reserved
if (v->res_sm)
{
av_log(avctx, AV_LOG_ERROR,
"Reserved RES_SM=%i is forbidden\n", v->res_sm);
return -1;
}
}
// (fps-2)/4 (->30)
v->frmrtq_postproc = get_bits(gb, 3); //common
// (bitrate-32kbps)/64kbps
v->bitrtq_postproc = get_bits(gb, 5); //common
v->s.loop_filter = get_bits1(gb); //common
if(v->s.loop_filter == 1 && v->profile == PROFILE_SIMPLE)
{
av_log(avctx, AV_LOG_ERROR,
"LOOPFILTER shell not be enabled in simple profile\n");
}
v->res_x8 = get_bits1(gb); //reserved
if (v->res_x8)
{
av_log(avctx, AV_LOG_ERROR,
"1 for reserved RES_X8 is forbidden\n");
//return -1;
}
v->multires = get_bits1(gb);
v->res_fasttx = get_bits1(gb);
if (!v->res_fasttx)
{
av_log(avctx, AV_LOG_ERROR,
"0 for reserved RES_FASTTX is forbidden\n");
//return -1;
}
v->fastuvmc = get_bits1(gb); //common
if (!v->profile && !v->fastuvmc)
{
av_log(avctx, AV_LOG_ERROR,
"FASTUVMC unavailable in Simple Profile\n");
return -1;
}
v->extended_mv = get_bits1(gb); //common
if (!v->profile && v->extended_mv)
{
av_log(avctx, AV_LOG_ERROR,
"Extended MVs unavailable in Simple Profile\n");
return -1;
}
v->dquant = get_bits(gb, 2); //common
v->vstransform = get_bits1(gb); //common
v->res_transtab = get_bits1(gb);
if (v->res_transtab)
{
av_log(avctx, AV_LOG_ERROR,
"1 for reserved RES_TRANSTAB is forbidden\n");
return -1;
}
v->overlap = get_bits1(gb); //common
v->s.resync_marker = get_bits1(gb);
v->rangered = get_bits1(gb);
if (v->rangered && v->profile == PROFILE_SIMPLE)
{
av_log(avctx, AV_LOG_INFO,
"RANGERED should be set to 0 in simple profile\n");
}
v->s.max_b_frames = avctx->max_b_frames = get_bits(gb, 3); //common
v->quantizer_mode = get_bits(gb, 2); //common
v->finterpflag = get_bits1(gb); //common
v->res_rtm_flag = get_bits1(gb); //reserved
if (!v->res_rtm_flag)
{
// av_log(avctx, AV_LOG_ERROR,
// "0 for reserved RES_RTM_FLAG is forbidden\n");
av_log(avctx, AV_LOG_ERROR,
"Old WMV3 version detected, only I-frames will be decoded\n");
//return -1;
}
//TODO: figure out what they mean (always 0x402F)
if(!v->res_fasttx) skip_bits(gb, 16);
av_log(avctx, AV_LOG_DEBUG,
"Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
"LoopFilter=%i, MultiRes=%i, FastUVMC=%i, Extended MV=%i\n"
"Rangered=%i, VSTransform=%i, Overlap=%i, SyncMarker=%i\n"
"DQuant=%i, Quantizer mode=%i, Max B frames=%i\n",
v->profile, v->frmrtq_postproc, v->bitrtq_postproc,
v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv,
v->rangered, v->vstransform, v->overlap, v->s.resync_marker,
v->dquant, v->quantizer_mode, avctx->max_b_frames
);
return 0;
}
static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
{
v->res_rtm_flag = 1;
v->level = get_bits(gb, 3);
if(v->level >= 5)
{
av_log(v->s.avctx, AV_LOG_ERROR, "Reserved LEVEL %i\n",v->level);
}
v->chromaformat = get_bits(gb, 2);
if (v->chromaformat != 1)
{
av_log(v->s.avctx, AV_LOG_ERROR,
"Only 4:2:0 chroma format supported\n");
return -1;
}
// (fps-2)/4 (->30)
v->frmrtq_postproc = get_bits(gb, 3); //common
// (bitrate-32kbps)/64kbps
v->bitrtq_postproc = get_bits(gb, 5); //common
v->postprocflag = get_bits1(gb); //common
v->s.avctx->coded_width = (get_bits(gb, 12) + 1) << 1;
v->s.avctx->coded_height = (get_bits(gb, 12) + 1) << 1;
v->s.avctx->width = v->s.avctx->coded_width;
v->s.avctx->height = v->s.avctx->coded_height;
v->broadcast = get_bits1(gb);
v->interlace = get_bits1(gb);
v->tfcntrflag = get_bits1(gb);
v->finterpflag = get_bits1(gb);
skip_bits1(gb); // reserved
v->s.h_edge_pos = v->s.avctx->coded_width;
v->s.v_edge_pos = v->s.avctx->coded_height;
av_log(v->s.avctx, AV_LOG_DEBUG,
"Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
"LoopFilter=%i, ChromaFormat=%i, Pulldown=%i, Interlace: %i\n"
"TFCTRflag=%i, FINTERPflag=%i\n",
v->level, v->frmrtq_postproc, v->bitrtq_postproc,
v->s.loop_filter, v->chromaformat, v->broadcast, v->interlace,
v->tfcntrflag, v->finterpflag
);
v->psf = get_bits1(gb);
if(v->psf) { //PsF, 6.1.13
av_log(v->s.avctx, AV_LOG_ERROR, "Progressive Segmented Frame mode: not supported (yet)\n");
return -1;
}
v->s.max_b_frames = v->s.avctx->max_b_frames = 7;
if(get_bits1(gb)) { //Display Info - decoding is not affected by it
int w, h, ar = 0;
av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n");
v->s.avctx->width = v->s.width = w = get_bits(gb, 14) + 1;
v->s.avctx->height = v->s.height = h = get_bits(gb, 14) + 1;
av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", w, h);
if(get_bits1(gb))
ar = get_bits(gb, 4);
if(ar && ar < 14){
v->s.avctx->sample_aspect_ratio = ff_vc1_pixel_aspect[ar];
}else if(ar == 15){
w = get_bits(gb, 8);
h = get_bits(gb, 8);
v->s.avctx->sample_aspect_ratio = (AVRational){w, h};
}
if(get_bits1(gb)){ //framerate stuff
if(get_bits1(gb)) {
v->s.avctx->time_base.num = 32;
v->s.avctx->time_base.den = get_bits(gb, 16) + 1;
} else {
int nr, dr;
nr = get_bits(gb, 8);
dr = get_bits(gb, 4);
if(nr && nr < 8 && dr && dr < 3){
v->s.avctx->time_base.num = ff_vc1_fps_dr[dr - 1];
v->s.avctx->time_base.den = ff_vc1_fps_nr[nr - 1] * 1000;
}
}
}
if(get_bits1(gb)){
v->color_prim = get_bits(gb, 8);
v->transfer_char = get_bits(gb, 8);
v->matrix_coef = get_bits(gb, 8);
}
}
v->hrd_param_flag = get_bits1(gb);
if(v->hrd_param_flag) {
int i;
v->hrd_num_leaky_buckets = get_bits(gb, 5);
skip_bits(gb, 4); //bitrate exponent
skip_bits(gb, 4); //buffer size exponent
for(i = 0; i < v->hrd_num_leaky_buckets; i++) {
skip_bits(gb, 16); //hrd_rate[n]
skip_bits(gb, 16); //hrd_buffer[n]
}
}
return 0;
}
static int decode_entry_point(AVCodecContext *avctx, GetBitContext *gb)
{
VC1Context *v = avctx->priv_data;
int i, blink, clentry, refdist;
av_log(avctx, AV_LOG_DEBUG, "Entry point: %08X\n", show_bits_long(gb, 32));
blink = get_bits1(gb); // broken link
clentry = get_bits1(gb); // closed entry
v->panscanflag = get_bits1(gb);
refdist = get_bits1(gb); // refdist flag
v->s.loop_filter = get_bits1(gb);
v->fastuvmc = get_bits1(gb);
v->extended_mv = get_bits1(gb);
v->dquant = get_bits(gb, 2);
v->vstransform = get_bits1(gb);
v->overlap = get_bits1(gb);
v->quantizer_mode = get_bits(gb, 2);
if(v->hrd_param_flag){
for(i = 0; i < v->hrd_num_leaky_buckets; i++) {
skip_bits(gb, 8); //hrd_full[n]
}
}
if(get_bits1(gb)){
avctx->coded_width = (get_bits(gb, 12)+1)<<1;
avctx->coded_height = (get_bits(gb, 12)+1)<<1;
}
if(v->extended_mv)
v->extended_dmv = get_bits1(gb);
if(get_bits1(gb)) {
av_log(avctx, AV_LOG_ERROR, "Luma scaling is not supported, expect wrong picture\n");
skip_bits(gb, 3); // Y range, ignored for now
}
if(get_bits1(gb)) {
av_log(avctx, AV_LOG_ERROR, "Chroma scaling is not supported, expect wrong picture\n");
skip_bits(gb, 3); // UV range, ignored for now
}
av_log(avctx, AV_LOG_DEBUG, "Entry point info:\n"
"BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n"
"RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n"
"DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n",
blink, clentry, v->panscanflag, refdist, v->s.loop_filter,
v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode);
return 0;
}
static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
{
int pqindex, lowquant, status;
if(v->finterpflag) v->interpfrm = get_bits1(gb);
skip_bits(gb, 2); //framecnt unused
v->rangeredfrm = 0;
if (v->rangered) v->rangeredfrm = get_bits1(gb);
v->s.pict_type = get_bits1(gb);
if (v->s.avctx->max_b_frames) {
if (!v->s.pict_type) {
if (get_bits1(gb)) v->s.pict_type = I_TYPE;
else v->s.pict_type = B_TYPE;
} else v->s.pict_type = P_TYPE;
} else v->s.pict_type = v->s.pict_type ? P_TYPE : I_TYPE;
v->bi_type = 0;
if(v->s.pict_type == B_TYPE) {
v->bfraction = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);
v->bfraction = ff_vc1_bfraction_lut[v->bfraction];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -