mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
different edge positions fixed with edge emu / dr1
Originally committed as revision 814 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
bc4a1ffe96
commit
b5a093b3a9
@ -1348,6 +1348,8 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
|
||||
|
||||
s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; //FIXME add short header support
|
||||
s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
|
||||
s->h_edge_pos= s->width;
|
||||
s->v_edge_pos= s->height;
|
||||
}
|
||||
|
||||
static void h263_dc_scale(MpegEncContext * s)
|
||||
@ -3851,11 +3853,15 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
|
||||
printf("Error, header damaged or not MPEG4 header (f_code=0)\n");
|
||||
return -1; // makes no sense to continue, as the MV decoding will break very quickly
|
||||
}
|
||||
}
|
||||
}else
|
||||
s->f_code=1;
|
||||
|
||||
if (s->pict_type == B_TYPE) {
|
||||
s->b_code = get_bits(&s->gb, 3);
|
||||
//printf("b-code %d\n", s->b_code);
|
||||
}
|
||||
}else
|
||||
s->b_code=1;
|
||||
|
||||
//printf("quant:%d fcode:%d bcode:%d type:%d\n", s->qscale, s->f_code, s->b_code, s->pict_type);
|
||||
if(!s->scalability){
|
||||
if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) {
|
||||
@ -3884,6 +3890,10 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
|
||||
s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; //FIXME add short header support
|
||||
s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
|
||||
|
||||
if(s->divx_version==0 || s->divx_version < 500){
|
||||
s->h_edge_pos= s->width;
|
||||
s->v_edge_pos= s->height;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -145,6 +145,11 @@ int MPV_common_init(MpegEncContext *s)
|
||||
|
||||
s->mb_width = (s->width + 15) / 16;
|
||||
s->mb_height = (s->height + 15) / 16;
|
||||
|
||||
/* set default edge pos, will be overriden in decode_header if needed */
|
||||
s->h_edge_pos= s->mb_width*16;
|
||||
s->v_edge_pos= s->mb_height*16;
|
||||
|
||||
s->mb_num = s->mb_width * s->mb_height;
|
||||
if(!(s->flags&CODEC_FLAG_DR1)){
|
||||
s->linesize = s->mb_width * 16 + 2 * EDGE_WIDTH;
|
||||
@ -624,7 +629,6 @@ void MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
|
||||
avctx->mbskip_table= s->mbskip_table;
|
||||
|
||||
if(avctx->flags&CODEC_FLAG_DR1){
|
||||
int i;
|
||||
avctx->get_buffer_callback(avctx, s->width, s->height, s->pict_type);
|
||||
|
||||
s->linesize = avctx->dr_stride;
|
||||
@ -676,16 +680,9 @@ void MPV_frame_end(MpegEncContext *s)
|
||||
|
||||
/* draw edge for correct motion prediction if outside */
|
||||
if (s->pict_type != B_TYPE && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
|
||||
if(s->avctx==NULL || s->avctx->codec->id!=CODEC_ID_MPEG4 || s->divx_version>=500){
|
||||
draw_edges(s->current_picture[0], s->linesize, s->mb_width*16, s->mb_height*16, EDGE_WIDTH);
|
||||
draw_edges(s->current_picture[1], s->uvlinesize, s->mb_width*8, s->mb_height*8, EDGE_WIDTH/2);
|
||||
draw_edges(s->current_picture[2], s->uvlinesize, s->mb_width*8, s->mb_height*8, EDGE_WIDTH/2);
|
||||
}else{
|
||||
/* mpeg4? / opendivx / xvid */
|
||||
draw_edges(s->current_picture[0], s->linesize, s->width, s->height, EDGE_WIDTH);
|
||||
draw_edges(s->current_picture[1], s->uvlinesize, s->width/2, s->height/2, EDGE_WIDTH/2);
|
||||
draw_edges(s->current_picture[2], s->uvlinesize, s->width/2, s->height/2, EDGE_WIDTH/2);
|
||||
}
|
||||
draw_edges(s->current_picture[0], s->linesize , s->h_edge_pos , s->v_edge_pos , EDGE_WIDTH );
|
||||
draw_edges(s->current_picture[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
|
||||
draw_edges(s->current_picture[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);
|
||||
}
|
||||
emms_c();
|
||||
|
||||
@ -908,9 +905,9 @@ static inline void gmc1_motion(MpegEncContext *s,
|
||||
|
||||
dest_y+=dest_offset;
|
||||
if(s->flags&CODEC_FLAG_EMU_EDGE){
|
||||
if(src_x<0 || src_y<0 || src_x + (motion_x&15) + 16 > s->width
|
||||
|| src_y + (motion_y&15) + h > s->height){
|
||||
emulated_edge_mc(s, ptr, linesize, 17, h+1, src_x, src_y, s->width, s->height);
|
||||
if(src_x<0 || src_y<0 || src_x + (motion_x&15) + 16 > s->h_edge_pos
|
||||
|| src_y + (motion_y&15) + h > s->v_edge_pos){
|
||||
emulated_edge_mc(s, ptr, linesize, 17, h+1, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
|
||||
ptr= s->edge_emu_buffer;
|
||||
emu=1;
|
||||
}
|
||||
@ -934,14 +931,14 @@ static inline void gmc1_motion(MpegEncContext *s,
|
||||
offset = (src_y * uvlinesize) + src_x + (src_offset>>1);
|
||||
ptr = ref_picture[1] + offset;
|
||||
if(emu){
|
||||
emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->width>>1, s->height>>1);
|
||||
emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
|
||||
ptr= s->edge_emu_buffer;
|
||||
}
|
||||
gmc1(dest_cb + (dest_offset>>1), ptr, uvlinesize, h>>1, motion_x&15, motion_y&15, s->no_rounding);
|
||||
|
||||
ptr = ref_picture[2] + offset;
|
||||
if(emu){
|
||||
emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->width>>1, s->height>>1);
|
||||
emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
|
||||
ptr= s->edge_emu_buffer;
|
||||
}
|
||||
gmc1(dest_cr + (dest_offset>>1), ptr, uvlinesize, h>>1, motion_x&15, motion_y&15, s->no_rounding);
|
||||
@ -954,17 +951,7 @@ static void emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int bl
|
||||
int x, y;
|
||||
int start_y, start_x, end_y, end_x;
|
||||
UINT8 *buf= s->edge_emu_buffer;
|
||||
#if 0
|
||||
if(s->codec_id!=CODEC_ID_MPEG4 || s->divx_version>=500){
|
||||
if(block_w < 10){
|
||||
w= (w+7)&(~7);
|
||||
h= (h+7)&(~7);
|
||||
}else{
|
||||
w= (w+15)&(~15);
|
||||
h= (h+15)&(~15);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(src_y>= h){
|
||||
src+= (h-1-src_y)*linesize;
|
||||
src_y=h-1;
|
||||
@ -1029,7 +1016,7 @@ static inline void mpeg_motion(MpegEncContext *s,
|
||||
int motion_x, int motion_y, int h)
|
||||
{
|
||||
UINT8 *ptr;
|
||||
int dxy, offset, mx, my, src_x, src_y, height, linesize, uvlinesize;
|
||||
int dxy, offset, mx, my, src_x, src_y, height, v_edge_pos, linesize, uvlinesize;
|
||||
int emu=0;
|
||||
|
||||
if(s->quarter_sample)
|
||||
@ -1043,6 +1030,7 @@ if(s->quarter_sample)
|
||||
|
||||
/* WARNING: do no forget half pels */
|
||||
height = s->height >> field_based;
|
||||
v_edge_pos = s->v_edge_pos >> field_based;
|
||||
src_x = clip(src_x, -16, s->width);
|
||||
if (src_x == s->width)
|
||||
dxy &= ~1;
|
||||
@ -1055,9 +1043,9 @@ if(s->quarter_sample)
|
||||
dest_y += dest_offset;
|
||||
|
||||
if(s->flags&CODEC_FLAG_EMU_EDGE){
|
||||
if(src_x<0 || src_y<0 || src_x + (motion_x&1) + 16 > s->width
|
||||
|| src_y + (motion_y&1) + h > height){
|
||||
emulated_edge_mc(s, ptr, linesize, 17, h+1, src_x, src_y, s->width, height);
|
||||
if(src_x<0 || src_y<0 || src_x + (motion_x&1) + 16 > s->h_edge_pos
|
||||
|| src_y + (motion_y&1) + h > v_edge_pos){
|
||||
emulated_edge_mc(s, ptr, linesize, 17, h+1, src_x, src_y, s->h_edge_pos, v_edge_pos);
|
||||
ptr= s->edge_emu_buffer;
|
||||
emu=1;
|
||||
}
|
||||
@ -1094,14 +1082,14 @@ if(s->quarter_sample)
|
||||
offset = (src_y * uvlinesize) + src_x + (src_offset >> 1);
|
||||
ptr = ref_picture[1] + offset;
|
||||
if(emu){
|
||||
emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->width>>1, height>>1);
|
||||
emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, v_edge_pos>>1);
|
||||
ptr= s->edge_emu_buffer;
|
||||
}
|
||||
pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, uvlinesize, h >> 1);
|
||||
|
||||
ptr = ref_picture[2] + offset;
|
||||
if(emu){
|
||||
emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->width>>1, height>>1);
|
||||
emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, v_edge_pos>>1);
|
||||
ptr= s->edge_emu_buffer;
|
||||
}
|
||||
pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, uvlinesize, h >> 1);
|
||||
@ -1116,7 +1104,7 @@ static inline void qpel_motion(MpegEncContext *s,
|
||||
int motion_x, int motion_y, int h)
|
||||
{
|
||||
UINT8 *ptr;
|
||||
int dxy, offset, mx, my, src_x, src_y, height, linesize;
|
||||
int dxy, offset, mx, my, src_x, src_y, height, v_edge_pos, linesize;
|
||||
int emu=0;
|
||||
|
||||
dxy = ((motion_y & 3) << 2) | (motion_x & 3);
|
||||
@ -1124,6 +1112,7 @@ static inline void qpel_motion(MpegEncContext *s,
|
||||
src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2);
|
||||
|
||||
height = s->height >> field_based;
|
||||
v_edge_pos = s->v_edge_pos >> field_based;
|
||||
src_x = clip(src_x, -16, s->width);
|
||||
if (src_x == s->width)
|
||||
dxy &= ~3;
|
||||
@ -1136,9 +1125,9 @@ static inline void qpel_motion(MpegEncContext *s,
|
||||
//printf("%d %d %d\n", src_x, src_y, dxy);
|
||||
|
||||
if(s->flags&CODEC_FLAG_EMU_EDGE){
|
||||
if(src_x<0 || src_y<0 || src_x + (motion_x&3) + 16 > s->width
|
||||
|| src_y + (motion_y&3) + h > height){
|
||||
emulated_edge_mc(s, ptr, linesize, 17, h+1, src_x, src_y, s->width, height);
|
||||
if(src_x<0 || src_y<0 || src_x + (motion_x&3) + 16 > s->h_edge_pos
|
||||
|| src_y + (motion_y&3) + h > v_edge_pos){
|
||||
emulated_edge_mc(s, ptr, linesize, 17, h+1, src_x, src_y, s->h_edge_pos, v_edge_pos);
|
||||
ptr= s->edge_emu_buffer;
|
||||
emu=1;
|
||||
}
|
||||
@ -1173,14 +1162,14 @@ static inline void qpel_motion(MpegEncContext *s,
|
||||
offset = (src_y * s->uvlinesize) + src_x + (src_offset >> 1);
|
||||
ptr = ref_picture[1] + offset;
|
||||
if(emu){
|
||||
emulated_edge_mc(s, ptr, s->uvlinesize, 9, (h>>1)+1, src_x, src_y, s->width>>1, height>>1);
|
||||
emulated_edge_mc(s, ptr, s->uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, v_edge_pos>>1);
|
||||
ptr= s->edge_emu_buffer;
|
||||
}
|
||||
pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, s->uvlinesize, h >> 1);
|
||||
|
||||
ptr = ref_picture[2] + offset;
|
||||
if(emu){
|
||||
emulated_edge_mc(s, ptr, s->uvlinesize, 9, (h>>1)+1, src_x, src_y, s->width>>1, height>>1);
|
||||
emulated_edge_mc(s, ptr, s->uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, v_edge_pos>>1);
|
||||
ptr= s->edge_emu_buffer;
|
||||
}
|
||||
pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, s->uvlinesize, h >> 1);
|
||||
@ -1246,9 +1235,9 @@ static inline void MPV_motion(MpegEncContext *s,
|
||||
|
||||
ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
|
||||
if(s->flags&CODEC_FLAG_EMU_EDGE){
|
||||
if(src_x<0 || src_y<0 || src_x + (motion_x&1) + 8 > s->width
|
||||
|| src_y + (motion_y&1) + 8 > s->height){
|
||||
emulated_edge_mc(s, ptr, s->linesize, 9, 9, src_x, src_y, s->width, s->height);
|
||||
if(src_x<0 || src_y<0 || src_x + (motion_x&1) + 8 > s->h_edge_pos
|
||||
|| src_y + (motion_y&1) + 8 > s->v_edge_pos){
|
||||
emulated_edge_mc(s, ptr, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
|
||||
ptr= s->edge_emu_buffer;
|
||||
}
|
||||
}
|
||||
@ -1293,9 +1282,9 @@ static inline void MPV_motion(MpegEncContext *s,
|
||||
offset = (src_y * (s->uvlinesize)) + src_x;
|
||||
ptr = ref_picture[1] + offset;
|
||||
if(s->flags&CODEC_FLAG_EMU_EDGE){
|
||||
if(src_x<0 || src_y<0 || src_x + (dxy &1) + 8 > s->width >>1
|
||||
|| src_y + (dxy>>1) + 8 > s->height>>1){
|
||||
emulated_edge_mc(s, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->width>>1, s->height>>1);
|
||||
if(src_x<0 || src_y<0 || src_x + (dxy &1) + 8 > s->h_edge_pos>>1
|
||||
|| src_y + (dxy>>1) + 8 > s->v_edge_pos>>1){
|
||||
emulated_edge_mc(s, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
|
||||
ptr= s->edge_emu_buffer;
|
||||
emu=1;
|
||||
}
|
||||
@ -1304,7 +1293,7 @@ static inline void MPV_motion(MpegEncContext *s,
|
||||
|
||||
ptr = ref_picture[2] + offset;
|
||||
if(emu){
|
||||
emulated_edge_mc(s, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->width>>1, s->height>>1);
|
||||
emulated_edge_mc(s, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
|
||||
ptr= s->edge_emu_buffer;
|
||||
}
|
||||
pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);
|
||||
@ -2022,7 +2011,6 @@ static void encode_picture(MpegEncContext *s, int picture_number)
|
||||
//printf("f_code %d ///\n", s->f_code);
|
||||
|
||||
// printf("%d %d\n", s->avg_mb_var, s->mc_mb_var);
|
||||
|
||||
if(s->flags&CODEC_FLAG_PASS2)
|
||||
s->qscale = ff_rate_estimate_qscale_pass2(s);
|
||||
else if (!s->fixed_qscale)
|
||||
|
@ -130,6 +130,7 @@ typedef struct MpegEncContext {
|
||||
int picture_in_gop_number; /* 0-> first pic in gop, ... */
|
||||
int b_frames_since_non_b; /* used for encoding, relative to not yet reordered input */
|
||||
int mb_width, mb_height; /* number of MBs horizontally & vertically */
|
||||
int h_edge_pos, v_edge_pos;/* horizontal / vertical position of the right/bottom edge (pixel replicateion)*/
|
||||
int mb_num; /* number of MBs of a picture */
|
||||
int linesize; /* line size, in bytes, may be different from width */
|
||||
int uvlinesize; /* line size, for chroma in bytes, may be different from width */
|
||||
|
Loading…
Reference in New Issue
Block a user