| 1 | /* |
| 2 | * MPEG4 decoder / encoder common code. |
| 3 | * Copyright (c) 2000,2001 Fabrice Bellard |
| 4 | * Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at> |
| 5 | * |
| 6 | * This file is part of FFmpeg. |
| 7 | * |
| 8 | * FFmpeg is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU Lesser General Public |
| 10 | * License as published by the Free Software Foundation; either |
| 11 | * version 2.1 of the License, or (at your option) any later version. |
| 12 | * |
| 13 | * FFmpeg is distributed in the hope that it will be useful, |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 | * Lesser General Public License for more details. |
| 17 | * |
| 18 | * You should have received a copy of the GNU Lesser General Public |
| 19 | * License along with FFmpeg; if not, write to the Free Software |
| 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 21 | */ |
| 22 | |
| 23 | #include "mpegutils.h" |
| 24 | #include "mpegvideo.h" |
| 25 | #include "mpeg4video.h" |
| 26 | #include "mpeg4data.h" |
| 27 | |
| 28 | uint8_t ff_mpeg4_static_rl_table_store[3][2][2 * MAX_RUN + MAX_LEVEL + 3]; |
| 29 | |
| 30 | int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s) |
| 31 | { |
| 32 | switch (s->pict_type) { |
| 33 | case AV_PICTURE_TYPE_I: |
| 34 | return 16; |
| 35 | case AV_PICTURE_TYPE_P: |
| 36 | case AV_PICTURE_TYPE_S: |
| 37 | return s->f_code + 15; |
| 38 | case AV_PICTURE_TYPE_B: |
| 39 | return FFMAX3(s->f_code, s->b_code, 2) + 15; |
| 40 | default: |
| 41 | return -1; |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | void ff_mpeg4_clean_buffers(MpegEncContext *s) |
| 46 | { |
| 47 | int c_wrap, c_xy, l_wrap, l_xy; |
| 48 | |
| 49 | l_wrap = s->b8_stride; |
| 50 | l_xy = (2 * s->mb_y - 1) * l_wrap + s->mb_x * 2 - 1; |
| 51 | c_wrap = s->mb_stride; |
| 52 | c_xy = (s->mb_y - 1) * c_wrap + s->mb_x - 1; |
| 53 | |
| 54 | #if 0 |
| 55 | /* clean DC */ |
| 56 | memsetw(s->dc_val[0] + l_xy, 1024, l_wrap * 2 + 1); |
| 57 | memsetw(s->dc_val[1] + c_xy, 1024, c_wrap + 1); |
| 58 | memsetw(s->dc_val[2] + c_xy, 1024, c_wrap + 1); |
| 59 | #endif |
| 60 | |
| 61 | /* clean AC */ |
| 62 | memset(s->ac_val[0] + l_xy, 0, (l_wrap * 2 + 1) * 16 * sizeof(int16_t)); |
| 63 | memset(s->ac_val[1] + c_xy, 0, (c_wrap + 1) * 16 * sizeof(int16_t)); |
| 64 | memset(s->ac_val[2] + c_xy, 0, (c_wrap + 1) * 16 * sizeof(int16_t)); |
| 65 | |
| 66 | /* clean MV */ |
| 67 | // we can't clear the MVs as they might be needed by a b frame |
| 68 | // memset(s->motion_val + l_xy, 0, (l_wrap * 2 + 1) * 2 * sizeof(int16_t)); |
| 69 | // memset(s->motion_val, 0, 2 * sizeof(int16_t) * (2 + s->mb_width * 2) * |
| 70 | // (2 + s->mb_height * 2)); |
| 71 | s->last_mv[0][0][0] = |
| 72 | s->last_mv[0][0][1] = |
| 73 | s->last_mv[1][0][0] = |
| 74 | s->last_mv[1][0][1] = 0; |
| 75 | } |
| 76 | |
| 77 | #define tab_size ((signed)FF_ARRAY_ELEMS(s->direct_scale_mv[0])) |
| 78 | #define tab_bias (tab_size / 2) |
| 79 | |
| 80 | // used by mpeg4 and rv10 decoder |
| 81 | void ff_mpeg4_init_direct_mv(MpegEncContext *s) |
| 82 | { |
| 83 | int i; |
| 84 | for (i = 0; i < tab_size; i++) { |
| 85 | s->direct_scale_mv[0][i] = (i - tab_bias) * s->pb_time / s->pp_time; |
| 86 | s->direct_scale_mv[1][i] = (i - tab_bias) * (s->pb_time - s->pp_time) / |
| 87 | s->pp_time; |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, |
| 92 | int my, int i) |
| 93 | { |
| 94 | int xy = s->block_index[i]; |
| 95 | uint16_t time_pp = s->pp_time; |
| 96 | uint16_t time_pb = s->pb_time; |
| 97 | int p_mx, p_my; |
| 98 | |
| 99 | p_mx = s->next_picture.motion_val[0][xy][0]; |
| 100 | if ((unsigned)(p_mx + tab_bias) < tab_size) { |
| 101 | s->mv[0][i][0] = s->direct_scale_mv[0][p_mx + tab_bias] + mx; |
| 102 | s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx |
| 103 | : s->direct_scale_mv[1][p_mx + tab_bias]; |
| 104 | } else { |
| 105 | s->mv[0][i][0] = p_mx * time_pb / time_pp + mx; |
| 106 | s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx |
| 107 | : p_mx * (time_pb - time_pp) / time_pp; |
| 108 | } |
| 109 | p_my = s->next_picture.motion_val[0][xy][1]; |
| 110 | if ((unsigned)(p_my + tab_bias) < tab_size) { |
| 111 | s->mv[0][i][1] = s->direct_scale_mv[0][p_my + tab_bias] + my; |
| 112 | s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my |
| 113 | : s->direct_scale_mv[1][p_my + tab_bias]; |
| 114 | } else { |
| 115 | s->mv[0][i][1] = p_my * time_pb / time_pp + my; |
| 116 | s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my |
| 117 | : p_my * (time_pb - time_pp) / time_pp; |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | #undef tab_size |
| 122 | #undef tab_bias |
| 123 | |
| 124 | /** |
| 125 | * @return the mb_type |
| 126 | */ |
| 127 | int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my) |
| 128 | { |
| 129 | const int mb_index = s->mb_x + s->mb_y * s->mb_stride; |
| 130 | const int colocated_mb_type = s->next_picture.mb_type[mb_index]; |
| 131 | uint16_t time_pp; |
| 132 | uint16_t time_pb; |
| 133 | int i; |
| 134 | |
| 135 | // FIXME avoid divides |
| 136 | // try special case with shifts for 1 and 3 B-frames? |
| 137 | |
| 138 | if (IS_8X8(colocated_mb_type)) { |
| 139 | s->mv_type = MV_TYPE_8X8; |
| 140 | for (i = 0; i < 4; i++) |
| 141 | ff_mpeg4_set_one_direct_mv(s, mx, my, i); |
| 142 | return MB_TYPE_DIRECT2 | MB_TYPE_8x8 | MB_TYPE_L0L1; |
| 143 | } else if (IS_INTERLACED(colocated_mb_type)) { |
| 144 | s->mv_type = MV_TYPE_FIELD; |
| 145 | for (i = 0; i < 2; i++) { |
| 146 | int field_select = s->next_picture.ref_index[0][4 * mb_index + 2 * i]; |
| 147 | s->field_select[0][i] = field_select; |
| 148 | s->field_select[1][i] = i; |
| 149 | if (s->top_field_first) { |
| 150 | time_pp = s->pp_field_time - field_select + i; |
| 151 | time_pb = s->pb_field_time - field_select + i; |
| 152 | } else { |
| 153 | time_pp = s->pp_field_time + field_select - i; |
| 154 | time_pb = s->pb_field_time + field_select - i; |
| 155 | } |
| 156 | s->mv[0][i][0] = s->p_field_mv_table[i][0][mb_index][0] * |
| 157 | time_pb / time_pp + mx; |
| 158 | s->mv[0][i][1] = s->p_field_mv_table[i][0][mb_index][1] * |
| 159 | time_pb / time_pp + my; |
| 160 | s->mv[1][i][0] = mx ? s->mv[0][i][0] - |
| 161 | s->p_field_mv_table[i][0][mb_index][0] |
| 162 | : s->p_field_mv_table[i][0][mb_index][0] * |
| 163 | (time_pb - time_pp) / time_pp; |
| 164 | s->mv[1][i][1] = my ? s->mv[0][i][1] - |
| 165 | s->p_field_mv_table[i][0][mb_index][1] |
| 166 | : s->p_field_mv_table[i][0][mb_index][1] * |
| 167 | (time_pb - time_pp) / time_pp; |
| 168 | } |
| 169 | return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | |
| 170 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED; |
| 171 | } else { |
| 172 | ff_mpeg4_set_one_direct_mv(s, mx, my, 0); |
| 173 | s->mv[0][1][0] = |
| 174 | s->mv[0][2][0] = |
| 175 | s->mv[0][3][0] = s->mv[0][0][0]; |
| 176 | s->mv[0][1][1] = |
| 177 | s->mv[0][2][1] = |
| 178 | s->mv[0][3][1] = s->mv[0][0][1]; |
| 179 | s->mv[1][1][0] = |
| 180 | s->mv[1][2][0] = |
| 181 | s->mv[1][3][0] = s->mv[1][0][0]; |
| 182 | s->mv[1][1][1] = |
| 183 | s->mv[1][2][1] = |
| 184 | s->mv[1][3][1] = s->mv[1][0][1]; |
| 185 | if ((s->avctx->workaround_bugs & FF_BUG_DIRECT_BLOCKSIZE) || |
| 186 | !s->quarter_sample) |
| 187 | s->mv_type = MV_TYPE_16X16; |
| 188 | else |
| 189 | s->mv_type = MV_TYPE_8X8; |
| 190 | // Note see prev line |
| 191 | return MB_TYPE_DIRECT2 | MB_TYPE_16x16 | MB_TYPE_L0L1; |
| 192 | } |
| 193 | } |