gpt4 book ai didi

vector - 在ffmpeg H.264解码器中修改运动向量

转载 作者:行者123 更新时间:2023-12-04 21:22:45 27 4
gpt4 key购买 nike

出于研究目的,我尝试在解码过程中在运动补偿之前为每个 P 和 B 帧修改 H.264 运动矢量 (MV)。我为此目的使用 FFmpeg。修改的一个例子是将每个 MV 替换为其原始空间邻居,然后使用生成的 MV,而不是原始的 MV 进行运动补偿。请适本地指导我。

到目前为止,我已经能够对文件中的MV进行简单的修改。/libavcodec/h264_cavlc.c .在函数中, ff_h264_decode_mb_cavlc() ,修改 MX 我的 变量,例如,通过增加它们的值来修改解码期间使用的 MV。

例如,如下所示, MX 我的 值增加了 50,从而延长了解码器中使用的 MV。

mx += get_se_golomb(&s->gb)+50;
my += get_se_golomb(&s->gb)+50;

但是,在这方面,我不知道如何访问 的邻居。 MX 我的 对于我在第一段中提到的空间均值分析。我相信这样做的关键在于操纵数组, mv_cache .

我进行的另一个实验在文件中, libavcodec/error_resilience.c .基于 guess_mv() 函数,我创建了一个新函数, mean_mv() 中执行ff_er_frame_end() 在第一个 if 语句中。第一个 if 语句退出函数 ff_er_frame_end() 如果条件之一是零错误计数 (s->error_count == 0)。但是,我决定插入我的 mean_mv() 在这一点上运行,以便在错误计数为零时始终执行。这个实验在一定程度上产生了我想要的结果,因为我可以开始在视频的顶部看到伪影,但它们仅限于右上角。我猜我插入的功能没有完成以满足播放截止日期或其他内容。

下面是修改后的 if 语句。唯一的补充是我的功能, mean_mv(s) .
if(!s->error_recognition || s->error_count==0 || s->avctx->lowres ||
s->avctx->hwaccel ||
s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
s->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled
s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) {
//av_log(s->avctx, AV_LOG_DEBUG, "ff_er_frame_end in er.c\n"); //KG
if(s->pict_type==AV_PICTURE_TYPE_P)
mean_mv(s);
return;

这是 mean_mv() 我基于 创建的函数guess_mv() .
static void mean_mv(MpegEncContext *s){
//uint8_t fixed[s->mb_stride * s->mb_height];
//const int mb_stride = s->mb_stride;
const int mb_width = s->mb_width;
const int mb_height= s->mb_height;
int mb_x, mb_y, mot_step, mot_stride;

//av_log(s->avctx, AV_LOG_DEBUG, "mean_mv\n"); //KG

set_mv_strides(s, &mot_step, &mot_stride);

for(mb_y=0; mb_y<s->mb_height; mb_y++){
for(mb_x=0; mb_x<s->mb_width; mb_x++){
const int mb_xy= mb_x + mb_y*s->mb_stride;
const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
int mv_predictor[4][2]={{0}};
int ref[4]={0};
int pred_count=0;
int m, n;

if(IS_INTRA(s->current_picture.f.mb_type[mb_xy])) continue;
//if(!(s->error_status_table[mb_xy]&MV_ERROR)){
//if (1){
if(mb_x>0){
mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index - mot_step][0];
mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index - mot_step][1];
ref [pred_count] = s->current_picture.f.ref_index[0][4*(mb_xy-1)];
pred_count++;
}

if(mb_x+1<mb_width){
mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index + mot_step][0];
mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index + mot_step][1];
ref [pred_count] = s->current_picture.f.ref_index[0][4*(mb_xy+1)];
pred_count++;
}

if(mb_y>0){
mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index - mot_stride*mot_step][0];
mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index - mot_stride*mot_step][1];
ref [pred_count] = s->current_picture.f.ref_index[0][4*(mb_xy-s->mb_stride)];
pred_count++;
}

if(mb_y+1<mb_height){
mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index + mot_stride*mot_step][0];
mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index + mot_stride*mot_step][1];
ref [pred_count] = s->current_picture.f.ref_index[0][4*(mb_xy+s->mb_stride)];
pred_count++;
}

if(pred_count==0) continue;

if(pred_count>=1){
int sum_x=0, sum_y=0, sum_r=0;
int k;

for(k=0; k<pred_count; k++){
sum_x+= mv_predictor[k][0]; // Sum all the MVx from MVs avail. for EC
sum_y+= mv_predictor[k][1]; // Sum all the MVy from MVs avail. for EC
sum_r+= ref[k];
// if(k && ref[k] != ref[k-1])
// goto skip_mean_and_median;
}

mv_predictor[pred_count][0] = sum_x/k;
mv_predictor[pred_count][1] = sum_y/k;
ref [pred_count] = sum_r/k;
}

s->mv[0][0][0] = mv_predictor[pred_count][0];
s->mv[0][0][1] = mv_predictor[pred_count][1];

for(m=0; m<mot_step; m++){
for(n=0; n<mot_step; n++){
s->current_picture.f.motion_val[0][mot_index + m + n * mot_stride][0] = s->mv[0][0][0];
s->current_picture.f.motion_val[0][mot_index + m + n * mot_stride][1] = s->mv[0][0][1];
}
}

decode_mb(s, ref[pred_count]);

//}
}
}
}

我真的很感激一些关于如何正确处理这个问题的帮助。

最佳答案

很长时间以来,我一直在内部与 FFMPEG 的代码脱节。

但是,鉴于我对 FFMPEG 内部恐怖的经验(你会明白我的意思),我宁愿给你一个简单实用的建议。

建议#1
最好的可能性是,当每个 block 的运动矢量被识别时 - 您可以在 FFMPEG 编码器上下文(又名 s )中创建自己的附加数组,该数组将存储所有这些。当您的算法运行时,它将从那里获取值。

建议#2
我读的另一件事(我不确定我是否读对了)

the mx and my values are increased by 50



我认为 50 是一个非常大的运动向量。并且通常,运动矢量编码的 F 值范围是先验限制的。如果您将内容更改 +/- 8(甚至 +/- 16)可能就可以了 - 但 +50 可能会如此之高,以至于最终结果可能无法正确编码。

我不太明白你关于 mean_mv() 的目的。以及您期望从那里发生的失败。请重新措辞一下。

关于vector - 在ffmpeg H.264解码器中修改运动向量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9270250/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com