1/* 2 * MobiClip Video decoder 3 * Copyright (c) 2015-2016 Florian Nouwt 4 * Copyright (c) 2017 Adib Surani 5 * Copyright (c) 2020 Paul B Mahol 6 * 7 * This file is part of FFmpeg. 8 * 9 * FFmpeg is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * FFmpeg is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with FFmpeg; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 24#include <inttypes.h> 25 26#include "libavutil/avassert.h" 27#include "libavutil/thread.h" 28 29#include "avcodec.h" 30#include "bytestream.h" 31#include "bswapdsp.h" 32#include "codec_internal.h" 33#include "get_bits.h" 34#include "golomb.h" 35#include "internal.h" 36 37#define MOBI_RL_VLC_BITS 12 38#define MOBI_MV_VLC_BITS 6 39 40static const uint8_t zigzag4x4_tab[] = 41{ 42 0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A, 43 0x0D, 0x0E, 0x0B, 0x0F 44}; 45 46static const uint8_t quant4x4_tab[][16] = 47{ 48 { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 }, 49 { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 }, 50 { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 }, 51 { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 }, 52 { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 }, 53 { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 }, 54}; 55 56static const uint8_t quant8x8_tab[][64] = 57{ 58 { 20, 19, 19, 25, 18, 25, 19, 24, 24, 19, 20, 18, 32, 18, 20, 19, 19, 24, 24, 19, 19, 25, 18, 25, 18, 25, 18, 25, 19, 24, 24, 19, 59 19, 24, 24, 19, 18, 32, 18, 20, 18, 32, 18, 24, 24, 19, 19, 24, 24, 18, 25, 18, 25, 18, 19, 24, 24, 19, 18, 32, 18, 24, 24, 18,}, 60 { 22, 21, 21, 28, 19, 28, 21, 26, 26, 21, 22, 19, 35, 19, 22, 21, 21, 26, 26, 21, 21, 28, 19, 28, 19, 28, 19, 28, 21, 26, 26, 21, 61 21, 26, 26, 21, 19, 35, 19, 22, 19, 35, 19, 26, 26, 21, 21, 26, 26, 19, 28, 19, 28, 19, 21, 26, 26, 21, 19, 35, 19, 26, 26, 19,}, 62 { 26, 24, 24, 33, 23, 33, 24, 31, 31, 24, 26, 23, 42, 23, 26, 24, 24, 31, 31, 24, 24, 33, 23, 33, 23, 33, 23, 33, 24, 31, 31, 24, 63 24, 31, 31, 24, 23, 42, 23, 26, 23, 42, 23, 31, 31, 24, 24, 31, 31, 23, 33, 23, 33, 23, 24, 31, 31, 24, 23, 42, 23, 31, 31, 23,}, 64 { 28, 26, 26, 35, 25, 35, 26, 33, 33, 26, 28, 25, 45, 25, 28, 26, 26, 33, 33, 26, 26, 35, 25, 35, 25, 35, 25, 35, 26, 33, 33, 26, 65 26, 33, 33, 26, 25, 45, 25, 28, 25, 45, 25, 33, 33, 26, 26, 33, 33, 25, 35, 25, 35, 25, 26, 33, 33, 26, 25, 45, 25, 33, 33, 25,}, 66 { 32, 30, 30, 40, 28, 40, 30, 38, 38, 30, 32, 28, 51, 28, 32, 30, 30, 38, 38, 30, 30, 40, 28, 40, 28, 40, 28, 40, 30, 38, 38, 30, 67 30, 38, 38, 30, 28, 51, 28, 32, 28, 51, 28, 38, 38, 30, 30, 38, 38, 28, 40, 28, 40, 28, 30, 38, 38, 30, 28, 51, 28, 38, 38, 28,}, 68 { 36, 34, 34, 46, 32, 46, 34, 43, 43, 34, 36, 32, 58, 32, 36, 34, 34, 43, 43, 34, 34, 46, 32, 46, 32, 46, 32, 46, 34, 43, 43, 34, 69 34, 43, 43, 34, 32, 58, 32, 36, 32, 58, 32, 43, 43, 34, 34, 43, 43, 32, 46, 32, 46, 32, 34, 43, 43, 34, 32, 58, 32, 43, 43, 32,}, 70}; 71 72static const uint8_t block4x4_coefficients_tab[] = 73{ 74 15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6, 75}; 76 77static const uint8_t pframe_block4x4_coefficients_tab[] = 78{ 79 0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6, 80}; 81 82static const uint8_t block8x8_coefficients_tab[] = 83{ 84 0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D, 85 0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B, 86 0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14, 87 0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34, 88 0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C, 89 0x2A, 0x28, 0x29, 0x26, 90}; 91 92static const uint8_t pframe_block8x8_coefficients_tab[] = 93{ 94 0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09, 95 0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20, 96 0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C, 97 0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36 98}; 99 100static const uint8_t run_residue[2][256] = 101{ 102 { 103 12, 6, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 106 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107 1, 27, 11, 7, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 108 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 109 1, 41, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 110 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 111 }, 112 { 113 27, 10, 5, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115 8, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117 1, 15, 10, 8, 4, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 118 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 119 1, 21, 7, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 120 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 121 }, 122}; 123 124static const uint8_t bits0[] = { 125 9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 126 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 127 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 7, 10, 10, 9, 128 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 129 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 130 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 131 6, 6, 6, 6, 6, 6, 5, 5, 5, 4, 2, 3, 4, 4, 132}; 133 134static const uint16_t syms0[] = { 135 0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122, 136 0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301, 137 0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142, 138 0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01, 139 0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21, 140 0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82, 141 0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921, 142 0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161, 143 0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22, 144 0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2, 145}; 146 147static const uint16_t syms1[] = { 148 0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83, 149 0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01, 150 0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21, 151 0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804, 152 0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901, 153 0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861, 154 0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22, 155 0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3, 156}; 157 158static const uint8_t mv_len[16] = 159{ 160 10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6, 161}; 162 163static const uint8_t mv_bits[2][16][10] = 164{ 165 { 166 { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 }, 167 { 2, 3, 4, 4, 3, 4, 4, 2 }, 168 { 3, 4, 4, 2, 4, 4, 3, 2 }, 169 { 1, 3, 4, 5, 5, 3, 3 }, 170 { 2, 4, 4, 3, 3, 4, 4, 2 }, 171 { 2, 3, 4, 4, 4, 4, 3, 2 }, 172 { 2, 3, 4, 4, 4, 4, 3, 2 }, 173 { 2, 2, 3, 4, 5, 5, 2 }, 174 { 2, 3, 4, 4, 3, 4, 4, 2 }, 175 { 2, 4, 4, 3, 4, 4, 3, 2 }, 176 { 2, 3, 3, 5, 5, 4, 3, 2 }, 177 { 2, 3, 4, 4, 3, 3, 2 }, 178 { 1, 4, 4, 3, 3, 4, 4 }, 179 { 2, 3, 4, 4, 3, 3, 2 }, 180 { 2, 3, 4, 4, 3, 3, 2 }, 181 { 3, 3, 2, 2, 3, 3 }, 182 }, 183 { 184 { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 }, 185 { 2, 3, 4, 5, 5, 2, 3, 3 }, 186 { 2, 4, 4, 3, 3, 4, 4, 2 }, 187 { 1, 4, 4, 3, 4, 4, 3 }, 188 { 3, 3, 2, 4, 5, 5, 3, 2 }, 189 { 3, 4, 4, 3, 3, 3, 3, 2 }, 190 { 1, 3, 3, 4, 4, 4, 5, 5 }, 191 { 1, 4, 4, 3, 3, 4, 4 }, 192 { 2, 4, 4, 3, 3, 4, 4, 2 }, 193 { 1, 3, 3, 4, 4, 4, 5, 5 }, 194 { 2, 3, 4, 4, 4, 4, 3, 2 }, 195 { 2, 3, 3, 4, 4, 3, 2 }, 196 { 1, 4, 4, 3, 3, 4, 4 }, 197 { 1, 4, 4, 3, 3, 4, 4 }, 198 { 2, 3, 3, 4, 4, 3, 2 }, 199 { 2, 3, 3, 3, 3, 2 }, 200 } 201}; 202 203static const uint8_t mv_syms[2][16][10] = 204{ 205 { 206 { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 }, 207 { 0, 9, 5, 4, 2, 3, 8, 1 }, 208 { 3, 9, 5, 0, 4, 8, 2, 1 }, 209 { 1, 3, 4, 8, 5, 2, 0 }, 210 { 0, 5, 4, 8, 2, 3, 9, 1 }, 211 { 0, 3, 5, 9, 4, 8, 2, 1 }, 212 { 0, 3, 9, 5, 8, 4, 2, 1 }, 213 { 0, 2, 3, 4, 8, 5, 1 }, 214 { 0, 3, 8, 4, 2, 5, 9, 1 }, 215 { 2, 8, 9, 3, 5, 4, 0, 1 }, 216 { 0, 4, 3, 8, 9, 5, 2, 1 }, 217 { 0, 4, 8, 5, 3, 2, 1 }, 218 { 1, 9, 4, 2, 0, 5, 3 }, 219 { 2, 4, 9, 5, 3, 0, 1 }, 220 { 0, 4, 9, 5, 3, 2, 1 }, 221 { 5, 4, 1, 0, 3, 2 }, 222 }, 223 { 224 { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 }, 225 { 9, 2, 3, 5, 4, 1, 8, 0 }, 226 { 0, 5, 4, 2, 9, 3, 8, 1 }, 227 { 1, 5, 4, 2, 8, 3, 0 }, 228 { 2, 9, 8, 3, 5, 4, 0, 1 }, 229 { 3, 5, 4, 2, 9, 8, 0, 1 }, 230 { 1, 2, 0, 9, 8, 3, 5, 4 }, 231 { 1, 8, 5, 2, 0, 4, 3 }, 232 { 0, 5, 4, 2, 8, 3, 9, 1 }, 233 { 1, 2, 0, 9, 8, 3, 5, 4 }, 234 { 0, 3, 9, 8, 5, 4, 2, 1 }, 235 { 0, 4, 3, 8, 5, 2, 1 }, 236 { 1, 5, 4, 2, 0, 9, 3 }, 237 { 1, 9, 5, 2, 0, 4, 3 }, 238 { 0, 5, 3, 9, 4, 2, 1 }, 239 { 0, 4, 5, 3, 2, 1 }, 240 } 241}; 242 243typedef struct BlockXY { 244 int w, h; 245 int ax, ay; 246 int x, y; 247 int size; 248 uint8_t *block; 249 int linesize; 250} BlockXY; 251 252typedef struct MotionXY { 253 int x, y; 254} MotionXY; 255 256typedef struct MobiClipContext { 257 AVFrame *pic[6]; 258 259 int current_pic; 260 int moflex; 261 int dct_tab_idx; 262 int quantizer; 263 264 GetBitContext gb; 265 266 uint8_t *bitstream; 267 int bitstream_size; 268 269 int qtab[2][64]; 270 uint8_t pre[32]; 271 MotionXY *motion; 272 int motion_size; 273 274 BswapDSPContext bdsp; 275} MobiClipContext; 276 277static VLC rl_vlc[2]; 278static VLC mv_vlc[2][16]; 279 280static av_cold void mobiclip_init_static(void) 281{ 282 INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[0], MOBI_RL_VLC_BITS, 104, 283 bits0, sizeof(*bits0), 284 syms0, sizeof(*syms0), sizeof(*syms0), 285 0, 0, 1 << MOBI_RL_VLC_BITS); 286 INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[1], MOBI_RL_VLC_BITS, 104, 287 bits0, sizeof(*bits0), 288 syms1, sizeof(*syms1), sizeof(*syms1), 289 0, 0, 1 << MOBI_RL_VLC_BITS); 290 for (int i = 0; i < 2; i++) { 291 static VLCElem vlc_buf[2 * 16 << MOBI_MV_VLC_BITS]; 292 for (int j = 0; j < 16; j++) { 293 mv_vlc[i][j].table = &vlc_buf[(16 * i + j) << MOBI_MV_VLC_BITS]; 294 mv_vlc[i][j].table_allocated = 1 << MOBI_MV_VLC_BITS; 295 ff_init_vlc_from_lengths(&mv_vlc[i][j], MOBI_MV_VLC_BITS, mv_len[j], 296 mv_bits[i][j], sizeof(*mv_bits[i][j]), 297 mv_syms[i][j], sizeof(*mv_syms[i][j]), sizeof(*mv_syms[i][j]), 298 0, INIT_VLC_USE_NEW_STATIC, NULL); 299 } 300 } 301} 302 303static av_cold int mobiclip_init(AVCodecContext *avctx) 304{ 305 static AVOnce init_static_once = AV_ONCE_INIT; 306 MobiClipContext *s = avctx->priv_data; 307 308 if (avctx->width & 15 || avctx->height & 15) { 309 av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n"); 310 return AVERROR_INVALIDDATA; 311 } 312 313 ff_bswapdsp_init(&s->bdsp); 314 315 avctx->pix_fmt = AV_PIX_FMT_YUV420P; 316 317 s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY)); 318 if (!s->motion) 319 return AVERROR(ENOMEM); 320 s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY); 321 322 for (int i = 0; i < 6; i++) { 323 s->pic[i] = av_frame_alloc(); 324 if (!s->pic[i]) 325 return AVERROR(ENOMEM); 326 } 327 328 ff_thread_once(&init_static_once, mobiclip_init_static); 329 330 return 0; 331} 332 333static int setup_qtables(AVCodecContext *avctx, int64_t quantizer) 334{ 335 MobiClipContext *s = avctx->priv_data; 336 int qx, qy; 337 338 if (quantizer < 12 || quantizer > 161) 339 return AVERROR_INVALIDDATA; 340 341 s->quantizer = quantizer; 342 343 qx = quantizer % 6; 344 qy = quantizer / 6; 345 346 for (int i = 0; i < 16; i++) 347 s->qtab[0][i] = quant4x4_tab[qx][i] << qy; 348 349 for (int i = 0; i < 64; i++) 350 s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2); 351 352 for (int i = 0; i < 20; i++) 353 s->pre[i] = 9; 354 355 return 0; 356} 357 358static void inverse4(unsigned *rs) 359{ 360 unsigned a = rs[0] + rs[2]; 361 unsigned b = rs[0] - rs[2]; 362 unsigned c = rs[1] + ((int)rs[3] >> 1); 363 unsigned d = ((int)rs[1] >> 1) - rs[3]; 364 365 rs[0] = a + c; 366 rs[1] = b + d; 367 rs[2] = b - d; 368 rs[3] = a - c; 369} 370 371static void idct(int *arr, int size) 372{ 373 int e, f, g, h; 374 unsigned x3, x2, x1, x0; 375 int tmp[4]; 376 377 if (size == 4) { 378 inverse4(arr); 379 return; 380 } 381 382 tmp[0] = arr[0]; 383 tmp[1] = arr[2]; 384 tmp[2] = arr[4]; 385 tmp[3] = arr[6]; 386 387 inverse4(tmp); 388 389 e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1); 390 f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1); 391 g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1); 392 h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1); 393 x3 = (unsigned)g + (h >> 2); 394 x2 = (unsigned)e + (f >> 2); 395 x1 = (e >> 2) - (unsigned)f; 396 x0 = (unsigned)h - (g >> 2); 397 398 arr[0] = tmp[0] + x0; 399 arr[1] = tmp[1] + x1; 400 arr[2] = tmp[2] + x2; 401 arr[3] = tmp[3] + x3; 402 arr[4] = tmp[3] - x3; 403 arr[5] = tmp[2] - x2; 404 arr[6] = tmp[1] - x1; 405 arr[7] = tmp[0] - x0; 406} 407 408static void read_run_encoding(AVCodecContext *avctx, 409 int *last, int *run, int *level) 410{ 411 MobiClipContext *s = avctx->priv_data; 412 GetBitContext *gb = &s->gb; 413 int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx].table, 414 MOBI_RL_VLC_BITS, 1); 415 416 *last = (n >> 11) == 1; 417 *run = (n >> 5) & 0x3F; 418 *level = n & 0x1F; 419} 420 421static int add_coefficients(AVCodecContext *avctx, AVFrame *frame, 422 int bx, int by, int size, int plane) 423{ 424 MobiClipContext *s = avctx->priv_data; 425 GetBitContext *gb = &s->gb; 426 int mat[64] = { 0 }; 427 const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab; 428 const int *qtab = s->qtab[size == 8]; 429 uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx; 430 431 for (int pos = 0; get_bits_left(gb) > 0; pos++) { 432 int qval, last, run, level; 433 434 read_run_encoding(avctx, &last, &run, &level); 435 436 if (level) { 437 if (get_bits1(gb)) 438 level = -level; 439 } else if (!get_bits1(gb)) { 440 read_run_encoding(avctx, &last, &run, &level); 441 level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run]; 442 if (get_bits1(gb)) 443 level = -level; 444 } else if (!get_bits1(gb)) { 445 read_run_encoding(avctx, &last, &run, &level); 446 run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level]; 447 if (get_bits1(gb)) 448 level = -level; 449 } else { 450 last = get_bits1(gb); 451 run = get_bits(gb, 6); 452 level = get_sbits(gb, 12); 453 } 454 455 pos += run; 456 if (pos >= size * size) 457 return AVERROR_INVALIDDATA; 458 qval = qtab[pos]; 459 mat[ztab[pos]] = qval *(unsigned)level; 460 461 if (last) 462 break; 463 } 464 465 mat[0] += 32; 466 for (int y = 0; y < size; y++) 467 idct(&mat[y * size], size); 468 469 for (int y = 0; y < size; y++) { 470 for (int x = y + 1; x < size; x++) { 471 int a = mat[x * size + y]; 472 int b = mat[y * size + x]; 473 474 mat[y * size + x] = a; 475 mat[x * size + y] = b; 476 } 477 478 idct(&mat[y * size], size); 479 for (int x = 0; x < size; x++) 480 dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6)); 481 dst += frame->linesize[plane]; 482 } 483 484 return 0; 485} 486 487static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame, 488 int bx, int by, int size, int plane) 489{ 490 MobiClipContext *s = avctx->priv_data; 491 GetBitContext *gb = &s->gb; 492 int ret, idx = get_ue_golomb_31(gb); 493 494 if (idx == 0) { 495 return add_coefficients(avctx, frame, bx, by, size, plane); 496 } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) { 497 int flags = pframe_block4x4_coefficients_tab[idx]; 498 499 for (int y = by; y < by + 8; y += 4) { 500 for (int x = bx; x < bx + 8; x += 4) { 501 if (flags & 1) { 502 ret = add_coefficients(avctx, frame, x, y, 4, plane); 503 if (ret < 0) 504 return ret; 505 } 506 flags >>= 1; 507 } 508 } 509 return 0; 510 } else { 511 return AVERROR_INVALIDDATA; 512 } 513} 514 515static int adjust(int x, int size) 516{ 517 return size == 16 ? (x + 1) >> 1 : x; 518} 519 520static uint8_t pget(BlockXY b) 521{ 522 BlockXY ret = b; 523 int x, y; 524 525 if (b.x == -1 && b.y >= b.size) { 526 ret.x = -1, ret.y = b.size - 1; 527 } else if (b.x >= -1 && b.y >= -1) { 528 ret.x = b.x, ret.y = b.y; 529 } else if (b.x == -1 && b.y == -2) { 530 ret.x = 0, ret.y = -1; 531 } else if (b.x == -2 && b.y == -1) { 532 ret.x = -1, ret.y = 0; 533 } 534 535 y = av_clip(ret.ay + ret.y, 0, ret.h - 1); 536 x = av_clip(ret.ax + ret.x, 0, ret.w - 1); 537 538 return ret.block[y * ret.linesize + x]; 539} 540 541static uint8_t half(int a, int b) 542{ 543 return ((a + b) + 1) / 2; 544} 545 546static uint8_t half3(int a, int b, int c) 547{ 548 return ((a + b + b + c) * 2 / 4 + 1) / 2; 549} 550 551static uint8_t pick_above(BlockXY bxy) 552{ 553 bxy.y = bxy.y - 1; 554 555 return pget(bxy); 556} 557 558static uint8_t pick_left(BlockXY bxy) 559{ 560 bxy.x = bxy.x - 1; 561 562 return pget(bxy); 563} 564 565static uint8_t half_horz(BlockXY bxy) 566{ 567 BlockXY a = bxy, b = bxy, c = bxy; 568 569 a.x -= 1; 570 c.x += 1; 571 572 return half3(pget(a), pget(b), pget(c)); 573} 574 575static uint8_t half_vert(BlockXY bxy) 576{ 577 BlockXY a = bxy, b = bxy, c = bxy; 578 579 a.y -= 1; 580 c.y += 1; 581 582 return half3(pget(a), pget(b), pget(c)); 583} 584 585static uint8_t pick_4(BlockXY bxy) 586{ 587 int val; 588 589 if ((bxy.x % 2) == 0) { 590 BlockXY ba, bb; 591 int a, b; 592 593 ba = bxy; 594 ba.x = -1; 595 ba.y = bxy.y + bxy.x / 2; 596 a = pget(ba); 597 598 bb = bxy; 599 bb.x = -1; 600 bb.y = bxy.y + bxy.x / 2 + 1; 601 b = pget(bb); 602 603 val = half(a, b); 604 } else { 605 BlockXY ba; 606 607 ba = bxy; 608 ba.x = -1; 609 ba.y = bxy.y + bxy.x / 2 + 1; 610 val = half_vert(ba); 611 } 612 613 return val; 614} 615 616static uint8_t pick_5(BlockXY bxy) 617{ 618 int val; 619 620 if (bxy.x == 0) { 621 BlockXY a = bxy; 622 BlockXY b = bxy; 623 624 a.x = -1; 625 a.y -= 1; 626 627 b.x = -1; 628 629 val = half(pget(a), pget(b)); 630 } else if (bxy.y == 0) { 631 BlockXY a = bxy; 632 633 a.x -= 2; 634 a.y -= 1; 635 636 val = half_horz(a); 637 } else if (bxy.x == 1) { 638 BlockXY a = bxy; 639 640 a.x -= 2; 641 a.y -= 1; 642 643 val = half_vert(a); 644 } else { 645 BlockXY a = bxy; 646 647 a.x -= 2; 648 a.y -= 1; 649 650 val = pget(a); 651 } 652 653 return val; 654} 655 656static uint8_t pick_6(BlockXY bxy) 657{ 658 int val; 659 660 if (bxy.y == 0) { 661 BlockXY a = bxy; 662 BlockXY b = bxy; 663 664 a.x -= 1; 665 a.y = -1; 666 667 b.y = -1; 668 669 val = half(pget(a), pget(b)); 670 } else if (bxy.x == 0) { 671 BlockXY a = bxy; 672 673 a.x -= 1; 674 a.y -= 2; 675 676 val = half_vert(a); 677 } else if (bxy.y == 1) { 678 BlockXY a = bxy; 679 680 a.x -= 1; 681 a.y -= 2; 682 683 val = half_horz(a); 684 } else { 685 BlockXY a = bxy; 686 687 a.x -= 1; 688 a.y -= 2; 689 690 val = pget(a); 691 } 692 693 return val; 694} 695 696static uint8_t pick_7(BlockXY bxy) 697{ 698 int clr, acc1, acc2; 699 BlockXY a = bxy; 700 701 a.x -= 1; 702 a.y -= 1; 703 clr = pget(a); 704 if (bxy.x && bxy.y) 705 return clr; 706 707 if (bxy.x == 0) { 708 a.x = -1; 709 a.y = bxy.y; 710 } else { 711 a.x = bxy.x - 2; 712 a.y = -1; 713 } 714 acc1 = pget(a); 715 716 if (bxy.y == 0) { 717 a.x = bxy.x; 718 a.y = -1; 719 } else { 720 a.x = -1; 721 a.y = bxy.y - 2; 722 } 723 acc2 = pget(a); 724 725 return half3(acc1, clr, acc2); 726} 727 728static uint8_t pick_8(BlockXY bxy) 729{ 730 BlockXY ba = bxy; 731 BlockXY bb = bxy; 732 int val; 733 734 if (bxy.y == 0) { 735 int a, b; 736 737 ba.y = -1; 738 a = pget(ba); 739 740 bb.x += 1; 741 bb.y = -1; 742 743 b = pget(bb); 744 745 val = half(a, b); 746 } else if (bxy.y == 1) { 747 ba.x += 1; 748 ba.y -= 2; 749 750 val = half_horz(ba); 751 } else if (bxy.x < bxy.size - 1) { 752 ba.x += 1; 753 ba.y -= 2; 754 755 val = pget(ba); 756 } else if (bxy.y % 2 == 0) { 757 int a, b; 758 759 ba.x = bxy.y / 2 + bxy.size - 1; 760 ba.y = -1; 761 a = pget(ba); 762 763 bb.x = bxy.y / 2 + bxy.size; 764 bb.y = -1; 765 766 b = pget(bb); 767 768 val = half(a, b); 769 } else { 770 ba.x = bxy.y / 2 + bxy.size; 771 ba.y = -1; 772 773 val = half_horz(ba); 774 } 775 776 return val; 777} 778 779static void block_fill_simple(uint8_t *block, int size, int linesize, int fill) 780{ 781 for (int y = 0; y < size; y++) { 782 memset(block, fill, size); 783 block += linesize; 784 } 785} 786 787static void block_fill(uint8_t *block, int size, int linesize, 788 int w, int h, int ax, int ay, 789 uint8_t (*pick)(BlockXY bxy)) 790{ 791 BlockXY bxy; 792 793 bxy.size = size; 794 bxy.block = block; 795 bxy.linesize = linesize; 796 bxy.w = w; 797 bxy.h = h; 798 bxy.ay = ay; 799 bxy.ax = ax; 800 801 for (int y = 0; y < size; y++) { 802 bxy.y = y; 803 for (int x = 0; x < size; x++) { 804 uint8_t val; 805 806 bxy.x = x; 807 808 val = pick(bxy); 809 810 block[ax + x + (ay + y) * linesize] = val; 811 } 812 } 813} 814 815static int block_sum(const uint8_t *block, int w, int h, int linesize) 816{ 817 int sum = 0; 818 819 for (int y = 0; y < h; y++) { 820 for (int x = 0; x < w; x++) { 821 sum += block[x]; 822 } 823 block += linesize; 824 } 825 826 return sum; 827} 828 829static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay, 830 int pmode, int add_coeffs, int size, int plane) 831{ 832 MobiClipContext *s = avctx->priv_data; 833 GetBitContext *gb = &s->gb; 834 int w = avctx->width >> !!plane, h = avctx->height >> !!plane; 835 int ret = 0; 836 837 switch (pmode) { 838 case 0: 839 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_above); 840 break; 841 case 1: 842 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_left); 843 break; 844 case 2: 845 { 846 int arr1[16]; 847 int arr2[16]; 848 uint8_t *top = frame->data[plane] + FFMAX(ay - 1, 0) * frame->linesize[plane] + ax; 849 uint8_t *left = frame->data[plane] + ay * frame->linesize[plane] + FFMAX(ax - 1, 0); 850 int bottommost = frame->data[plane][(ay + size - 1) * frame->linesize[plane] + FFMAX(ax - 1, 0)]; 851 int rightmost = frame->data[plane][FFMAX(ay - 1, 0) * frame->linesize[plane] + ax + size - 1]; 852 int avg = (bottommost + rightmost + 1) / 2 + 2 * av_clip(get_se_golomb(gb), -(1<<16), 1<<16); 853 int r6 = adjust(avg - bottommost, size); 854 int r9 = adjust(avg - rightmost, size); 855 int shift = adjust(size, size) == 8 ? 3 : 2; 856 uint8_t *block; 857 858 for (int x = 0; x < size; x++) { 859 int val = top[x]; 860 arr1[x] = adjust(((bottommost - val) * (1 << shift)) + r6 * (x + 1), size); 861 } 862 863 for (int y = 0; y < size; y++) { 864 int val = left[y * frame->linesize[plane]]; 865 arr2[y] = adjust(((rightmost - val) * (1 << shift)) + r9 * (y + 1), size); 866 } 867 868 block = frame->data[plane] + ay * frame->linesize[plane] + ax; 869 for (int y = 0; y < size; y++) { 870 for (int x = 0; x < size; x++) { 871 block[x] = (((top[x] + left[0] + ((arr1[x] * (y + 1) + 872 arr2[y] * (x + 1)) >> 2 * shift)) + 1) / 2) & 0xFF; 873 } 874 block += frame->linesize[plane]; 875 left += frame->linesize[plane]; 876 } 877 } 878 break; 879 case 3: 880 { 881 uint8_t fill; 882 883 if (ax == 0 && ay == 0) { 884 fill = 0x80; 885 } else if (ax >= 1 && ay >= 1) { 886 int left = block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1, 887 1, size, frame->linesize[plane]); 888 int top = block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax, 889 size, 1, frame->linesize[plane]); 890 891 fill = ((left + top) * 2 / (2 * size) + 1) / 2; 892 } else if (ax >= 1) { 893 fill = (block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1, 894 1, size, frame->linesize[plane]) * 2 / size + 1) / 2; 895 } else if (ay >= 1) { 896 fill = (block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax, 897 size, 1, frame->linesize[plane]) * 2 / size + 1) / 2; 898 } else { 899 return -1; 900 } 901 902 block_fill_simple(frame->data[plane] + ay * frame->linesize[plane] + ax, 903 size, frame->linesize[plane], fill); 904 } 905 break; 906 case 4: 907 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_4); 908 break; 909 case 5: 910 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_5); 911 break; 912 case 6: 913 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_6); 914 break; 915 case 7: 916 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_7); 917 break; 918 case 8: 919 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_8); 920 break; 921 } 922 923 if (add_coeffs) 924 ret = add_coefficients(avctx, frame, ax, ay, size, plane); 925 926 return ret; 927} 928 929static int get_prediction(AVCodecContext *avctx, int x, int y, int size) 930{ 931 MobiClipContext *s = avctx->priv_data; 932 GetBitContext *gb = &s->gb; 933 int index = (y & 0xC) | (x / 4 % 4); 934 935 uint8_t val = FFMIN(s->pre[index], index % 4 == 0 ? 9 : s->pre[index + 3]); 936 if (val == 9) 937 val = 3; 938 939 if (!get_bits1(gb)) { 940 int x = get_bits(gb, 3); 941 val = x + (x >= val ? 1 : 0); 942 } 943 944 s->pre[index + 4] = val; 945 if (size == 8) 946 s->pre[index + 5] = s->pre[index + 8] = s->pre[index + 9] = val; 947 948 return val; 949} 950 951static int process_block(AVCodecContext *avctx, AVFrame *frame, 952 int x, int y, int pmode, int has_coeffs, int plane) 953{ 954 MobiClipContext *s = avctx->priv_data; 955 GetBitContext *gb = &s->gb; 956 int tmp, ret; 957 958 if (!has_coeffs) { 959 if (pmode < 0) 960 pmode = get_prediction(avctx, x, y, 8); 961 return predict_intra(avctx, frame, x, y, pmode, 0, 8, plane); 962 } 963 964 tmp = get_ue_golomb_31(gb); 965 if ((unsigned)tmp > FF_ARRAY_ELEMS(block4x4_coefficients_tab)) 966 return AVERROR_INVALIDDATA; 967 968 if (tmp == 0) { 969 if (pmode < 0) 970 pmode = get_prediction(avctx, x, y, 8); 971 ret = predict_intra(avctx, frame, x, y, pmode, 1, 8, plane); 972 } else { 973 int flags = block4x4_coefficients_tab[tmp - 1]; 974 975 for (int by = y; by < y + 8; by += 4) { 976 for (int bx = x; bx < x + 8; bx += 4) { 977 int new_pmode = pmode; 978 979 if (new_pmode < 0) 980 new_pmode = get_prediction(avctx, bx, by, 4); 981 ret = predict_intra(avctx, frame, bx, by, new_pmode, flags & 1, 4, plane); 982 if (ret < 0) 983 return ret; 984 flags >>= 1; 985 } 986 } 987 } 988 989 return ret; 990} 991 992static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame, 993 int x, int y, int predict) 994{ 995 MobiClipContext *s = avctx->priv_data; 996 GetBitContext *gb = &s->gb; 997 int flags, pmode_uv, idx = get_ue_golomb(gb); 998 int ret = 0; 999 1000 if (idx < 0 || idx >= FF_ARRAY_ELEMS(block8x8_coefficients_tab)) 1001 return AVERROR_INVALIDDATA; 1002 1003 flags = block8x8_coefficients_tab[idx]; 1004 1005 if (predict) { 1006 ret = process_block(avctx, frame, x, y, -1, flags & 1, 0); 1007 if (ret < 0) 1008 return ret; 1009 flags >>= 1; 1010 ret = process_block(avctx, frame, x + 8, y, -1, flags & 1, 0); 1011 if (ret < 0) 1012 return ret; 1013 flags >>= 1; 1014 ret = process_block(avctx, frame, x, y + 8, -1, flags & 1, 0); 1015 if (ret < 0) 1016 return ret; 1017 flags >>= 1; 1018 ret = process_block(avctx, frame, x + 8, y + 8, -1, flags & 1, 0); 1019 if (ret < 0) 1020 return ret; 1021 flags >>= 1; 1022 } else { 1023 int pmode = get_bits(gb, 3); 1024 1025 if (pmode == 2) { 1026 ret = predict_intra(avctx, frame, x, y, pmode, 0, 16, 0); 1027 if (ret < 0) 1028 return ret; 1029 pmode = 9; 1030 } 1031 1032 ret = process_block(avctx, frame, x, y, pmode, flags & 1, 0); 1033 if (ret < 0) 1034 return ret; 1035 flags >>= 1; 1036 ret = process_block(avctx, frame, x + 8, y, pmode, flags & 1, 0); 1037 if (ret < 0) 1038 return ret; 1039 flags >>= 1; 1040 ret = process_block(avctx, frame, x, y + 8, pmode, flags & 1, 0); 1041 if (ret < 0) 1042 return ret; 1043 flags >>= 1; 1044 ret = process_block(avctx, frame, x + 8, y + 8, pmode, flags & 1, 0); 1045 if (ret < 0) 1046 return ret; 1047 flags >>= 1; 1048 } 1049 1050 pmode_uv = get_bits(gb, 3); 1051 if (pmode_uv == 2) { 1052 ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 1 + !s->moflex); 1053 if (ret < 0) 1054 return ret; 1055 ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 2 - !s->moflex); 1056 if (ret < 0) 1057 return ret; 1058 pmode_uv = 9; 1059 } 1060 1061 ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 1 + !s->moflex); 1062 if (ret < 0) 1063 return ret; 1064 flags >>= 1; 1065 ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 2 - !s->moflex); 1066 if (ret < 0) 1067 return ret; 1068 1069 return 0; 1070} 1071 1072static int get_index(int x) 1073{ 1074 return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0; 1075} 1076 1077static int predict_motion(AVCodecContext *avctx, 1078 int width, int height, int index, 1079 int offsetm, int offsetx, int offsety) 1080{ 1081 MobiClipContext *s = avctx->priv_data; 1082 MotionXY *motion = s->motion; 1083 GetBitContext *gb = &s->gb; 1084 int fheight = avctx->height; 1085 int fwidth = avctx->width; 1086 1087 if (index <= 5) { 1088 int sidx = -FFMAX(1, index) + s->current_pic; 1089 MotionXY mv = s->motion[0]; 1090 1091 if (sidx < 0) 1092 sidx += 6; 1093 1094 if (index > 0) { 1095 mv.x = mv.x + (unsigned)get_se_golomb(gb); 1096 mv.y = mv.y + (unsigned)get_se_golomb(gb); 1097 } 1098 if (mv.x >= INT_MAX || mv.y >= INT_MAX) 1099 return AVERROR_INVALIDDATA; 1100 1101 motion[offsetm].x = mv.x; 1102 motion[offsetm].y = mv.y; 1103 1104 for (int i = 0; i < 3; i++) { 1105 int method, src_linesize, dst_linesize; 1106 uint8_t *src, *dst; 1107 1108 if (i == 1) { 1109 offsetx = offsetx >> 1; 1110 offsety = offsety >> 1; 1111 mv.x = mv.x >> 1; 1112 mv.y = mv.y >> 1; 1113 width = width >> 1; 1114 height = height >> 1; 1115 fwidth = fwidth >> 1; 1116 fheight = fheight >> 1; 1117 } 1118 1119 av_assert0(s->pic[sidx]); 1120 av_assert0(s->pic[s->current_pic]); 1121 av_assert0(s->pic[s->current_pic]->data[i]); 1122 if (!s->pic[sidx]->data[i]) 1123 return AVERROR_INVALIDDATA; 1124 1125 method = (mv.x & 1) | ((mv.y & 1) << 1); 1126 src_linesize = s->pic[sidx]->linesize[i]; 1127 dst_linesize = s->pic[s->current_pic]->linesize[i]; 1128 dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize; 1129 1130 if (offsetx + (mv.x >> 1) < 0 || 1131 offsety + (mv.y >> 1) < 0 || 1132 offsetx + width + (mv.x + 1 >> 1) > fwidth || 1133 offsety + height + (mv.y + 1 >> 1) > fheight) 1134 return AVERROR_INVALIDDATA; 1135 1136 switch (method) { 1137 case 0: 1138 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) + 1139 (offsety + (mv.y >> 1)) * src_linesize; 1140 for (int y = 0; y < height; y++) { 1141 for (int x = 0; x < width; x++) 1142 dst[x] = src[x]; 1143 dst += dst_linesize; 1144 src += src_linesize; 1145 } 1146 break; 1147 case 1: 1148 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) + 1149 (offsety + (mv.y >> 1)) * src_linesize; 1150 for (int y = 0; y < height; y++) { 1151 for (int x = 0; x < width; x++) { 1152 dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1)); 1153 } 1154 1155 dst += dst_linesize; 1156 src += src_linesize; 1157 } 1158 break; 1159 case 2: 1160 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) + 1161 (offsety + (mv.y >> 1)) * src_linesize; 1162 for (int y = 0; y < height; y++) { 1163 for (int x = 0; x < width; x++) { 1164 dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1)); 1165 } 1166 1167 dst += dst_linesize; 1168 src += src_linesize; 1169 } 1170 break; 1171 case 3: 1172 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) + 1173 (offsety + (mv.y >> 1)) * src_linesize; 1174 for (int y = 0; y < height; y++) { 1175 for (int x = 0; x < width; x++) { 1176 dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) + 1177 (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1)); 1178 } 1179 1180 dst += dst_linesize; 1181 src += src_linesize; 1182 } 1183 break; 1184 } 1185 } 1186 } else { 1187 int tidx; 1188 int adjx = index == 8 ? 0 : width / 2; 1189 int adjy = index == 8 ? height / 2 : 0; 1190 1191 width = width - adjx; 1192 height = height - adjy; 1193 tidx = get_index(height) * 4 + get_index(width); 1194 1195 for (int i = 0; i < 2; i++) { 1196 int ret, idx2; 1197 1198 idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx].table, 1199 MOBI_MV_VLC_BITS, 1); 1200 1201 ret = predict_motion(avctx, width, height, idx2, 1202 offsetm, offsetx + i * adjx, offsety + i * adjy); 1203 if (ret < 0) 1204 return ret; 1205 } 1206 } 1207 1208 return 0; 1209} 1210 1211static int mobiclip_decode(AVCodecContext *avctx, AVFrame *rframe, 1212 int *got_frame, AVPacket *pkt) 1213{ 1214 MobiClipContext *s = avctx->priv_data; 1215 GetBitContext *gb = &s->gb; 1216 AVFrame *frame = s->pic[s->current_pic]; 1217 int ret; 1218 1219 av_fast_padded_malloc(&s->bitstream, &s->bitstream_size, 1220 pkt->size); 1221 1222 if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0) 1223 return ret; 1224 1225 s->bdsp.bswap16_buf((uint16_t *)s->bitstream, 1226 (uint16_t *)pkt->data, 1227 (pkt->size + 1) >> 1); 1228 1229 ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2)); 1230 if (ret < 0) 1231 return ret; 1232 1233 if (get_bits1(gb)) { 1234 frame->pict_type = AV_PICTURE_TYPE_I; 1235 frame->key_frame = 1; 1236 s->moflex = get_bits1(gb); 1237 s->dct_tab_idx = get_bits1(gb); 1238 1239 ret = setup_qtables(avctx, get_bits(gb, 6)); 1240 if (ret < 0) 1241 return ret; 1242 1243 for (int y = 0; y < avctx->height; y += 16) { 1244 for (int x = 0; x < avctx->width; x += 16) { 1245 ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb)); 1246 if (ret < 0) 1247 return ret; 1248 } 1249 } 1250 } else { 1251 MotionXY *motion = s->motion; 1252 1253 memset(motion, 0, s->motion_size); 1254 1255 frame->pict_type = AV_PICTURE_TYPE_P; 1256 frame->key_frame = 0; 1257 s->dct_tab_idx = 0; 1258 1259 ret = setup_qtables(avctx, s->quantizer + (int64_t)get_se_golomb(gb)); 1260 if (ret < 0) 1261 return ret; 1262 1263 for (int y = 0; y < avctx->height; y += 16) { 1264 for (int x = 0; x < avctx->width; x += 16) { 1265 int idx; 1266 1267 motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x); 1268 motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y); 1269 motion[x / 16 + 2].x = 0; 1270 motion[x / 16 + 2].y = 0; 1271 1272 idx = get_vlc2(gb, mv_vlc[s->moflex][0].table, 1273 MOBI_MV_VLC_BITS, 1); 1274 1275 if (idx == 6 || idx == 7) { 1276 ret = decode_macroblock(avctx, frame, x, y, idx == 7); 1277 if (ret < 0) 1278 return ret; 1279 } else { 1280 int flags, idx2; 1281 ret = predict_motion(avctx, 16, 16, idx, x / 16 + 2, x, y); 1282 if (ret < 0) 1283 return ret; 1284 idx2 = get_ue_golomb(gb); 1285 if (idx2 >= FF_ARRAY_ELEMS(pframe_block8x8_coefficients_tab)) 1286 return AVERROR_INVALIDDATA; 1287 flags = pframe_block8x8_coefficients_tab[idx2]; 1288 1289 for (int sy = y; sy < y + 16; sy += 8) { 1290 for (int sx = x; sx < x + 16; sx += 8) { 1291 if (flags & 1) 1292 add_pframe_coefficients(avctx, frame, sx, sy, 8, 0); 1293 flags >>= 1; 1294 } 1295 } 1296 1297 if (flags & 1) 1298 add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 1 + !s->moflex); 1299 flags >>= 1; 1300 if (flags & 1) 1301 add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 2 - !s->moflex); 1302 } 1303 } 1304 } 1305 } 1306 1307 if (!s->moflex) 1308 avctx->colorspace = AVCOL_SPC_YCGCO; 1309 1310 s->current_pic = (s->current_pic + 1) % 6; 1311 ret = av_frame_ref(rframe, frame); 1312 if (ret < 0) 1313 return ret; 1314 *got_frame = 1; 1315 1316 return 0; 1317} 1318 1319static void mobiclip_flush(AVCodecContext *avctx) 1320{ 1321 MobiClipContext *s = avctx->priv_data; 1322 1323 for (int i = 0; i < 6; i++) 1324 av_frame_unref(s->pic[i]); 1325} 1326 1327static av_cold int mobiclip_close(AVCodecContext *avctx) 1328{ 1329 MobiClipContext *s = avctx->priv_data; 1330 1331 av_freep(&s->bitstream); 1332 s->bitstream_size = 0; 1333 av_freep(&s->motion); 1334 s->motion_size = 0; 1335 1336 for (int i = 0; i < 6; i++) { 1337 av_frame_free(&s->pic[i]); 1338 } 1339 1340 return 0; 1341} 1342 1343const FFCodec ff_mobiclip_decoder = { 1344 .p.name = "mobiclip", 1345 .p.long_name = NULL_IF_CONFIG_SMALL("MobiClip Video"), 1346 .p.type = AVMEDIA_TYPE_VIDEO, 1347 .p.id = AV_CODEC_ID_MOBICLIP, 1348 .priv_data_size = sizeof(MobiClipContext), 1349 .init = mobiclip_init, 1350 FF_CODEC_DECODE_CB(mobiclip_decode), 1351 .flush = mobiclip_flush, 1352 .close = mobiclip_close, 1353 .p.capabilities = AV_CODEC_CAP_DR1, 1354 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 1355}; 1356