aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2002-07-25 20:22:36 +0000
committerMichael Niedermayer <michaelni@gmx.at>2002-07-25 20:22:36 +0000
commitb5a093b3a9f22f559a6c40f8e8a33efa16da269d (patch)
tree5f57d0af84907a41906551ab033216f9254aa7ed /libavcodec
parentbc4a1ffe96f544b0380431d7c9fc4c997d01e065 (diff)
downloadffmpeg-b5a093b3a9f22f559a6c40f8e8a33efa16da269d.tar.gz
different edge positions fixed with edge emu / dr1
Originally committed as revision 814 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/h263.c14
-rw-r--r--libavcodec/mpegvideo.c82
-rw-r--r--libavcodec/mpegvideo.h1
3 files changed, 48 insertions, 49 deletions
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index fdebcab47a..3b183830b9 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -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;
}
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 0cbe85934a..be4e1dc0a9 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -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)
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index b04d4f74cd..820f1100ec 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -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 */