锌是什么颜色| 婚检男性检查什么项目| 大拇指有黑色竖纹是什么原因| 天空又什么又什么| 烂舌头是什么原因| 肠胃炎看什么科| 保胎吃什么药| 肝火旺吃什么水果| 农历六月六是什么节日| 纳豆是什么味道| 水瓶座是什么性格| 什么运动可以让孩子长高| 匹维溴铵片治什么病| 蓝颜知己是什么意思| 水痘长什么样子| 吃深海鱼油有什么好处和坏处| 艾滋有什么症状| 海姆立克急救法是什么| 东莞有什么区| 菌群失调是什么意思| 1987年属什么的| 玫瑰茄和洛神花有什么区别吗| 群众路线是什么| 为什么牙缝里的东西很臭| 隆鼻后吃什么消肿快| 喉咙有浓痰是什么原因| 梅尼埃病是什么病| 知了猴什么时候出来| 高血糖主食吃什么好| 黄河水为什么是黄的| 小拇指有痣代表什么| 清肺热用什么泡水喝比较好| 权志龙为什么叫gd| 清一色是什么意思| 桥本甲状腺炎是什么意思| 鲁班是什么家| 制作人是干什么的| 怀孕后乳房有什么变化| 布朗尼是什么| 苹果和生姜煮水喝有什么功效| 屈原为什么投江| 心电图窦性心律不齐是什么意思| 开光什么意思| 左眼跳什么预兆| 什么情什么意| 外伤用什么消炎药| 野人是什么意思| 甲状腺适合吃什么食物| 尿肌酐低是什么原因| 交替脉见于什么病| 滴水观音叶子发黄是什么原因| 什么时候可以领退休金| 紫河车是什么东西| 什么眼霜去皱效果好| 蔬菜沙拉一般用什么蔬菜| 邹去掉耳朵旁读什么| 畏光是什么意思| 旭日是什么意思| a21和以纯什么关系| 天性使然什么意思| 吃什么能长胖| 风湿和类风湿有什么区别| 血红蛋白偏高说明了什么| 锁骨上的痣代表什么| 醋有什么功效和作用| 梦见很多苍蝇是什么意思| 手术前吃什么补充营养| 中水是什么水| 吃什么下奶最快最多最有效| 眼睛红肿是什么原因引起的| 拆骨肉是什么肉| 1是什么数| 湖南省的简称是什么| 子宫回声欠均匀是什么意思| 太阳里面有什么| 女人多吃什么补黄体酮| 骨钙素低是什么原因| 全组副鼻窦炎什么意思| 藤茶有什么功效| 五月十日是什么星座| 宫颈异常是什么意思| 丙氨酸是什么| 耳浴10分钟什么意思| 人乳头瘤病毒16型阳性是什么意思| 八七年属什么生肖| 生津止渴是什么意思| 1973年是什么命| 鼻子干痒是什么原因| 吃了阿莫西林不能吃什么| 广州有什么特产| 梦见红色的蛇是什么意思| 中央党校什么级别| 局灶是什么意思| 头疼什么原因| 什么叫打板| 喇蛄和小龙虾什么区别| mm是什么意思| 无偿献血有什么待遇| 乳头状瘤是什么病| 贵州的特产是什么| 太安鱼是什么鱼| 盐酸氯米帕明片有什么作用| 菌群异常是什么意思| lamer是什么牌子| 1月28号是什么星座| 骨加客读什么| 反复发烧是什么原因引起的| 火山飘雪是什么菜| 贪污是什么意思| 隐血阴性是什么意思| 腺肌症是什么症状| 淋巴结是什么东西| 神经大条是什么意思| 乙肝表面抗体偏高是什么意思| 隐翅虫怕什么| 肝什么相照| 冲击波治疗有什么效果| 当兵苦到什么程度| 酸奶能做什么美食| 尿常规红细胞高是什么原因| 舌头起泡是什么原因| 不感冒什么意思| 2月23日什么星座| 什么是胎梦| 头晕喝什么饮料| 前轮轴承坏了会有什么症状| 淋巴结发炎吃什么药| 什么地方看到的月亮最大| 头痛吃什么药效果好| 腰椎间盘突吃什么药| 内是什么意思| 小肠换气吃什么药| 胃疼为什么后背也疼| hpv亚临床感染是什么意思| kpi是什么意思啊| 10月什么星座| 女生被操是什么感觉| 产后检查挂什么科| a型rh阳性是什么意思| 喝水都长肉是什么原因| 做眉毛有什么危害| 舅舅是什么关系| 阴帝是什么| 兜兜转转是什么意思| 蒜苔炒什么好吃| 阳光明媚下一句接什么| 中国科协是什么级别| 不让看朋友圈显示什么| 瘦脱相是什么意思| 失眠是什么原因引起的| 08年属什么| 为什么不娶养猫的女人| 球拍状胎盘对胎儿有什么影响| 为什么要打破伤风| 尿道炎吃什么药比较好的快| 眼肿是什么原因| 婴幼儿屁股红擦什么| 乌托邦什么意思| 什么原因导致宫外孕| 强龙不压地头蛇是什么生肖| 预防心肌梗塞吃什么药最好| 脉率是什么| 药流没流干净有什么症状| 喝什么提神| 梦见小白兔是什么意思| 血小板低是什么原因| 为什么叫香港脚| 食用碱是什么| 老人双脚浮肿是什么原因| 隔离霜和粉底液有什么区别| 双子男喜欢什么样的女生| 改户口需要什么手续| 什么降糖药效果最好| 为什么会反胃想吐| 举的部首是什么| ercp是什么检查| 霏字五行属什么| 酊是什么意思| 吃燕麦片有什么好处| 十二月十号是什么星座| 运字是什么结构| 一什么天| 暴毙是什么意思| 什么的变化| 顶臀径是指什么| 一什么地毯| 鲫鱼不能和什么一起吃| 支气管炎什么症状| 梦见西瓜是什么意思| 晨起口干口苦是什么原因| 肌酐低是什么问题| 气阴两虚吃什么中成药| 女人梦见好多蛇是什么预兆| 阿拉伯是什么意思| 什么而不舍| 反应停是什么药| 30岁用什么眼霜比较好| qa和qc有什么区别| 什么是铅| 什么是金砖国家| 崽崽是什么意思| 递增是什么意思| 以梦为马什么意思| 西红柿和什么搭配最好| 副乳挂什么科| 端午是什么时候| 常喝苦荞茶有什么好处| cr是什么意思| 6月17日是什么星座| 腿发软无力是什么原因引起的| 戒指中指代表什么意思| 眼睛闪光是什么症状| 为什么月经会提前来| 契丹族现在是什么族| 松鼠桂鱼是什么鱼| 痛风喝什么茶最好| 520是什么节日| 青光眼是什么原因引起的| 情感是什么意思| 进展是什么意思| 三伏天晒背有什么好处| 上日下立读什么| 回不到我们的从前是什么歌| 膀胱钙化是什么意思| 什么万| 什么不生四字成语| 晦气是什么意思| 灵芝搭配什么煲汤最好| 封闭抗体是什么意思| 爱迪生发明什么| 精液是什么组成的| 手术后吃什么鱼伤口愈合快| 软坚散结是什么意思| 桑枝是什么| 输卵管不通有什么症状| 结晶是什么意思| 心悸心慌吃什么药| 核磁是检查什么的| 拔完智齿吃什么食物好| 天眼是什么意思| 之虞是什么意思| 临床医学是干什么的| 政委是什么级别| 坐小月子可以吃什么水果| 斐乐手表属于什么档次| 刑警队是干什么的| 咳嗽恶心干呕是什么原因引起的| 泰迪吃什么| naomi什么意思| 羊病是什么病| 秦时明月什么时候更新| 菩萨是什么意思| 韭黄炒什么好吃| 任什么任什么| 什么病误诊为帕金森| 搭桥香是什么意思| 类风湿因子高吃什么药| 什么品牌的沙发好| 嘴下面起痘是什么原因| 铁观音属于什么茶| 踏雪寻梅什么意思| 紫苏煮水喝有什么功效| 1998年五行属什么| 遍体鳞伤是什么意思| 百度

南宁晚上有什么好玩的地方


Directory: ../../../ffmpeg/
File: src/libavcodec/mobiclip.c
Date: 2025-08-04 11:35:17
Exec Total Coverage
Lines: 0 675 0.0%
Functions: 0 33 0.0%
Branches: 0 357 0.0%

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

中医为什么下午不把脉 为什么耳屎是湿的 鸡蛋属于什么类食品 红军为什么要长征 lps医学上是什么意思
姝字五行属什么 咽炎咳嗽吃什么 高危妊娠是什么意思啊 新生儿拉肚子是什么原因引起的 血糖和尿糖有什么区别
历久弥新的意思是什么 ada医学上是什么意思 ras医学上是什么意思 为什么夏天越来越热 海鸥吃什么食物
骨密度z值是什么意思 六字真言是什么 什么是幽门螺杆菌感染 2025年属什么生肖 难能可贵是什么意思
心什么胆什么hcv8jop1ns7r.cn 看男性性功能挂什么科hcv7jop6ns2r.cn 梦见小女孩是什么意思hcv9jop1ns0r.cn 什么是逆向思维hcv8jop5ns3r.cn 吃什么解辣hcv8jop0ns0r.cn
bjd娃娃是什么hcv9jop3ns1r.cn 正常小便是什么颜色hcv8jop6ns1r.cn 翡翠属于什么玉beikeqingting.com 四月十五什么星座hcv8jop5ns4r.cn 人老珠黄是什么动物hcv8jop9ns6r.cn
真太阳时是什么意思hcv8jop4ns5r.cn 金砖国家是什么意思hcv8jop9ns6r.cn 中盐是什么盐1949doufunao.com 血脂高适合吃什么食物tiangongnft.com 福寿延绵是什么意思hcv9jop5ns1r.cn
8.23是什么星座hcv8jop5ns1r.cn 蛐蛐是什么意思1949doufunao.com 开黑是什么意思hcv8jop4ns3r.cn 脂溢性脱发是什么原因引起的hcv8jop9ns7r.cn 为什么肚子会胀气hcv7jop6ns5r.cn
百度