Mercurial > libavcodec.hg
comparison h263.c @ 2502:f5fe61bd08ac libavcodec
support skiping some bitstream encoding
author | michael |
---|---|
date | Sun, 06 Feb 2005 17:01:07 +0000 |
parents | 8a30df830ad6 |
children | 5a28a7dd57d7 |
comparison
equal
deleted
inserted
replaced
2501:236562127b89 | 2502:f5fe61bd08ac |
---|---|
67 static int h263_decode_block(MpegEncContext * s, DCTELEM * block, | 67 static int h263_decode_block(MpegEncContext * s, DCTELEM * block, |
68 int n, int coded); | 68 int n, int coded); |
69 static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); | 69 static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); |
70 static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, | 70 static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, |
71 int n, int coded, int intra, int rvlc); | 71 int n, int coded, int intra, int rvlc); |
72 static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, | |
73 uint8_t *scan_table); | |
72 static int h263_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr); | 74 static int h263_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr); |
73 #ifdef CONFIG_ENCODERS | 75 #ifdef CONFIG_ENCODERS |
74 static void mpeg4_encode_visual_object_header(MpegEncContext * s); | 76 static void mpeg4_encode_visual_object_header(MpegEncContext * s); |
75 static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number); | 77 static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number); |
76 #endif //CONFIG_ENCODERS | 78 #endif //CONFIG_ENCODERS |
663 } | 665 } |
664 } | 666 } |
665 | 667 |
666 #ifdef CONFIG_ENCODERS | 668 #ifdef CONFIG_ENCODERS |
667 | 669 |
670 static inline int h263_get_motion_length(MpegEncContext * s, int val, int f_code){ | |
671 int l, bit_size, code; | |
672 | |
673 if (val == 0) { | |
674 return mvtab[0][1]; | |
675 } else { | |
676 bit_size = f_code - 1; | |
677 /* modulo encoding */ | |
678 l= INT_BIT - 6 - bit_size; | |
679 val = (val<<l)>>l; | |
680 val--; | |
681 code = (val >> bit_size) + 1; | |
682 | |
683 return mvtab[code][1] + 1 + bit_size; | |
684 } | |
685 } | |
686 | |
687 static inline void ff_h263_encode_motion_vector(MpegEncContext * s, int x, int y, int f_code){ | |
688 if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){ | |
689 skip_put_bits(&s->pb, | |
690 h263_get_motion_length(s, x, f_code) | |
691 +h263_get_motion_length(s, y, f_code)); | |
692 }else{ | |
693 ff_h263_encode_motion(s, x, f_code); | |
694 ff_h263_encode_motion(s, y, f_code); | |
695 } | |
696 } | |
697 | |
668 static inline int get_p_cbp(MpegEncContext * s, | 698 static inline int get_p_cbp(MpegEncContext * s, |
669 DCTELEM block[6][64], | 699 DCTELEM block[6][64], |
670 int motion_x, int motion_y){ | 700 int motion_x, int motion_y){ |
671 int cbp, i; | 701 int cbp, i; |
672 | 702 |
760 if (s->block_last_index[i] >= 0) | 790 if (s->block_last_index[i] >= 0) |
761 cbp |= 1 << (5 - i); | 791 cbp |= 1 << (5 - i); |
762 } | 792 } |
763 } | 793 } |
764 return cbp; | 794 return cbp; |
795 } | |
796 | |
797 static inline void mpeg4_encode_blocks(MpegEncContext * s, DCTELEM block[6][64], int intra_dc[6], | |
798 uint8_t **scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb){ | |
799 int i; | |
800 | |
801 if(scan_table){ | |
802 if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){ | |
803 for (i = 0; i < 6; i++) { | |
804 skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, intra_dc[i], scan_table[i])); | |
805 } | |
806 }else{ | |
807 /* encode each block */ | |
808 for (i = 0; i < 6; i++) { | |
809 mpeg4_encode_block(s, block[i], i, intra_dc[i], scan_table[i], dc_pb, ac_pb); | |
810 } | |
811 } | |
812 }else{ | |
813 if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){ | |
814 for (i = 0; i < 6; i++) { | |
815 skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, 0, s->intra_scantable.permutated)); | |
816 } | |
817 }else{ | |
818 /* encode each block */ | |
819 for (i = 0; i < 6; i++) { | |
820 mpeg4_encode_block(s, block[i], i, 0, s->intra_scantable.permutated, dc_pb, ac_pb); | |
821 } | |
822 } | |
823 } | |
765 } | 824 } |
766 | 825 |
767 void mpeg4_encode_mb(MpegEncContext * s, | 826 void mpeg4_encode_mb(MpegEncContext * s, |
768 DCTELEM block[6][64], | 827 DCTELEM block[6][64], |
769 int motion_x, int motion_y) | 828 int motion_x, int motion_y) |
850 s->misc_bits+= get_bits_diff(s); | 909 s->misc_bits+= get_bits_diff(s); |
851 } | 910 } |
852 | 911 |
853 if(mb_type == 0){ | 912 if(mb_type == 0){ |
854 assert(s->mv_dir & MV_DIRECT); | 913 assert(s->mv_dir & MV_DIRECT); |
855 ff_h263_encode_motion(s, motion_x, 1); | 914 ff_h263_encode_motion_vector(s, motion_x, motion_y, 1); |
856 ff_h263_encode_motion(s, motion_y, 1); | |
857 s->b_count++; | 915 s->b_count++; |
858 s->f_count++; | 916 s->f_count++; |
859 }else{ | 917 }else{ |
860 assert(mb_type > 0 && mb_type < 4); | 918 assert(mb_type > 0 && mb_type < 4); |
861 if(s->mv_type != MV_TYPE_FIELD){ | 919 if(s->mv_type != MV_TYPE_FIELD){ |
862 if(s->mv_dir & MV_DIR_FORWARD){ | 920 if(s->mv_dir & MV_DIR_FORWARD){ |
863 ff_h263_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); | 921 ff_h263_encode_motion_vector(s, s->mv[0][0][0] - s->last_mv[0][0][0], |
864 ff_h263_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); | 922 s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); |
865 s->last_mv[0][0][0]= s->last_mv[0][1][0]= s->mv[0][0][0]; | 923 s->last_mv[0][0][0]= s->last_mv[0][1][0]= s->mv[0][0][0]; |
866 s->last_mv[0][0][1]= s->last_mv[0][1][1]= s->mv[0][0][1]; | 924 s->last_mv[0][0][1]= s->last_mv[0][1][1]= s->mv[0][0][1]; |
867 s->f_count++; | 925 s->f_count++; |
868 } | 926 } |
869 if(s->mv_dir & MV_DIR_BACKWARD){ | 927 if(s->mv_dir & MV_DIR_BACKWARD){ |
870 ff_h263_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); | 928 ff_h263_encode_motion_vector(s, s->mv[1][0][0] - s->last_mv[1][0][0], |
871 ff_h263_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); | 929 s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); |
872 s->last_mv[1][0][0]= s->last_mv[1][1][0]= s->mv[1][0][0]; | 930 s->last_mv[1][0][0]= s->last_mv[1][1][0]= s->mv[1][0][0]; |
873 s->last_mv[1][0][1]= s->last_mv[1][1][1]= s->mv[1][0][1]; | 931 s->last_mv[1][0][1]= s->last_mv[1][1][1]= s->mv[1][0][1]; |
874 s->b_count++; | 932 s->b_count++; |
875 } | 933 } |
876 }else{ | 934 }else{ |
882 put_bits(&s->pb, 1, s->field_select[1][0]); | 940 put_bits(&s->pb, 1, s->field_select[1][0]); |
883 put_bits(&s->pb, 1, s->field_select[1][1]); | 941 put_bits(&s->pb, 1, s->field_select[1][1]); |
884 } | 942 } |
885 if(s->mv_dir & MV_DIR_FORWARD){ | 943 if(s->mv_dir & MV_DIR_FORWARD){ |
886 for(i=0; i<2; i++){ | 944 for(i=0; i<2; i++){ |
887 ff_h263_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); | 945 ff_h263_encode_motion_vector(s, s->mv[0][i][0] - s->last_mv[0][i][0] , |
888 ff_h263_encode_motion(s, s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code); | 946 s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code); |
889 s->last_mv[0][i][0]= s->mv[0][i][0]; | 947 s->last_mv[0][i][0]= s->mv[0][i][0]; |
890 s->last_mv[0][i][1]= s->mv[0][i][1]*2; | 948 s->last_mv[0][i][1]= s->mv[0][i][1]*2; |
891 } | 949 } |
892 s->f_count++; | 950 s->f_count++; |
893 } | 951 } |
894 if(s->mv_dir & MV_DIR_BACKWARD){ | 952 if(s->mv_dir & MV_DIR_BACKWARD){ |
895 for(i=0; i<2; i++){ | 953 for(i=0; i<2; i++){ |
896 ff_h263_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code); | 954 ff_h263_encode_motion_vector(s, s->mv[1][i][0] - s->last_mv[1][i][0] , |
897 ff_h263_encode_motion(s, s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code); | 955 s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code); |
898 s->last_mv[1][i][0]= s->mv[1][i][0]; | 956 s->last_mv[1][i][0]= s->mv[1][i][0]; |
899 s->last_mv[1][i][1]= s->mv[1][i][1]*2; | 957 s->last_mv[1][i][1]= s->mv[1][i][1]*2; |
900 } | 958 } |
901 s->b_count++; | 959 s->b_count++; |
902 } | 960 } |
905 | 963 |
906 if(interleaved_stats){ | 964 if(interleaved_stats){ |
907 s->mv_bits+= get_bits_diff(s); | 965 s->mv_bits+= get_bits_diff(s); |
908 } | 966 } |
909 | 967 |
910 /* encode each block */ | 968 mpeg4_encode_blocks(s, block, NULL, NULL, NULL, &s->pb); |
911 for (i = 0; i < 6; i++) { | |
912 mpeg4_encode_block(s, block[i], i, 0, s->intra_scantable.permutated, NULL, &s->pb); | |
913 } | |
914 | 969 |
915 if(interleaved_stats){ | 970 if(interleaved_stats){ |
916 s->p_tex_bits+= get_bits_diff(s); | 971 s->p_tex_bits+= get_bits_diff(s); |
917 } | 972 } |
918 | 973 |
992 } | 1047 } |
993 | 1048 |
994 /* motion vectors: 16x16 mode */ | 1049 /* motion vectors: 16x16 mode */ |
995 h263_pred_motion(s, 0, 0, &pred_x, &pred_y); | 1050 h263_pred_motion(s, 0, 0, &pred_x, &pred_y); |
996 | 1051 |
997 ff_h263_encode_motion(s, motion_x - pred_x, s->f_code); | 1052 ff_h263_encode_motion_vector(s, motion_x - pred_x, |
998 ff_h263_encode_motion(s, motion_y - pred_y, s->f_code); | 1053 motion_y - pred_y, s->f_code); |
999 }else if(s->mv_type==MV_TYPE_FIELD){ | 1054 }else if(s->mv_type==MV_TYPE_FIELD){ |
1000 if(s->dquant) cbpc+= 8; | 1055 if(s->dquant) cbpc+= 8; |
1001 put_bits(&s->pb, | 1056 put_bits(&s->pb, |
1002 inter_MCBPC_bits[cbpc], | 1057 inter_MCBPC_bits[cbpc], |
1003 inter_MCBPC_code[cbpc]); | 1058 inter_MCBPC_code[cbpc]); |
1020 pred_y /=2; | 1075 pred_y /=2; |
1021 | 1076 |
1022 put_bits(&s->pb, 1, s->field_select[0][0]); | 1077 put_bits(&s->pb, 1, s->field_select[0][0]); |
1023 put_bits(&s->pb, 1, s->field_select[0][1]); | 1078 put_bits(&s->pb, 1, s->field_select[0][1]); |
1024 | 1079 |
1025 ff_h263_encode_motion(s, s->mv[0][0][0] - pred_x, s->f_code); | 1080 ff_h263_encode_motion_vector(s, s->mv[0][0][0] - pred_x, |
1026 ff_h263_encode_motion(s, s->mv[0][0][1] - pred_y, s->f_code); | 1081 s->mv[0][0][1] - pred_y, s->f_code); |
1027 ff_h263_encode_motion(s, s->mv[0][1][0] - pred_x, s->f_code); | 1082 ff_h263_encode_motion_vector(s, s->mv[0][1][0] - pred_x, |
1028 ff_h263_encode_motion(s, s->mv[0][1][1] - pred_y, s->f_code); | 1083 s->mv[0][1][1] - pred_y, s->f_code); |
1029 }else{ | 1084 }else{ |
1030 assert(s->mv_type==MV_TYPE_8X8); | 1085 assert(s->mv_type==MV_TYPE_8X8); |
1031 put_bits(&s->pb, | 1086 put_bits(&s->pb, |
1032 inter_MCBPC_bits[cbpc+16], | 1087 inter_MCBPC_bits[cbpc+16], |
1033 inter_MCBPC_code[cbpc+16]); | 1088 inter_MCBPC_code[cbpc+16]); |
1044 | 1099 |
1045 for(i=0; i<4; i++){ | 1100 for(i=0; i<4; i++){ |
1046 /* motion vectors: 8x8 mode*/ | 1101 /* motion vectors: 8x8 mode*/ |
1047 h263_pred_motion(s, i, 0, &pred_x, &pred_y); | 1102 h263_pred_motion(s, i, 0, &pred_x, &pred_y); |
1048 | 1103 |
1049 ff_h263_encode_motion(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x, s->f_code); | 1104 ff_h263_encode_motion_vector(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x, |
1050 ff_h263_encode_motion(s, s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code); | 1105 s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code); |
1051 } | 1106 } |
1052 } | 1107 } |
1053 | 1108 |
1054 if(interleaved_stats){ | 1109 if(interleaved_stats){ |
1055 s->mv_bits+= get_bits_diff(s); | 1110 s->mv_bits+= get_bits_diff(s); |
1056 } | 1111 } |
1057 | 1112 |
1058 /* encode each block */ | 1113 mpeg4_encode_blocks(s, block, NULL, NULL, NULL, tex_pb); |
1059 for (i = 0; i < 6; i++) { | |
1060 mpeg4_encode_block(s, block[i], i, 0, s->intra_scantable.permutated, NULL, tex_pb); | |
1061 } | |
1062 | 1114 |
1063 if(interleaved_stats){ | 1115 if(interleaved_stats){ |
1064 s->p_tex_bits+= get_bits_diff(s); | 1116 s->p_tex_bits+= get_bits_diff(s); |
1065 } | 1117 } |
1066 s->f_count++; | 1118 s->f_count++; |
1118 | 1170 |
1119 if(interleaved_stats){ | 1171 if(interleaved_stats){ |
1120 s->misc_bits+= get_bits_diff(s); | 1172 s->misc_bits+= get_bits_diff(s); |
1121 } | 1173 } |
1122 | 1174 |
1123 /* encode each block */ | 1175 mpeg4_encode_blocks(s, block, dc_diff, scan_table, dc_pb, tex_pb); |
1124 for (i = 0; i < 6; i++) { | |
1125 mpeg4_encode_block(s, block[i], i, dc_diff[i], scan_table[i], dc_pb, tex_pb); | |
1126 } | |
1127 | 1176 |
1128 if(interleaved_stats){ | 1177 if(interleaved_stats){ |
1129 s->i_tex_bits+= get_bits_diff(s); | 1178 s->i_tex_bits+= get_bits_diff(s); |
1130 } | 1179 } |
1131 s->i_count++; | 1180 s->i_count++; |
1185 | 1234 |
1186 /* motion vectors: 16x16 mode */ | 1235 /* motion vectors: 16x16 mode */ |
1187 h263_pred_motion(s, 0, 0, &pred_x, &pred_y); | 1236 h263_pred_motion(s, 0, 0, &pred_x, &pred_y); |
1188 | 1237 |
1189 if (!s->umvplus) { | 1238 if (!s->umvplus) { |
1190 ff_h263_encode_motion(s, motion_x - pred_x, 1); | 1239 ff_h263_encode_motion_vector(s, motion_x - pred_x, |
1191 ff_h263_encode_motion(s, motion_y - pred_y, 1); | 1240 motion_y - pred_y, 1); |
1192 } | 1241 } |
1193 else { | 1242 else { |
1194 h263p_encode_umotion(s, motion_x - pred_x); | 1243 h263p_encode_umotion(s, motion_x - pred_x); |
1195 h263p_encode_umotion(s, motion_y - pred_y); | 1244 h263p_encode_umotion(s, motion_y - pred_y); |
1196 if (((motion_x - pred_x) == 1) && ((motion_y - pred_y) == 1)) | 1245 if (((motion_x - pred_x) == 1) && ((motion_y - pred_y) == 1)) |
1214 h263_pred_motion(s, i, 0, &pred_x, &pred_y); | 1263 h263_pred_motion(s, i, 0, &pred_x, &pred_y); |
1215 | 1264 |
1216 motion_x= s->current_picture.motion_val[0][ s->block_index[i] ][0]; | 1265 motion_x= s->current_picture.motion_val[0][ s->block_index[i] ][0]; |
1217 motion_y= s->current_picture.motion_val[0][ s->block_index[i] ][1]; | 1266 motion_y= s->current_picture.motion_val[0][ s->block_index[i] ][1]; |
1218 if (!s->umvplus) { | 1267 if (!s->umvplus) { |
1219 ff_h263_encode_motion(s, motion_x - pred_x, 1); | 1268 ff_h263_encode_motion_vector(s, motion_x - pred_x, |
1220 ff_h263_encode_motion(s, motion_y - pred_y, 1); | 1269 motion_y - pred_y, 1); |
1221 } | 1270 } |
1222 else { | 1271 else { |
1223 h263p_encode_umotion(s, motion_x - pred_x); | 1272 h263p_encode_umotion(s, motion_x - pred_x); |
1224 h263p_encode_umotion(s, motion_y - pred_y); | 1273 h263p_encode_umotion(s, motion_y - pred_y); |
1225 if (((motion_x - pred_x) == 1) && ((motion_y - pred_y) == 1)) | 1274 if (((motion_x - pred_x) == 1) && ((motion_y - pred_y) == 1)) |
1645 put_bits(&s->pb, mvtab[code][1] + 1, (mvtab[code][0] << 1) | sign); | 1694 put_bits(&s->pb, mvtab[code][1] + 1, (mvtab[code][0] << 1) | sign); |
1646 if (bit_size > 0) { | 1695 if (bit_size > 0) { |
1647 put_bits(&s->pb, bit_size, bits); | 1696 put_bits(&s->pb, bit_size, bits); |
1648 } | 1697 } |
1649 } | 1698 } |
1650 | |
1651 } | 1699 } |
1652 | 1700 |
1653 /* Encode MV differences on H.263+ with Unrestricted MV mode */ | 1701 /* Encode MV differences on H.263+ with Unrestricted MV mode */ |
1654 static void h263p_encode_umotion(MpegEncContext * s, int val) | 1702 static void h263p_encode_umotion(MpegEncContext * s, int val) |
1655 { | 1703 { |
2173 }else{ | 2221 }else{ |
2174 s->last_time_base= s->time_base; | 2222 s->last_time_base= s->time_base; |
2175 s->time_base= time_div; | 2223 s->time_base= time_div; |
2176 s->pp_time= s->time - s->last_non_b_time; | 2224 s->pp_time= s->time - s->last_non_b_time; |
2177 s->last_non_b_time= s->time; | 2225 s->last_non_b_time= s->time; |
2178 assert(s->pp_time > 0); | 2226 assert(picture_number==0 || s->pp_time > 0); |
2179 } | 2227 } |
2180 } | 2228 } |
2181 | 2229 |
2182 static void mpeg4_encode_gop_header(MpegEncContext * s){ | 2230 static void mpeg4_encode_gop_header(MpegEncContext * s){ |
2183 int hours, minutes, seconds; | 2231 int hours, minutes, seconds; |
2603 put_bits(&s->pb, size, level); | 2651 put_bits(&s->pb, size, level); |
2604 if (size > 8) | 2652 if (size > 8) |
2605 put_bits(&s->pb, 1, 1); | 2653 put_bits(&s->pb, 1, 1); |
2606 } | 2654 } |
2607 #endif | 2655 #endif |
2656 } | |
2657 | |
2658 static inline int mpeg4_get_dc_length(int level, int n){ | |
2659 if (n < 4) { | |
2660 return uni_DCtab_lum_len[level + 256]; | |
2661 } else { | |
2662 return uni_DCtab_chrom_len[level + 256]; | |
2663 } | |
2608 } | 2664 } |
2609 | 2665 |
2610 /** | 2666 /** |
2611 * encodes a 8x8 block | 2667 * encodes a 8x8 block |
2612 * @param n block index (0-3 are luma, 4-5 are chroma) | 2668 * @param n block index (0-3 are luma, 4-5 are chroma) |
2725 } | 2781 } |
2726 } | 2782 } |
2727 #endif | 2783 #endif |
2728 } | 2784 } |
2729 | 2785 |
2730 static inline int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, | 2786 static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, |
2731 uint8_t *scan_table) | 2787 uint8_t *scan_table) |
2732 { | 2788 { |
2733 int i, last_non_zero; | 2789 int i, last_non_zero; |
2734 const RLTable *rl; | 2790 const RLTable *rl; |
2735 uint8_t *len_tab; | 2791 uint8_t *len_tab; |
2736 const int last_index = s->block_last_index[n]; | 2792 const int last_index = s->block_last_index[n]; |
2737 int len=0; | 2793 int len=0; |
2738 | 2794 |
2739 if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away | 2795 if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away |
2740 /* mpeg4 based DC predictor */ | 2796 /* mpeg4 based DC predictor */ |
2741 //mpeg4_encode_dc(dc_pb, intra_dc, n); //FIXME | 2797 len += mpeg4_get_dc_length(intra_dc, n); |
2742 if(last_index<1) return len; | 2798 if(last_index<1) return len; |
2743 i = 1; | 2799 i = 1; |
2744 rl = &rl_intra; | 2800 rl = &rl_intra; |
2745 len_tab = uni_mpeg4_intra_rl_len; | 2801 len_tab = uni_mpeg4_intra_rl_len; |
2746 } else { | 2802 } else { |