Originally committed as revision 406 to svn://svn.ffmpeg.org/ffmpeg/trunk
Michael Niedermayer authored on 2002/04/19 12:25:20... | ... |
@@ -881,6 +881,16 @@ static inline int mid_pred(int a, int b, int c) |
881 | 881 |
return a + b + c - vmin - vmax; |
882 | 882 |
} |
883 | 883 |
|
884 |
+static inline int clip(int a, int amin, int amax) |
|
885 |
+{ |
|
886 |
+ if (a < amin) |
|
887 |
+ return amin; |
|
888 |
+ else if (a > amax) |
|
889 |
+ return amax; |
|
890 |
+ else |
|
891 |
+ return a; |
|
892 |
+} |
|
893 |
+ |
|
884 | 894 |
/* memory */ |
885 | 895 |
void *av_mallocz(int size); |
886 | 896 |
|
... | ... |
@@ -18,7 +18,7 @@ |
18 | 18 |
* along with this program; if not, write to the Free Software |
19 | 19 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | 20 |
* |
21 |
- * ac prediction encoding by Michael Niedermayer <michaelni@gmx.at> |
|
21 |
+ * ac prediction encoding & b-frame support by Michael Niedermayer <michaelni@gmx.at> |
|
22 | 22 |
*/ |
23 | 23 |
#include "common.h" |
24 | 24 |
#include "dsputil.h" |
... | ... |
@@ -282,7 +282,7 @@ void mpeg4_encode_mb(MpegEncContext * s, |
282 | 282 |
s->mv[0][0][1]= |
283 | 283 |
s->mv[1][0][0]= |
284 | 284 |
s->mv[1][0][1]= 0; |
285 |
-// s->mv_dir= MV_DIR_FORWARD; //doesnt matter |
|
285 |
+ s->mv_dir= MV_DIR_FORWARD; //doesnt matter |
|
286 | 286 |
return; |
287 | 287 |
} |
288 | 288 |
|
... | ... |
@@ -334,7 +334,8 @@ void mpeg4_encode_mb(MpegEncContext * s, |
334 | 334 |
s->last_mv[0][0][0]= motion_x; |
335 | 335 |
s->last_mv[0][0][1]= motion_y; |
336 | 336 |
break; |
337 |
- default: |
|
337 |
+ default: |
|
338 |
+ printf("unknown mb type\n"); |
|
338 | 339 |
return; |
339 | 340 |
} |
340 | 341 |
bits= get_bit_count(&s->pb); |
... | ... |
@@ -959,6 +960,31 @@ static void put_string(PutBitContext * pbc, char *s) |
959 | 959 |
put_bits(pbc, 8, 0); |
960 | 960 |
} |
961 | 961 |
|
962 |
+/* must be called before writing the header */ |
|
963 |
+void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){ |
|
964 |
+ int time_div, time_mod; |
|
965 |
+ |
|
966 |
+ if(s->pict_type==I_TYPE){ //we will encode a vol header |
|
967 |
+ s->time_increment_resolution= s->frame_rate/ff_gcd(s->frame_rate, FRAME_RATE_BASE); |
|
968 |
+ if(s->time_increment_resolution>=256*256) s->time_increment_resolution= 256*128; |
|
969 |
+ |
|
970 |
+ s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; |
|
971 |
+ } |
|
972 |
+ |
|
973 |
+ s->time= picture_number*(int64_t)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate; |
|
974 |
+ time_div= s->time/s->time_increment_resolution; |
|
975 |
+ time_mod= s->time%s->time_increment_resolution; |
|
976 |
+ |
|
977 |
+ if(s->pict_type==B_TYPE){ |
|
978 |
+ s->bp_time= s->last_non_b_time - s->time; |
|
979 |
+ }else{ |
|
980 |
+ s->last_time_base= s->time_base; |
|
981 |
+ s->time_base= time_div; |
|
982 |
+ s->pp_time= s->time - s->last_non_b_time; |
|
983 |
+ s->last_non_b_time= s->time; |
|
984 |
+ } |
|
985 |
+} |
|
986 |
+ |
|
962 | 987 |
static void mpeg4_encode_vol_header(MpegEncContext * s) |
963 | 988 |
{ |
964 | 989 |
int vo_ver_id=1; //must be 2 if we want GMC or q-pel |
... | ... |
@@ -983,11 +1009,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s) |
983 | 983 |
put_bits(&s->pb, 2, RECT_SHAPE); /* vol shape= rectangle */ |
984 | 984 |
put_bits(&s->pb, 1, 1); /* marker bit */ |
985 | 985 |
|
986 |
- s->time_increment_resolution= s->frame_rate/ff_gcd(s->frame_rate, FRAME_RATE_BASE); |
|
987 |
- if(s->time_increment_resolution>=256*256) s->time_increment_resolution= 256*128; |
|
988 |
- |
|
989 | 986 |
put_bits(&s->pb, 16, s->time_increment_resolution); |
990 |
- s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; |
|
991 | 987 |
if (s->time_increment_bits < 1) |
992 | 988 |
s->time_increment_bits = 1; |
993 | 989 |
put_bits(&s->pb, 1, 1); /* marker bit */ |
... | ... |
@@ -1034,9 +1056,6 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) |
1034 | 1034 |
|
1035 | 1035 |
if(s->pict_type==I_TYPE) mpeg4_encode_vol_header(s); |
1036 | 1036 |
|
1037 |
- s->time= s->picture_number*(int64_t)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate; |
|
1038 |
- time_div= s->time/s->time_increment_resolution; |
|
1039 |
- time_mod= s->time%s->time_increment_resolution; |
|
1040 | 1037 |
//printf("num:%d rate:%d base:%d\n", s->picture_number, s->frame_rate, FRAME_RATE_BASE); |
1041 | 1038 |
|
1042 | 1039 |
if(get_bit_count(&s->pb)!=0) mpeg4_stuffing(&s->pb); |
... | ... |
@@ -1044,15 +1063,8 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) |
1044 | 1044 |
put_bits(&s->pb, 16, 0x1B6); /* vop header */ |
1045 | 1045 |
put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */ |
1046 | 1046 |
|
1047 |
- if(s->pict_type==B_TYPE){ |
|
1048 |
- s->bp_time= s->last_non_b_time - s->time; |
|
1049 |
- }else{ |
|
1050 |
- s->last_time_base= s->time_base; |
|
1051 |
- s->time_base= time_div; |
|
1052 |
- s->pp_time= s->time - s->last_non_b_time; |
|
1053 |
- s->last_non_b_time= s->time; |
|
1054 |
- } |
|
1055 |
- |
|
1047 |
+ time_div= s->time/s->time_increment_resolution; |
|
1048 |
+ time_mod= s->time%s->time_increment_resolution; |
|
1056 | 1049 |
time_incr= time_div - s->last_time_base; |
1057 | 1050 |
while(time_incr--) |
1058 | 1051 |
put_bits(&s->pb, 1, 1); |
... | ... |
@@ -1770,6 +1782,7 @@ int h263_decode_mb(MpegEncContext *s, |
1770 | 1770 |
s->last_mv[0][0][1]= |
1771 | 1771 |
s->last_mv[1][0][0]= |
1772 | 1772 |
s->last_mv[1][0][1]= 0; |
1773 |
+// printf("\n"); |
|
1773 | 1774 |
} |
1774 | 1775 |
|
1775 | 1776 |
/* if we skipped it in the future P Frame than skip it now too */ |
... | ... |
@@ -1789,6 +1802,7 @@ int h263_decode_mb(MpegEncContext *s, |
1789 | 1789 |
//FIXME is this correct? |
1790 | 1790 |
/* s->last_mv[0][0][0]= |
1791 | 1791 |
s->last_mv[0][0][1]=0;*/ |
1792 |
+// printf("S"); |
|
1792 | 1793 |
return 0; |
1793 | 1794 |
} |
1794 | 1795 |
|
... | ... |
@@ -1837,6 +1851,7 @@ int h263_decode_mb(MpegEncContext *s, |
1837 | 1837 |
s->mv[0][0][1] = |
1838 | 1838 |
s->mv[1][0][0] = |
1839 | 1839 |
s->mv[1][0][1] = 1000;*/ |
1840 |
+// printf("D"); |
|
1840 | 1841 |
break; |
1841 | 1842 |
case 1: |
1842 | 1843 |
s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; |
... | ... |
@@ -1849,6 +1864,7 @@ int h263_decode_mb(MpegEncContext *s, |
1849 | 1849 |
my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code); |
1850 | 1850 |
s->last_mv[1][0][0]= s->mv[1][0][0] = mx; |
1851 | 1851 |
s->last_mv[1][0][1]= s->mv[1][0][1] = my; |
1852 |
+// printf("I"); |
|
1852 | 1853 |
break; |
1853 | 1854 |
case 2: |
1854 | 1855 |
s->mv_dir = MV_DIR_BACKWARD; |
... | ... |
@@ -1856,6 +1872,7 @@ int h263_decode_mb(MpegEncContext *s, |
1856 | 1856 |
my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code); |
1857 | 1857 |
s->last_mv[1][0][0]= s->mv[1][0][0] = mx; |
1858 | 1858 |
s->last_mv[1][0][1]= s->mv[1][0][1] = my; |
1859 |
+// printf("B"); |
|
1859 | 1860 |
break; |
1860 | 1861 |
case 3: |
1861 | 1862 |
s->mv_dir = MV_DIR_FORWARD; |
... | ... |
@@ -1863,6 +1880,7 @@ int h263_decode_mb(MpegEncContext *s, |
1863 | 1863 |
my = h263_decode_motion(s, s->last_mv[0][0][1], s->f_code); |
1864 | 1864 |
s->last_mv[0][0][0]= s->mv[0][0][0] = mx; |
1865 | 1865 |
s->last_mv[0][0][1]= s->mv[0][0][1] = my; |
1866 |
+// printf("F"); |
|
1866 | 1867 |
break; |
1867 | 1868 |
default: return -1; |
1868 | 1869 |
} |
... | ... |
@@ -29,7 +29,7 @@ |
29 | 29 |
#define MAX(a,b) ((a) > (b) ? (a) : (b)) |
30 | 30 |
#define INTER_BIAS 257 |
31 | 31 |
|
32 |
-static void halfpel_motion_search(MpegEncContext * s, |
|
32 |
+static int halfpel_motion_search(MpegEncContext * s, |
|
33 | 33 |
int *mx_ptr, int *my_ptr, int dmin, |
34 | 34 |
int xmin, int ymin, int xmax, int ymax, |
35 | 35 |
int pred_x, int pred_y, uint8_t *ref_picture); |
... | ... |
@@ -673,7 +673,7 @@ static int epzs_motion_search4(MpegEncContext * s, int block, |
673 | 673 |
|
674 | 674 |
/* The idea would be to make half pel ME after Inter/Intra decision to |
675 | 675 |
save time. */ |
676 |
-static inline void halfpel_motion_search(MpegEncContext * s, |
|
676 |
+static inline int halfpel_motion_search(MpegEncContext * s, |
|
677 | 677 |
int *mx_ptr, int *my_ptr, int dmin, |
678 | 678 |
int xmin, int ymin, int xmax, int ymax, |
679 | 679 |
int pred_x, int pred_y, uint8_t *ref_picture) |
... | ... |
@@ -702,7 +702,7 @@ static inline void halfpel_motion_search(MpegEncContext * s, |
702 | 702 |
if(dmin < Z_THRESHOLD && mx==0 && my==0){ |
703 | 703 |
*mx_ptr = 0; |
704 | 704 |
*my_ptr = 0; |
705 |
- return; |
|
705 |
+ return dmin; |
|
706 | 706 |
} |
707 | 707 |
|
708 | 708 |
pen_x= pred_x + mx; |
... | ... |
@@ -727,6 +727,7 @@ static inline void halfpel_motion_search(MpegEncContext * s, |
727 | 727 |
|
728 | 728 |
*mx_ptr = mx; |
729 | 729 |
*my_ptr = my; |
730 |
+ return dminh; |
|
730 | 731 |
} |
731 | 732 |
|
732 | 733 |
static inline void halfpel_motion_search4(MpegEncContext * s, |
... | ... |
@@ -1044,17 +1045,15 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, |
1044 | 1044 |
set_p_mv_tables(s, mx, my); |
1045 | 1045 |
} |
1046 | 1046 |
|
1047 |
-void ff_estimate_motion_b(MpegEncContext * s, |
|
1047 |
+int ff_estimate_motion_b(MpegEncContext * s, |
|
1048 | 1048 |
int mb_x, int mb_y, int16_t (*mv_table)[2], uint8_t *ref_picture, int f_code) |
1049 | 1049 |
{ |
1050 |
- UINT8 *pix, *ppix; |
|
1051 |
- int sum, varc, vard, mx, my, range, dmin, xx, yy; |
|
1050 |
+ int mx, my, range, dmin; |
|
1052 | 1051 |
int xmin, ymin, xmax, ymax; |
1053 | 1052 |
int rel_xmin, rel_ymin, rel_xmax, rel_ymax; |
1054 | 1053 |
int pred_x=0, pred_y=0; |
1055 | 1054 |
int P[6][2]; |
1056 | 1055 |
const int shift= 1+s->quarter_sample; |
1057 |
- int mb_type=0; |
|
1058 | 1056 |
const int mot_stride = s->mb_width + 2; |
1059 | 1057 |
const int mot_xy = (mb_y + 1)*mot_stride + mb_x + 1; |
1060 | 1058 |
|
... | ... |
@@ -1124,18 +1123,210 @@ void ff_estimate_motion_b(MpegEncContext * s, |
1124 | 1124 |
/* At this point (mx,my) are full-pell and the absolute displacement */ |
1125 | 1125 |
// ppix = ref_picture + (my * s->linesize) + mx; |
1126 | 1126 |
|
1127 |
- halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, pred_x, pred_y, ref_picture); |
|
1127 |
+ dmin= halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, pred_x, pred_y, ref_picture); |
|
1128 | 1128 |
|
1129 | 1129 |
// s->mb_type[mb_y*s->mb_width + mb_x]= mb_type; |
1130 | 1130 |
mv_table[mot_xy][0]= mx; |
1131 | 1131 |
mv_table[mot_xy][1]= my; |
1132 |
+ return dmin; |
|
1132 | 1133 |
} |
1133 | 1134 |
|
1134 | 1135 |
|
1135 |
-int ff_decide_type(MpegEncContext * s, |
|
1136 |
- int mb_x, int mb_y) |
|
1136 |
+static inline int check_bidir_mv(MpegEncContext * s, |
|
1137 |
+ int mb_x, int mb_y, |
|
1138 |
+ int motion_fx, int motion_fy, |
|
1139 |
+ int motion_bx, int motion_by, |
|
1140 |
+ int pred_fx, int pred_fy, |
|
1141 |
+ int pred_bx, int pred_by) |
|
1137 | 1142 |
{ |
1143 |
+ //FIXME optimize? |
|
1144 |
+ UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame |
|
1145 |
+ uint8_t *dest_y = s->me_scratchpad; |
|
1146 |
+ uint8_t *ptr; |
|
1147 |
+ int dxy; |
|
1148 |
+ int src_x, src_y; |
|
1149 |
+ int fbmin; |
|
1150 |
+ |
|
1151 |
+ fbmin = (mv_penalty[motion_fx-pred_fx] + mv_penalty[motion_fy-pred_fy])*s->qscale; |
|
1152 |
+ |
|
1153 |
+ dxy = ((motion_fy & 1) << 1) | (motion_fx & 1); |
|
1154 |
+ src_x = mb_x * 16 + (motion_fx >> 1); |
|
1155 |
+ src_y = mb_y * 16 + (motion_fy >> 1); |
|
1156 |
+ |
|
1157 |
+ ptr = s->last_picture[0] + (src_y * s->linesize) + src_x; |
|
1158 |
+ put_pixels_tab[dxy](dest_y , ptr , s->linesize, 16); |
|
1159 |
+ put_pixels_tab[dxy](dest_y + 8, ptr + 8, s->linesize, 16); |
|
1160 |
+ |
|
1161 |
+ fbmin += (mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->qscale; |
|
1162 |
+ |
|
1163 |
+ dxy = ((motion_by & 1) << 1) | (motion_bx & 1); |
|
1164 |
+ src_x = mb_x * 16 + (motion_bx >> 1); |
|
1165 |
+ src_y = mb_y * 16 + (motion_by >> 1); |
|
1166 |
+ |
|
1167 |
+ ptr = s->next_picture[0] + (src_y * s->linesize) + src_x; |
|
1168 |
+ avg_pixels_tab[dxy](dest_y , ptr , s->linesize, 16); |
|
1169 |
+ avg_pixels_tab[dxy](dest_y + 8, ptr + 8, s->linesize, 16); |
|
1170 |
+ |
|
1171 |
+ fbmin += pix_abs16x16(s->new_picture[0] + mb_x*16 + mb_y*16*s->linesize, dest_y, s->linesize); |
|
1172 |
+ return fbmin; |
|
1173 |
+} |
|
1138 | 1174 |
|
1175 |
+/* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/ |
|
1176 |
+static inline int bidir_refine(MpegEncContext * s, |
|
1177 |
+ int mb_x, int mb_y) |
|
1178 |
+{ |
|
1179 |
+ const int mot_stride = s->mb_width + 2; |
|
1180 |
+ const int xy = (mb_y + 1)*mot_stride + mb_x + 1; |
|
1181 |
+ int fbmin; |
|
1182 |
+ int pred_fx= s->b_bidir_forw_mv_table[xy-1][0]; |
|
1183 |
+ int pred_fy= s->b_bidir_forw_mv_table[xy-1][1]; |
|
1184 |
+ int pred_bx= s->b_bidir_back_mv_table[xy-1][0]; |
|
1185 |
+ int pred_by= s->b_bidir_back_mv_table[xy-1][1]; |
|
1186 |
+ int motion_fx= s->b_bidir_forw_mv_table[xy][0]= s->b_forw_mv_table[xy][0]; |
|
1187 |
+ int motion_fy= s->b_bidir_forw_mv_table[xy][1]= s->b_forw_mv_table[xy][1]; |
|
1188 |
+ int motion_bx= s->b_bidir_back_mv_table[xy][0]= s->b_back_mv_table[xy][0]; |
|
1189 |
+ int motion_by= s->b_bidir_back_mv_table[xy][1]= s->b_back_mv_table[xy][1]; |
|
1190 |
+ |
|
1191 |
+ //FIXME do refinement and add flag |
|
1192 |
+ |
|
1193 |
+ fbmin= check_bidir_mv(s, mb_x, mb_y, |
|
1194 |
+ motion_fx, motion_fy, |
|
1195 |
+ motion_bx, motion_by, |
|
1196 |
+ pred_fx, pred_fy, |
|
1197 |
+ pred_bx, pred_by); |
|
1198 |
+ |
|
1199 |
+ return fbmin; |
|
1200 |
+} |
|
1201 |
+ |
|
1202 |
+static inline int direct_search(MpegEncContext * s, |
|
1203 |
+ int mb_x, int mb_y) |
|
1204 |
+{ |
|
1205 |
+ int P[6][2]; |
|
1206 |
+ const int mot_stride = s->mb_width + 2; |
|
1207 |
+ const int mot_xy = (mb_y + 1)*mot_stride + mb_x + 1; |
|
1208 |
+ int dmin, dmin2; |
|
1209 |
+ int motion_fx, motion_fy, motion_bx, motion_by, motion_bx0, motion_by0; |
|
1210 |
+ int motion_dx, motion_dy; |
|
1211 |
+ const int motion_px= s->p_mv_table[mot_xy][0]; |
|
1212 |
+ const int motion_py= s->p_mv_table[mot_xy][1]; |
|
1213 |
+ const int time_pp= s->pp_time; |
|
1214 |
+ const int time_bp= s->bp_time; |
|
1215 |
+ const int time_pb= time_pp - time_bp; |
|
1216 |
+ int bx, by; |
|
1217 |
+ int mx, my, mx2, my2; |
|
1218 |
+ uint8_t *ref_picture= s->me_scratchpad - (mb_x + 1 + (mb_y + 1)*s->linesize)*16; |
|
1219 |
+ int16_t (*mv_table)[2]= s->b_direct_mv_table; |
|
1220 |
+ uint16_t *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame |
|
1221 |
+ |
|
1222 |
+ /* thanks to iso-mpeg the rounding is different for the zero vector, so we need to handle that ... */ |
|
1223 |
+ motion_fx= (motion_px*time_pb)/time_pp; |
|
1224 |
+ motion_fy= (motion_py*time_pb)/time_pp; |
|
1225 |
+ motion_bx0= (-motion_px*time_bp)/time_pp; |
|
1226 |
+ motion_by0= (-motion_py*time_bp)/time_pp; |
|
1227 |
+ motion_dx= motion_dy=0; |
|
1228 |
+ dmin2= check_bidir_mv(s, mb_x, mb_y, |
|
1229 |
+ motion_fx, motion_fy, |
|
1230 |
+ motion_bx0, motion_by0, |
|
1231 |
+ motion_fx, motion_fy, |
|
1232 |
+ motion_bx0, motion_by0) - s->qscale; |
|
1233 |
+ |
|
1234 |
+ motion_bx= motion_fx - motion_px; |
|
1235 |
+ motion_by= motion_fy - motion_py; |
|
1236 |
+ for(by=-1; by<2; by++){ |
|
1237 |
+ for(bx=-1; bx<2; bx++){ |
|
1238 |
+ uint8_t *dest_y = s->me_scratchpad + (by+1)*s->linesize*16 + (bx+1)*16; |
|
1239 |
+ uint8_t *ptr; |
|
1240 |
+ int dxy; |
|
1241 |
+ int src_x, src_y; |
|
1242 |
+ const int width= s->width; |
|
1243 |
+ const int height= s->height; |
|
1244 |
+ |
|
1245 |
+ dxy = ((motion_fy & 1) << 1) | (motion_fx & 1); |
|
1246 |
+ src_x = (mb_x + bx) * 16 + (motion_fx >> 1); |
|
1247 |
+ src_y = (mb_y + by) * 16 + (motion_fy >> 1); |
|
1248 |
+ src_x = clip(src_x, -16, width); |
|
1249 |
+ if (src_x == width) dxy &= ~1; |
|
1250 |
+ src_y = clip(src_y, -16, height); |
|
1251 |
+ if (src_y == height) dxy &= ~2; |
|
1252 |
+ |
|
1253 |
+ ptr = s->last_picture[0] + (src_y * s->linesize) + src_x; |
|
1254 |
+ put_pixels_tab[dxy](dest_y , ptr , s->linesize, 16); |
|
1255 |
+ put_pixels_tab[dxy](dest_y + 8, ptr + 8, s->linesize, 16); |
|
1256 |
+ |
|
1257 |
+ dxy = ((motion_by & 1) << 1) | (motion_bx & 1); |
|
1258 |
+ src_x = (mb_x + bx) * 16 + (motion_bx >> 1); |
|
1259 |
+ src_y = (mb_y + by) * 16 + (motion_by >> 1); |
|
1260 |
+ src_x = clip(src_x, -16, width); |
|
1261 |
+ if (src_x == width) dxy &= ~1; |
|
1262 |
+ src_y = clip(src_y, -16, height); |
|
1263 |
+ if (src_y == height) dxy &= ~2; |
|
1264 |
+ |
|
1265 |
+ avg_pixels_tab[dxy](dest_y , ptr , s->linesize, 16); |
|
1266 |
+ avg_pixels_tab[dxy](dest_y + 8, ptr + 8, s->linesize, 16); |
|
1267 |
+ } |
|
1268 |
+ } |
|
1269 |
+ |
|
1270 |
+ P[0][0] = mv_table[mot_xy ][0]; |
|
1271 |
+ P[0][1] = mv_table[mot_xy ][1]; |
|
1272 |
+ P[1][0] = mv_table[mot_xy - 1][0]; |
|
1273 |
+ P[1][1] = mv_table[mot_xy - 1][1]; |
|
1274 |
+ |
|
1275 |
+ /* special case for first line */ |
|
1276 |
+ if ((mb_y == 0 || s->first_slice_line || s->first_gob_line)) { |
|
1277 |
+ P[4][0] = P[1][0]; |
|
1278 |
+ P[4][1] = P[1][1]; |
|
1279 |
+ } else { |
|
1280 |
+ P[2][0] = mv_table[mot_xy - mot_stride ][0]; |
|
1281 |
+ P[2][1] = mv_table[mot_xy - mot_stride ][1]; |
|
1282 |
+ P[3][0] = mv_table[mot_xy - mot_stride + 1 ][0]; |
|
1283 |
+ P[3][1] = mv_table[mot_xy - mot_stride + 1 ][1]; |
|
1284 |
+ |
|
1285 |
+ P[4][0]= mid_pred(P[1][0], P[2][0], P[3][0]); |
|
1286 |
+ P[4][1]= mid_pred(P[1][1], P[2][1], P[3][1]); |
|
1287 |
+ } |
|
1288 |
+ dmin = epzs_motion_search(s, &mx, &my, P, 0, 0, -16, -16, 15, 15, ref_picture); |
|
1289 |
+ if(mx==0 && my==0) dmin=99999999; // not representable, due to rounding stuff |
|
1290 |
+ if(dmin2<dmin){ |
|
1291 |
+ dmin= dmin2; |
|
1292 |
+ mx=0; |
|
1293 |
+ my=0; |
|
1294 |
+ } |
|
1295 |
+#if 1 |
|
1296 |
+ mx2= mx= mx*2; |
|
1297 |
+ my2= my= my*2; |
|
1298 |
+ for(by=-1; by<2; by++){ |
|
1299 |
+ if(my2+by < -32) continue; |
|
1300 |
+ for(bx=-1; bx<2; bx++){ |
|
1301 |
+ if(bx==0 && by==0) continue; |
|
1302 |
+ if(mx2+bx < -32) continue; |
|
1303 |
+ dmin2= check_bidir_mv(s, mb_x, mb_y, |
|
1304 |
+ mx2+bx+motion_fx, my2+by+motion_fy, |
|
1305 |
+ mx2+bx+motion_bx, my2+by+motion_by, |
|
1306 |
+ mx2+bx+motion_fx, my2+by+motion_fy, |
|
1307 |
+ motion_bx, motion_by) - s->qscale; |
|
1308 |
+ |
|
1309 |
+ if(dmin2<dmin){ |
|
1310 |
+ dmin=dmin2; |
|
1311 |
+ mx= mx2 + bx; |
|
1312 |
+ my= my2 + by; |
|
1313 |
+ } |
|
1314 |
+ } |
|
1315 |
+ } |
|
1316 |
+#else |
|
1317 |
+ mx*=2; my*=2; |
|
1318 |
+#endif |
|
1319 |
+ if(mx==0 && my==0){ |
|
1320 |
+ motion_bx= motion_bx0; |
|
1321 |
+ motion_by= motion_by0; |
|
1322 |
+ } |
|
1323 |
+ |
|
1324 |
+ s->b_direct_mv_table[mot_xy][0]= mx; |
|
1325 |
+ s->b_direct_mv_table[mot_xy][1]= my; |
|
1326 |
+ s->b_direct_forw_mv_table[mot_xy][0]= motion_fx + mx; |
|
1327 |
+ s->b_direct_forw_mv_table[mot_xy][1]= motion_fy + my; |
|
1328 |
+ s->b_direct_back_mv_table[mot_xy][0]= motion_bx + mx; |
|
1329 |
+ s->b_direct_back_mv_table[mot_xy][1]= motion_by + my; |
|
1330 |
+ return dmin; |
|
1139 | 1331 |
} |
1140 | 1332 |
|
1141 | 1333 |
void ff_estimate_b_frame_motion(MpegEncContext * s, |
... | ... |
@@ -1143,16 +1334,41 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, |
1143 | 1143 |
{ |
1144 | 1144 |
const int mot_stride = s->mb_width + 2; |
1145 | 1145 |
const int xy = (mb_y + 1)*mot_stride + mb_x + 1; |
1146 |
+ const int quant= s->qscale; |
|
1147 |
+ int fmin, bmin, dmin, fbmin; |
|
1148 |
+ int type=0; |
|
1149 |
+ int motion_fx, motion_fy, motion_bx, motion_by; |
|
1150 |
+ |
|
1151 |
+ dmin= direct_search(s, mb_x, mb_y); |
|
1146 | 1152 |
|
1147 |
- ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, s->last_picture[0], s->f_code); |
|
1148 |
- ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, s->next_picture[0], s->b_code); |
|
1153 |
+ fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, s->last_picture[0], s->f_code); |
|
1154 |
+ bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, s->next_picture[0], s->b_code) - quant; |
|
1149 | 1155 |
//printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); |
1150 |
- s->b_bidir_forw_mv_table[xy][0]= s->b_forw_mv_table[xy][0]; |
|
1151 |
- s->b_bidir_forw_mv_table[xy][1]= s->b_forw_mv_table[xy][1]; |
|
1152 |
- s->b_bidir_back_mv_table[xy][0]= s->b_back_mv_table[xy][0]; |
|
1153 |
- s->b_bidir_back_mv_table[xy][1]= s->b_back_mv_table[xy][1]; |
|
1154 |
- |
|
1155 |
- s->mb_type[mb_y*s->mb_width + mb_x]= MB_TYPE_FORWARD; //FIXME |
|
1156 |
+ |
|
1157 |
+ fbmin= bidir_refine(s, mb_x, mb_y); |
|
1158 |
+ |
|
1159 |
+ if(s->flags&CODEC_FLAG_HQ){ |
|
1160 |
+ type= MB_TYPE_FORWARD | MB_TYPE_BACKWARD | MB_TYPE_BIDIR | MB_TYPE_DIRECT; |
|
1161 |
+ }else{ |
|
1162 |
+ int score= dmin; |
|
1163 |
+ type=MB_TYPE_DIRECT; |
|
1164 |
+ |
|
1165 |
+ if(fmin<score){ |
|
1166 |
+ score=fmin; |
|
1167 |
+ type= MB_TYPE_FORWARD; |
|
1168 |
+ } |
|
1169 |
+ if(bmin<score){ |
|
1170 |
+ score=bmin; |
|
1171 |
+ type= MB_TYPE_BACKWARD; |
|
1172 |
+ } |
|
1173 |
+ if(fbmin<score){ |
|
1174 |
+ score=fbmin; |
|
1175 |
+ type= MB_TYPE_BIDIR; |
|
1176 |
+ } |
|
1177 |
+ s->mc_mb_var += score; |
|
1178 |
+ } |
|
1179 |
+ |
|
1180 |
+ s->mb_type[mb_y*s->mb_width + mb_x]= type; |
|
1156 | 1181 |
} |
1157 | 1182 |
|
1158 | 1183 |
/* find best f_code for ME which do unlimited searches */ |
... | ... |
@@ -1184,8 +1400,12 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type) |
1184 | 1184 |
} |
1185 | 1185 |
|
1186 | 1186 |
for(i=MAX_FCODE; i>1; i--){ |
1187 |
+ int threshold; |
|
1187 | 1188 |
loose+= mv_num[i]; |
1188 |
- if(loose > s->mb_num/20) break; //FIXME this is pretty ineffective |
|
1189 |
+ |
|
1190 |
+ if(s->pict_type==B_TYPE) threshold= 0; |
|
1191 |
+ else threshold= s->mb_num/20; //FIXME |
|
1192 |
+ if(loose > threshold) break; |
|
1189 | 1193 |
} |
1190 | 1194 |
// printf("fcode: %d type: %d\n", i, s->pict_type); |
1191 | 1195 |
return i; |
... | ... |
@@ -1275,11 +1495,12 @@ void ff_fix_long_b_mvs(MpegEncContext * s, int16_t (*mv_table)[2], int f_code, i |
1275 | 1275 |
|| fcode_tab[mv_table[xy][0] + MAX_MV] == 0 |
1276 | 1276 |
|| fcode_tab[mv_table[xy][1] + MAX_MV] > f_code |
1277 | 1277 |
|| fcode_tab[mv_table[xy][1] + MAX_MV] == 0 ){ |
1278 |
- s->mb_type[i] &= ~type; |
|
1279 |
- if(s->mb_type[i]==0) s->mb_type[i]= MB_TYPE_FORWARD; //FIXME |
|
1280 |
- mv_table[xy][0] = 0; |
|
1281 |
- mv_table[xy][1] = 0; |
|
1282 |
- //this is certainly bad FIXME |
|
1278 |
+ if(s->mb_type[i]&(~type)) s->mb_type[i] &= ~type; |
|
1279 |
+ else{ |
|
1280 |
+ mv_table[xy][0] = 0; |
|
1281 |
+ mv_table[xy][1] = 0; |
|
1282 |
+ //this is certainly bad FIXME |
|
1283 |
+ } |
|
1283 | 1284 |
} |
1284 | 1285 |
} |
1285 | 1286 |
xy++; |
... | ... |
@@ -225,6 +225,12 @@ int MPV_common_init(MpegEncContext *s) |
225 | 225 |
goto fail; |
226 | 226 |
} |
227 | 227 |
|
228 |
+ s->me_scratchpad = av_mallocz( s->linesize*16*3*sizeof(uint8_t)); |
|
229 |
+ if (s->me_scratchpad == NULL) { |
|
230 |
+ perror("malloc"); |
|
231 |
+ goto fail; |
|
232 |
+ } |
|
233 |
+ |
|
228 | 234 |
if(s->max_b_frames){ |
229 | 235 |
for(j=0; j<REORDER_BUFFER_SIZE; j++){ |
230 | 236 |
int i; |
... | ... |
@@ -297,7 +303,7 @@ int MPV_common_init(MpegEncContext *s) |
297 | 297 |
if (!s->mbskip_table) |
298 | 298 |
goto fail; |
299 | 299 |
|
300 |
- s->block= s->intra_block; |
|
300 |
+ s->block= s->blocks[0]; |
|
301 | 301 |
|
302 | 302 |
s->context_initialized = 1; |
303 | 303 |
return 0; |
... | ... |
@@ -333,6 +339,7 @@ void MPV_common_end(MpegEncContext *s) |
333 | 333 |
CHECK_FREE(s->ac_val[0]); |
334 | 334 |
CHECK_FREE(s->coded_block); |
335 | 335 |
CHECK_FREE(s->mbintra_table); |
336 |
+ CHECK_FREE(s->me_scratchpad); |
|
336 | 337 |
|
337 | 338 |
CHECK_FREE(s->mbskip_table); |
338 | 339 |
for(i=0;i<3;i++) { |
... | ... |
@@ -761,16 +768,6 @@ int MPV_encode_picture(AVCodecContext *avctx, |
761 | 761 |
return pbBufPtr(&s->pb) - s->pb.buf; |
762 | 762 |
} |
763 | 763 |
|
764 |
-static inline int clip(int a, int amin, int amax) |
|
765 |
-{ |
|
766 |
- if (a < amin) |
|
767 |
- return amin; |
|
768 |
- else if (a > amax) |
|
769 |
- return amax; |
|
770 |
- else |
|
771 |
- return a; |
|
772 |
-} |
|
773 |
- |
|
774 | 764 |
static inline void gmc1_motion(MpegEncContext *s, |
775 | 765 |
UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr, |
776 | 766 |
int dest_offset, |
... | ... |
@@ -1225,7 +1222,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) |
1225 | 1225 |
if (!s->mb_intra) { |
1226 | 1226 |
/* motion handling */ |
1227 | 1227 |
if((s->flags&CODEC_FLAG_HQ) || (!s->encoding)){ |
1228 |
- if (!s->no_rounding){ |
|
1228 |
+ if ((!s->no_rounding) || s->pict_type==B_TYPE){ |
|
1229 | 1229 |
op_pix = put_pixels_tab; |
1230 | 1230 |
op_qpix= qpel_mc_rnd_tab; |
1231 | 1231 |
}else{ |
... | ... |
@@ -1235,7 +1232,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) |
1235 | 1235 |
|
1236 | 1236 |
if (s->mv_dir & MV_DIR_FORWARD) { |
1237 | 1237 |
MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix); |
1238 |
- if (!s->no_rounding) |
|
1238 |
+ if ((!s->no_rounding) || s->pict_type==B_TYPE) |
|
1239 | 1239 |
op_pix = avg_pixels_tab; |
1240 | 1240 |
else |
1241 | 1241 |
op_pix = avg_no_rnd_pixels_tab; |
... | ... |
@@ -1312,7 +1309,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) |
1312 | 1312 |
dest_cb = s->current_picture[1] + (mb_y * 8 * (s->linesize >> 1)) + mb_x * 8; |
1313 | 1313 |
dest_cr = s->current_picture[2] + (mb_y * 8 * (s->linesize >> 1)) + mb_x * 8; |
1314 | 1314 |
|
1315 |
- if (!s->no_rounding){ |
|
1315 |
+ if ((!s->no_rounding) || s->pict_type==B_TYPE){ |
|
1316 | 1316 |
op_pix = put_pixels_tab; |
1317 | 1317 |
op_qpix= qpel_mc_rnd_tab; |
1318 | 1318 |
}else{ |
... | ... |
@@ -1322,7 +1319,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) |
1322 | 1322 |
|
1323 | 1323 |
if (s->mv_dir & MV_DIR_FORWARD) { |
1324 | 1324 |
MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix); |
1325 |
- if (!s->no_rounding) |
|
1325 |
+ if ((!s->no_rounding) || s->pict_type==B_TYPE) |
|
1326 | 1326 |
op_pix = avg_pixels_tab; |
1327 | 1327 |
else |
1328 | 1328 |
op_pix = avg_no_rnd_pixels_tab; |
... | ... |
@@ -1429,6 +1426,8 @@ static void copy_context_before_encode(MpegEncContext *d, MpegEncContext *s, int |
1429 | 1429 |
d->skip_count= s->skip_count; |
1430 | 1430 |
d->misc_bits= s->misc_bits; |
1431 | 1431 |
d->last_bits= s->last_bits; |
1432 |
+ |
|
1433 |
+ d->mb_skiped= s->mb_skiped; |
|
1432 | 1434 |
} |
1433 | 1435 |
|
1434 | 1436 |
static void copy_context_after_encode(MpegEncContext *d, MpegEncContext *s, int type){ |
... | ... |
@@ -1453,6 +1452,7 @@ static void copy_context_after_encode(MpegEncContext *d, MpegEncContext *s, int |
1453 | 1453 |
d->last_bits= s->last_bits; |
1454 | 1454 |
|
1455 | 1455 |
d->mb_intra= s->mb_intra; |
1456 |
+ d->mb_skiped= s->mb_skiped; |
|
1456 | 1457 |
d->mv_type= s->mv_type; |
1457 | 1458 |
d->mv_dir= s->mv_dir; |
1458 | 1459 |
d->pb= s->pb; |
... | ... |
@@ -1468,7 +1468,7 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
1468 | 1468 |
int i; |
1469 | 1469 |
int bits; |
1470 | 1470 |
MpegEncContext best_s, backup_s; |
1471 |
- UINT8 bit_buf[4][3000]; //FIXME check that this is ALLWAYS large enogh for a MB |
|
1471 |
+ UINT8 bit_buf[7][3000]; //FIXME check that this is ALLWAYS large enogh for a MB |
|
1472 | 1472 |
|
1473 | 1473 |
s->picture_number = picture_number; |
1474 | 1474 |
|
... | ... |
@@ -1483,7 +1483,11 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
1483 | 1483 |
/* Reset the average MB variance */ |
1484 | 1484 |
s->avg_mb_var = 0; |
1485 | 1485 |
s->mc_mb_var = 0; |
1486 |
- |
|
1486 |
+ |
|
1487 |
+ /* we need to initialize some time vars before we can encode b-frames */ |
|
1488 |
+ if (s->h263_pred && !s->h263_msmpeg4) |
|
1489 |
+ ff_set_mpeg4_time(s, s->picture_number); |
|
1490 |
+ |
|
1487 | 1491 |
/* Estimate motion for every MB */ |
1488 | 1492 |
if(s->pict_type != I_TYPE){ |
1489 | 1493 |
// int16_t (*tmp)[2]= s->p_mv_table; |
... | ... |
@@ -1535,9 +1539,11 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
1535 | 1535 |
if(s->pict_type==B_TYPE){ |
1536 | 1536 |
s->f_code= ff_get_best_fcode(s, s->b_forw_mv_table, MB_TYPE_FORWARD); |
1537 | 1537 |
s->b_code= ff_get_best_fcode(s, s->b_back_mv_table, MB_TYPE_BACKWARD); |
1538 |
- //FIXME if BIDIR != for&back |
|
1539 |
- ff_fix_long_b_mvs(s, s->b_forw_mv_table, s->f_code, MB_TYPE_FORWARD |MB_TYPE_BIDIR); |
|
1540 |
- ff_fix_long_b_mvs(s, s->b_back_mv_table, s->b_code, MB_TYPE_BACKWARD|MB_TYPE_BIDIR); |
|
1538 |
+ |
|
1539 |
+ ff_fix_long_b_mvs(s, s->b_forw_mv_table, s->f_code, MB_TYPE_FORWARD); |
|
1540 |
+ ff_fix_long_b_mvs(s, s->b_back_mv_table, s->b_code, MB_TYPE_BACKWARD); |
|
1541 |
+ ff_fix_long_b_mvs(s, s->b_bidir_forw_mv_table, s->f_code, MB_TYPE_BIDIR); |
|
1542 |
+ ff_fix_long_b_mvs(s, s->b_bidir_back_mv_table, s->b_code, MB_TYPE_BIDIR); |
|
1541 | 1543 |
} |
1542 | 1544 |
|
1543 | 1545 |
//printf("f_code %d ///\n", s->f_code); |
... | ... |
@@ -1632,7 +1638,8 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
1632 | 1632 |
s->block_index[4]= s->block_wrap[4]*(mb_y + 1) + s->block_wrap[0]*(s->mb_height*2 + 2); |
1633 | 1633 |
s->block_index[5]= s->block_wrap[4]*(mb_y + 1 + s->mb_height + 2) + s->block_wrap[0]*(s->mb_height*2 + 2); |
1634 | 1634 |
for(mb_x=0; mb_x < s->mb_width; mb_x++) { |
1635 |
- /*const */int mb_type= s->mb_type[mb_y * s->mb_width + mb_x]; |
|
1635 |
+ const int mb_type= s->mb_type[mb_y * s->mb_width + mb_x]; |
|
1636 |
+ const int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1; |
|
1636 | 1637 |
PutBitContext pb; |
1637 | 1638 |
int d; |
1638 | 1639 |
int dmin=10000000; |
... | ... |
@@ -1647,19 +1654,19 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
1647 | 1647 |
s->block_index[4]++; |
1648 | 1648 |
s->block_index[5]++; |
1649 | 1649 |
if(mb_type & (mb_type-1)){ // more than 1 MB type possible |
1650 |
+ int next_block=0; |
|
1650 | 1651 |
pb= s->pb; |
1651 |
- s->mv_dir = MV_DIR_FORWARD; |
|
1652 | 1652 |
|
1653 | 1653 |
copy_context_before_encode(&backup_s, s, -1); |
1654 | 1654 |
|
1655 | 1655 |
if(mb_type&MB_TYPE_INTER){ |
1656 |
- int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1; |
|
1656 |
+ s->mv_dir = MV_DIR_FORWARD; |
|
1657 | 1657 |
s->mv_type = MV_TYPE_16X16; |
1658 | 1658 |
s->mb_intra= 0; |
1659 | 1659 |
s->mv[0][0][0] = s->p_mv_table[xy][0]; |
1660 | 1660 |
s->mv[0][0][1] = s->p_mv_table[xy][1]; |
1661 | 1661 |
init_put_bits(&s->pb, bit_buf[1], 3000, NULL, NULL); |
1662 |
- s->block= s->inter_block; |
|
1662 |
+ s->block= s->blocks[next_block]; |
|
1663 | 1663 |
|
1664 | 1664 |
encode_mb(s, s->mv[0][0][0], s->mv[0][0][1]); |
1665 | 1665 |
d= get_bit_count(&s->pb); |
... | ... |
@@ -1668,10 +1675,12 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
1668 | 1668 |
dmin=d; |
1669 | 1669 |
copy_context_after_encode(&best_s, s, MB_TYPE_INTER); |
1670 | 1670 |
best=1; |
1671 |
+ next_block^=1; |
|
1671 | 1672 |
} |
1672 | 1673 |
} |
1673 | 1674 |
if(mb_type&MB_TYPE_INTER4V){ |
1674 | 1675 |
copy_context_before_encode(s, &backup_s, MB_TYPE_INTER4V); |
1676 |
+ s->mv_dir = MV_DIR_FORWARD; |
|
1675 | 1677 |
s->mv_type = MV_TYPE_8X8; |
1676 | 1678 |
s->mb_intra= 0; |
1677 | 1679 |
for(i=0; i<4; i++){ |
... | ... |
@@ -1679,25 +1688,111 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
1679 | 1679 |
s->mv[0][i][1] = s->motion_val[s->block_index[i]][1]; |
1680 | 1680 |
} |
1681 | 1681 |
init_put_bits(&s->pb, bit_buf[2], 3000, NULL, NULL); |
1682 |
- s->block= s->inter4v_block; |
|
1682 |
+ s->block= s->blocks[next_block]; |
|
1683 | 1683 |
|
1684 | 1684 |
encode_mb(s, 0, 0); |
1685 | 1685 |
d= get_bit_count(&s->pb); |
1686 |
- if(d<dmin && 0){ |
|
1686 |
+ if(d<dmin){ |
|
1687 | 1687 |
flush_put_bits(&s->pb); |
1688 | 1688 |
dmin=d; |
1689 | 1689 |
copy_context_after_encode(&best_s, s, MB_TYPE_INTER4V); |
1690 | 1690 |
best=2; |
1691 |
+ next_block^=1; |
|
1692 |
+ } |
|
1693 |
+ } |
|
1694 |
+ if(mb_type&MB_TYPE_FORWARD){ |
|
1695 |
+ copy_context_before_encode(s, &backup_s, MB_TYPE_FORWARD); |
|
1696 |
+ s->mv_dir = MV_DIR_FORWARD; |
|
1697 |
+ s->mv_type = MV_TYPE_16X16; |
|
1698 |
+ s->mb_intra= 0; |
|
1699 |
+ s->mv[0][0][0] = s->b_forw_mv_table[xy][0]; |
|
1700 |
+ s->mv[0][0][1] = s->b_forw_mv_table[xy][1]; |
|
1701 |
+ init_put_bits(&s->pb, bit_buf[3], 3000, NULL, NULL); |
|
1702 |
+ s->block= s->blocks[next_block]; |
|
1703 |
+ |
|
1704 |
+ encode_mb(s, s->mv[0][0][0], s->mv[0][0][1]); |
|
1705 |
+ d= get_bit_count(&s->pb); |
|
1706 |
+ if(d<dmin){ |
|
1707 |
+ flush_put_bits(&s->pb); |
|
1708 |
+ dmin=d; |
|
1709 |
+ copy_context_after_encode(&best_s, s, MB_TYPE_FORWARD); |
|
1710 |
+ best=3; |
|
1711 |
+ next_block^=1; |
|
1712 |
+ } |
|
1713 |
+ } |
|
1714 |
+ if(mb_type&MB_TYPE_BACKWARD){ |
|
1715 |
+ copy_context_before_encode(s, &backup_s, MB_TYPE_BACKWARD); |
|
1716 |
+ s->mv_dir = MV_DIR_BACKWARD; |
|
1717 |
+ s->mv_type = MV_TYPE_16X16; |
|
1718 |
+ s->mb_intra= 0; |
|
1719 |
+ s->mv[1][0][0] = s->b_back_mv_table[xy][0]; |
|
1720 |
+ s->mv[1][0][1] = s->b_back_mv_table[xy][1]; |
|
1721 |
+ init_put_bits(&s->pb, bit_buf[4], 3000, NULL, NULL); |
|
1722 |
+ s->block= s->blocks[next_block]; |
|
1723 |
+ |
|
1724 |
+ encode_mb(s, s->mv[1][0][0], s->mv[1][0][1]); |
|
1725 |
+ d= get_bit_count(&s->pb); |
|
1726 |
+ if(d<dmin){ |
|
1727 |
+ flush_put_bits(&s->pb); |
|
1728 |
+ dmin=d; |
|
1729 |
+ copy_context_after_encode(&best_s, s, MB_TYPE_BACKWARD); |
|
1730 |
+ best=4; |
|
1731 |
+ next_block^=1; |
|
1732 |
+ } |
|
1733 |
+ } |
|
1734 |
+ if(mb_type&MB_TYPE_BIDIR){ |
|
1735 |
+ copy_context_before_encode(s, &backup_s, MB_TYPE_BIDIR); |
|
1736 |
+ s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; |
|
1737 |
+ s->mv_type = MV_TYPE_16X16; |
|
1738 |
+ s->mb_intra= 0; |
|
1739 |
+ s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0]; |
|
1740 |
+ s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1]; |
|
1741 |
+ s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0]; |
|
1742 |
+ s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1]; |
|
1743 |
+ init_put_bits(&s->pb, bit_buf[5], 3000, NULL, NULL); |
|
1744 |
+ s->block= s->blocks[next_block]; |
|
1745 |
+ |
|
1746 |
+ encode_mb(s, 0, 0); |
|
1747 |
+ d= get_bit_count(&s->pb); |
|
1748 |
+ if(d<dmin){ |
|
1749 |
+ flush_put_bits(&s->pb); |
|
1750 |
+ dmin=d; |
|
1751 |
+ copy_context_after_encode(&best_s, s, MB_TYPE_BIDIR); |
|
1752 |
+ best=5; |
|
1753 |
+ next_block^=1; |
|
1754 |
+ } |
|
1755 |
+ } |
|
1756 |
+ if(mb_type&MB_TYPE_DIRECT){ |
|
1757 |
+ copy_context_before_encode(s, &backup_s, MB_TYPE_DIRECT); |
|
1758 |
+ s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; |
|
1759 |
+ s->mv_type = MV_TYPE_16X16; //FIXME |
|
1760 |
+ s->mb_intra= 0; |
|
1761 |
+ s->mv[0][0][0] = s->b_direct_forw_mv_table[xy][0]; |
|
1762 |
+ s->mv[0][0][1] = s->b_direct_forw_mv_table[xy][1]; |
|
1763 |
+ s->mv[1][0][0] = s->b_direct_back_mv_table[xy][0]; |
|
1764 |
+ s->mv[1][0][1] = s->b_direct_back_mv_table[xy][1]; |
|
1765 |
+ init_put_bits(&s->pb, bit_buf[6], 3000, NULL, NULL); |
|
1766 |
+ s->block= s->blocks[next_block]; |
|
1767 |
+ |
|
1768 |
+ encode_mb(s, s->b_direct_mv_table[xy][0], s->b_direct_mv_table[xy][1]); |
|
1769 |
+ d= get_bit_count(&s->pb); |
|
1770 |
+ if(d<dmin){ |
|
1771 |
+ flush_put_bits(&s->pb); |
|
1772 |
+ dmin=d; |
|
1773 |
+ copy_context_after_encode(&best_s, s, MB_TYPE_DIRECT); |
|
1774 |
+ best=6; |
|
1775 |
+ next_block^=1; |
|
1691 | 1776 |
} |
1692 | 1777 |
} |
1693 | 1778 |
if(mb_type&MB_TYPE_INTRA){ |
1694 | 1779 |
copy_context_before_encode(s, &backup_s, MB_TYPE_INTRA); |
1780 |
+ s->mv_dir = MV_DIR_FORWARD; |
|
1695 | 1781 |
s->mv_type = MV_TYPE_16X16; |
1696 | 1782 |
s->mb_intra= 1; |
1697 | 1783 |
s->mv[0][0][0] = 0; |
1698 | 1784 |
s->mv[0][0][1] = 0; |
1699 | 1785 |
init_put_bits(&s->pb, bit_buf[0], 3000, NULL, NULL); |
1700 |
- s->block= s->intra_block; |
|
1786 |
+ s->block= s->blocks[next_block]; |
|
1701 | 1787 |
|
1702 | 1788 |
encode_mb(s, 0, 0); |
1703 | 1789 |
d= get_bit_count(&s->pb); |
... | ... |
@@ -1706,6 +1801,7 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
1706 | 1706 |
dmin=d; |
1707 | 1707 |
copy_context_after_encode(&best_s, s, MB_TYPE_INTRA); |
1708 | 1708 |
best=0; |
1709 |
+ next_block^=1; |
|
1709 | 1710 |
} |
1710 | 1711 |
/* force cleaning of ac/dc pred stuff if needed ... */ |
1711 | 1712 |
if(s->h263_pred || s->h263_aic) |
... | ... |
@@ -1718,30 +1814,30 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
1718 | 1718 |
int motion_x, motion_y; |
1719 | 1719 |
s->mv_type=MV_TYPE_16X16; |
1720 | 1720 |
// only one MB-Type possible |
1721 |
- //FIXME convert to swicth() |
|
1722 |
- if(mb_type&MB_TYPE_INTRA){ |
|
1721 |
+ switch(mb_type){ |
|
1722 |
+ case MB_TYPE_INTRA: |
|
1723 | 1723 |
s->mv_dir = MV_DIR_FORWARD; |
1724 | 1724 |
s->mb_intra= 1; |
1725 | 1725 |
motion_x= s->mv[0][0][0] = 0; |
1726 | 1726 |
motion_y= s->mv[0][0][1] = 0; |
1727 |
- }else if(mb_type&MB_TYPE_INTER){ |
|
1728 |
- int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1; |
|
1727 |
+ break; |
|
1728 |
+ case MB_TYPE_INTER: |
|
1729 | 1729 |
s->mv_dir = MV_DIR_FORWARD; |
1730 | 1730 |
s->mb_intra= 0; |
1731 | 1731 |
motion_x= s->mv[0][0][0] = s->p_mv_table[xy][0]; |
1732 | 1732 |
motion_y= s->mv[0][0][1] = s->p_mv_table[xy][1]; |
1733 |
- }else if(mb_type&MB_TYPE_DIRECT){ |
|
1734 |
- int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1; |
|
1733 |
+ break; |
|
1734 |
+ case MB_TYPE_DIRECT: |
|
1735 | 1735 |
s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; |
1736 | 1736 |
s->mb_intra= 0; |
1737 |
- motion_x=0; |
|
1738 |
- motion_y=0; |
|
1739 |
- s->mv[0][0][0] = 0; |
|
1740 |
- s->mv[0][0][1] = 0; |
|
1741 |
- s->mv[1][0][0] = 0; |
|
1742 |
- s->mv[1][0][1] = 0; |
|
1743 |
- }else if(mb_type&MB_TYPE_BIDIR){ |
|
1744 |
- int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1; |
|
1737 |
+ motion_x=s->b_direct_mv_table[xy][0]; |
|
1738 |
+ motion_y=s->b_direct_mv_table[xy][1]; |
|
1739 |
+ s->mv[0][0][0] = s->b_direct_forw_mv_table[xy][0]; |
|
1740 |
+ s->mv[0][0][1] = s->b_direct_forw_mv_table[xy][1]; |
|
1741 |
+ s->mv[1][0][0] = s->b_direct_back_mv_table[xy][0]; |
|
1742 |
+ s->mv[1][0][1] = s->b_direct_back_mv_table[xy][1]; |
|
1743 |
+ break; |
|
1744 |
+ case MB_TYPE_BIDIR: |
|
1745 | 1745 |
s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; |
1746 | 1746 |
s->mb_intra= 0; |
1747 | 1747 |
motion_x=0; |
... | ... |
@@ -1750,25 +1846,31 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
1750 | 1750 |
s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1]; |
1751 | 1751 |
s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0]; |
1752 | 1752 |
s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1]; |
1753 |
- }else if(mb_type&MB_TYPE_BACKWARD){ |
|
1754 |
- int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1; |
|
1753 |
+ break; |
|
1754 |
+ case MB_TYPE_BACKWARD: |
|
1755 | 1755 |
s->mv_dir = MV_DIR_BACKWARD; |
1756 | 1756 |
s->mb_intra= 0; |
1757 | 1757 |
motion_x= s->mv[1][0][0] = s->b_back_mv_table[xy][0]; |
1758 | 1758 |
motion_y= s->mv[1][0][1] = s->b_back_mv_table[xy][1]; |
1759 |
- }else if(mb_type&MB_TYPE_FORWARD){ |
|
1760 |
- int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1; |
|
1759 |
+ break; |
|
1760 |
+ case MB_TYPE_FORWARD: |
|
1761 | 1761 |
s->mv_dir = MV_DIR_FORWARD; |
1762 | 1762 |
s->mb_intra= 0; |
1763 | 1763 |
motion_x= s->mv[0][0][0] = s->b_forw_mv_table[xy][0]; |
1764 | 1764 |
motion_y= s->mv[0][0][1] = s->b_forw_mv_table[xy][1]; |
1765 | 1765 |
// printf(" %d %d ", motion_x, motion_y); |
1766 |
- }else{ |
|
1766 |
+ break; |
|
1767 |
+ default: |
|
1767 | 1768 |
motion_x=motion_y=0; //gcc warning fix |
1768 | 1769 |
printf("illegal MB type\n"); |
1769 | 1770 |
} |
1770 | 1771 |
encode_mb(s, motion_x, motion_y); |
1771 | 1772 |
} |
1773 |
+ /* clean the MV table in IPS frames for direct mode in B frames */ |
|
1774 |
+ if(s->mb_intra /* && I,P,S_TYPE */){ |
|
1775 |
+ s->p_mv_table[xy][0]=0; |
|
1776 |
+ s->p_mv_table[xy][1]=0; |
|
1777 |
+ } |
|
1772 | 1778 |
|
1773 | 1779 |
MPV_decode_mb(s, s->block); |
1774 | 1780 |
} |
... | ... |
@@ -141,7 +141,8 @@ typedef struct MpegEncContext { |
141 | 141 |
INT16 (*b_direct_forw_mv_table)[2];/* MV table (1MV per MB) direct mode b-frame encoding */ |
142 | 142 |
INT16 (*b_direct_back_mv_table)[2];/* MV table (1MV per MB) direct mode b-frame encoding */ |
143 | 143 |
INT16 (*b_direct_mv_table)[2]; /* MV table (1MV per MB) direct mode b-frame encoding */ |
144 |
- int me_method; /* ME algorithm */ |
|
144 |
+ int me_method; /* ME algorithm */ |
|
145 |
+ uint8_t *me_scratchpad; /* data area for the me algo, so that the ME doesnt need to malloc/free */ |
|
145 | 146 |
int mv_dir; |
146 | 147 |
#define MV_DIR_BACKWARD 1 |
147 | 148 |
#define MV_DIR_FORWARD 2 |
... | ... |
@@ -164,7 +165,8 @@ typedef struct MpegEncContext { |
164 | 164 |
UINT8 *fcode_tab; /* smallest fcode needed for each MV */ |
165 | 165 |
|
166 | 166 |
int has_b_frames; |
167 |
- int no_rounding; /* apply no rounding to motion compensation (MPEG4, msmpeg4, ...) */ |
|
167 |
+ int no_rounding; /* apply no rounding to motion compensation (MPEG4, msmpeg4, ...) |
|
168 |
+ for b-frames rounding mode is allways 0 */ |
|
168 | 169 |
|
169 | 170 |
/* macroblock layer */ |
170 | 171 |
int mb_x, mb_y; |
... | ... |
@@ -335,9 +337,7 @@ typedef struct MpegEncContext { |
335 | 335 |
UINT32 mb_line_avgsize; |
336 | 336 |
|
337 | 337 |
DCTELEM (*block)[64]; /* points to one of the following blocks */ |
338 |
- DCTELEM intra_block[6][64] __align8; |
|
339 |
- DCTELEM inter_block[6][64] __align8; |
|
340 |
- DCTELEM inter4v_block[6][64] __align8; |
|
338 |
+ DCTELEM blocks[2][6][64] __align8; // for HQ mode we need to keep the best block |
|
341 | 339 |
void (*dct_unquantize_mpeg1)(struct MpegEncContext *s, |
342 | 340 |
DCTELEM *block, int n, int qscale); |
343 | 341 |
void (*dct_unquantize_mpeg2)(struct MpegEncContext *s, |
... | ... |
@@ -421,6 +421,7 @@ INT16 *h263_pred_motion(MpegEncContext * s, int block, |
421 | 421 |
int *px, int *py); |
422 | 422 |
void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, |
423 | 423 |
int dir); |
424 |
+void ff_set_mpeg4_time(MpegEncContext * s, int picture_number); |
|
424 | 425 |
void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number); |
425 | 426 |
void h263_encode_init(MpegEncContext *s); |
426 | 427 |
|