Mercurial > libavcodec.hg
annotate ffv1.c @ 12373:935c524d304b libavcodec
Add a CONFIG_ variable for generic Huffman routines.
author | diego |
---|---|
date | Fri, 06 Aug 2010 10:29:14 +0000 |
parents | 3dbbf18d4905 |
children |
rev | line source |
---|---|
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1 /* |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
2 * FFV1 codec for libavcodec |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
3 * |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
4 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
5 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
6 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
7 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
8 * FFmpeg is free software; you can redistribute it and/or |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
9 * modify it under the terms of the GNU Lesser General Public |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
10 * License as published by the Free Software Foundation; either |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
11 * version 2.1 of the License, or (at your option) any later version. |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
12 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
13 * FFmpeg is distributed in the hope that it will be useful, |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
16 * Lesser General Public License for more details. |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
17 * |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
18 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
19 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
21 */ |
2967 | 22 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
23 /** |
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
11572
diff
changeset
|
24 * @file |
11527 | 25 * FF Video Codec 1 (a lossless codec) |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
26 */ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
27 |
4962
f99e40a7155b
Remove redundant #inclusion of common.h, avcodec.h already #includes it.
diego
parents:
4494
diff
changeset
|
28 #include "avcodec.h" |
9428 | 29 #include "get_bits.h" |
9411
4cb7c65fc775
Split bitstream.h, put the bitstream writer stuff in the new file
stefano
parents:
9355
diff
changeset
|
30 #include "put_bits.h" |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
31 #include "dsputil.h" |
2338 | 32 #include "rangecoder.h" |
1306 | 33 #include "golomb.h" |
8627
d6bab465b82c
moves mid_pred() into mathops.h (with arch specific code split by directory)
aurel
parents:
8590
diff
changeset
|
34 #include "mathops.h" |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
35 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
36 #define MAX_PLANES 4 |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
37 #define CONTEXT_SIZE 32 |
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
38 |
7146
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
39 extern const uint8_t ff_log2_run[32]; |
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
40 |
1306 | 41 static const int8_t quant3[256]={ |
42 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
43 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
44 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
45 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
46 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
47 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
48 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
49 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1306 | 50 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, |
51 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
52 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
53 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
54 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
55 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
56 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
57 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, | |
58 }; | |
9548 | 59 |
60 static const int8_t quant5_10bit[256]={ | |
61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, | |
62 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
63 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
64 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
65 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
66 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
67 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
68 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
69 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
70 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
71 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
72 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
73 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1, | |
74 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
75 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
76 -1,-1,-1,-1,-1,-1,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0, | |
77 }; | |
78 | |
1306 | 79 static const int8_t quant5[256]={ |
80 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
81 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
1306 | 82 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
83 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
84 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
85 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
86 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
87 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
88 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
89 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
90 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
91 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
92 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
93 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
94 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
95 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1, | |
96 }; | |
97 static const int8_t quant7[256]={ | |
98 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
99 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
100 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, | |
101 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
102 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
103 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
104 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
105 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
106 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, | |
107 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, | |
108 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, | |
109 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, | |
110 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, | |
111 -3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2, | |
112 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
113 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1, | |
114 }; | |
115 static const int8_t quant9[256]={ | |
116 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
117 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
118 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
119 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
120 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
121 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
122 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
123 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
124 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
125 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
126 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
127 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
128 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
129 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
130 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3, | |
131 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1, | |
132 }; | |
9548 | 133 static const int8_t quant9_10bit[256]={ |
134 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, | |
135 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, | |
136 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
137 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, | |
138 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
139 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
140 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
141 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
142 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
143 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
144 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
145 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
146 -4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-3, | |
147 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, | |
148 -3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
149 -2,-2,-2,-2,-1,-1,-1,-1,-1,-1,-1,-1,-0,-0,-0,-0, | |
150 }; | |
151 | |
1306 | 152 static const int8_t quant11[256]={ |
153 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, | |
154 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
155 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
156 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
157 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
158 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
159 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
160 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
161 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
162 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
163 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
164 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
165 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
166 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-4,-4, | |
167 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
168 -4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-1, | |
169 }; | |
170 static const int8_t quant13[256]={ | |
171 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, | |
172 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
173 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
174 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | |
175 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | |
176 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | |
177 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | |
178 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | |
179 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6, | |
180 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6, | |
181 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6, | |
182 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6, | |
183 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-5, | |
184 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
185 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
186 -4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-2,-2,-1, | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
187 }; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
188 |
11572 | 189 static const uint8_t ver2_state[256]= { |
190 0, 10, 10, 10, 10, 16, 16, 16, 28, 16, 16, 29, 42, 49, 20, 49, | |
191 59, 25, 26, 26, 27, 31, 33, 33, 33, 34, 34, 37, 67, 38, 39, 39, | |
192 40, 40, 41, 79, 43, 44, 45, 45, 48, 48, 64, 50, 51, 52, 88, 52, | |
193 53, 74, 55, 57, 58, 58, 74, 60, 101, 61, 62, 84, 66, 66, 68, 69, | |
194 87, 82, 71, 97, 73, 73, 82, 75, 111, 77, 94, 78, 87, 81, 83, 97, | |
195 85, 83, 94, 86, 99, 89, 90, 99, 111, 92, 93, 134, 95, 98, 105, 98, | |
196 105, 110, 102, 108, 102, 118, 103, 106, 106, 113, 109, 112, 114, 112, 116, 125, | |
197 115, 116, 117, 117, 126, 119, 125, 121, 121, 123, 145, 124, 126, 131, 127, 129, | |
198 165, 130, 132, 138, 133, 135, 145, 136, 137, 139, 146, 141, 143, 142, 144, 148, | |
199 147, 155, 151, 149, 151, 150, 152, 157, 153, 154, 156, 168, 158, 162, 161, 160, | |
200 172, 163, 169, 164, 166, 184, 167, 170, 177, 174, 171, 173, 182, 176, 180, 178, | |
201 175, 189, 179, 181, 186, 183, 192, 185, 200, 187, 191, 188, 190, 197, 193, 196, | |
202 197, 194, 195, 196, 198, 202, 199, 201, 210, 203, 207, 204, 205, 206, 208, 214, | |
203 209, 211, 221, 212, 213, 215, 224, 216, 217, 218, 219, 220, 222, 228, 223, 225, | |
204 226, 224, 227, 229, 240, 230, 231, 232, 233, 234, 235, 236, 238, 239, 237, 242, | |
205 241, 243, 242, 244, 245, 246, 247, 248, 249, 250, 251, 252, 252, 253, 254, 255, | |
206 }; | |
207 | |
1306 | 208 typedef struct VlcState{ |
209 int16_t drift; | |
210 uint16_t error_sum; | |
211 int8_t bias; | |
212 uint8_t count; | |
213 } VlcState; | |
214 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
215 typedef struct PlaneContext{ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
216 int context_count; |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
217 uint8_t (*state)[CONTEXT_SIZE]; |
1306 | 218 VlcState *vlc_state; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
219 uint8_t interlace_bit_state[2]; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
220 } PlaneContext; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
221 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
222 typedef struct FFV1Context{ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
223 AVCodecContext *avctx; |
2338 | 224 RangeCoder c; |
1306 | 225 GetBitContext gb; |
226 PutBitContext pb; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
227 int version; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
228 int width, height; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
229 int chroma_h_shift, chroma_v_shift; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
230 int flags; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
231 int picture_number; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
232 AVFrame picture; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
233 int plane_count; |
10098
fef90da31453
Fix comments after switching from CABAC to range coder in r3658.
cehoyos
parents:
10048
diff
changeset
|
234 int ac; ///< 1=range coder <-> 0=golomb rice |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
235 PlaneContext plane[MAX_PLANES]; |
1306 | 236 int16_t quant_table[5][256]; |
11572 | 237 uint8_t state_transition[256]; |
1593 | 238 int run_index; |
239 int colorspace; | |
11965 | 240 int_fast16_t *sample_buffer; |
2967 | 241 |
242 DSPContext dsp; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
243 }FFV1Context; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
244 |
4283
d6f83e2f8804
rename always_inline to av_always_inline and move to common.h
mru
parents:
4001
diff
changeset
|
245 static av_always_inline int fold(int diff, int bits){ |
1593 | 246 if(bits==8) |
247 diff= (int8_t)diff; | |
248 else{ | |
249 diff+= 1<<(bits-1); | |
250 diff&=(1<<bits)-1; | |
251 diff-= 1<<(bits-1); | |
252 } | |
253 | |
254 return diff; | |
255 } | |
256 | |
257 static inline int predict(int_fast16_t *src, int_fast16_t *last){ | |
1306 | 258 const int LT= last[-1]; |
259 const int T= last[ 0]; | |
260 const int L = src[-1]; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
261 |
1360 | 262 return mid_pred(L, L + T - LT, T); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
263 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
264 |
1593 | 265 static inline int get_context(FFV1Context *f, int_fast16_t *src, int_fast16_t *last, int_fast16_t *last2){ |
1306 | 266 const int LT= last[-1]; |
267 const int T= last[ 0]; | |
268 const int RT= last[ 1]; | |
269 const int L = src[-1]; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
270 |
1306 | 271 if(f->quant_table[3][127]){ |
272 const int TT= last2[0]; | |
273 const int LL= src[-2]; | |
274 return f->quant_table[0][(L-LT) & 0xFF] + f->quant_table[1][(LT-T) & 0xFF] + f->quant_table[2][(T-RT) & 0xFF] | |
275 +f->quant_table[3][(LL-L) & 0xFF] + f->quant_table[4][(TT-T) & 0xFF]; | |
276 }else | |
277 return f->quant_table[0][(L-LT) & 0xFF] + f->quant_table[1][(LT-T) & 0xFF] + f->quant_table[2][(T-RT) & 0xFF]; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
278 } |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
279 |
9547
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
280 static inline void put_symbol_inline(RangeCoder *c, uint8_t *state, int v, int is_signed){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
281 int i; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
282 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
283 if(v){ |
4001 | 284 const int a= FFABS(v); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
285 const int e= av_log2(a); |
2338 | 286 put_rac(c, state+0, 0); |
9548 | 287 if(e<=9){ |
9552 | 288 for(i=0; i<e; i++){ |
289 put_rac(c, state+1+i, 1); //1..10 | |
290 } | |
291 put_rac(c, state+1+i, 0); | |
2339 | 292 |
9552 | 293 for(i=e-1; i>=0; i--){ |
294 put_rac(c, state+22+i, (a>>i)&1); //22..31 | |
295 } | |
1336
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
296 |
9552 | 297 if(is_signed) |
298 put_rac(c, state+11 + e, v < 0); //11..21 | |
9548 | 299 }else{ |
300 for(i=0; i<e; i++){ | |
301 put_rac(c, state+1+FFMIN(i,9), 1); //1..10 | |
302 } | |
303 put_rac(c, state+1+9, 0); | |
304 | |
305 for(i=e-1; i>=0; i--){ | |
306 put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31 | |
307 } | |
308 | |
309 if(is_signed) | |
310 put_rac(c, state+11 + 10, v < 0); //11..21 | |
311 } | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
312 }else{ |
2338 | 313 put_rac(c, state+0, 1); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
314 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
315 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
316 |
9547
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
317 static void av_noinline put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){ |
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
318 put_symbol_inline(c, state, v, is_signed); |
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
319 } |
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
320 |
9548 | 321 static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state, int is_signed){ |
2338 | 322 if(get_rac(c, state+0)) |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
323 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
324 else{ |
2339 | 325 int i, e, a; |
326 e= 0; | |
9548 | 327 while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10 |
2339 | 328 e++; |
329 } | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
330 |
2339 | 331 a= 1; |
332 for(i=e-1; i>=0; i--){ | |
9548 | 333 a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31 |
2339 | 334 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
335 |
9548 | 336 e= -(is_signed && get_rac(c, state+11 + FFMIN(e, 10))); //11..21 |
9546 | 337 return (a^e)-e; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
338 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
339 } |
1306 | 340 |
9547
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
341 static int av_noinline get_symbol(RangeCoder *c, uint8_t *state, int is_signed){ |
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
342 return get_symbol_inline(c, state, is_signed); |
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
343 } |
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
344 |
1306 | 345 static inline void update_vlc_state(VlcState * const state, const int v){ |
346 int drift= state->drift; | |
347 int count= state->count; | |
4001 | 348 state->error_sum += FFABS(v); |
1306 | 349 drift += v; |
350 | |
351 if(count == 128){ //FIXME variable | |
352 count >>= 1; | |
353 drift >>= 1; | |
354 state->error_sum >>= 1; | |
355 } | |
356 count++; | |
357 | |
358 if(drift <= -count){ | |
359 if(state->bias > -128) state->bias--; | |
2967 | 360 |
1306 | 361 drift += count; |
362 if(drift <= -count) | |
363 drift= -count + 1; | |
364 }else if(drift > 0){ | |
365 if(state->bias < 127) state->bias++; | |
2967 | 366 |
1306 | 367 drift -= count; |
2967 | 368 if(drift > 0) |
1306 | 369 drift= 0; |
370 } | |
371 | |
372 state->drift= drift; | |
373 state->count= count; | |
374 } | |
375 | |
1593 | 376 static inline void put_vlc_symbol(PutBitContext *pb, VlcState * const state, int v, int bits){ |
1306 | 377 int i, k, code; |
378 //printf("final: %d ", v); | |
1593 | 379 v = fold(v - state->bias, bits); |
380 | |
1306 | 381 i= state->count; |
382 k=0; | |
383 while(i < state->error_sum){ //FIXME optimize | |
384 k++; | |
385 i += i; | |
386 } | |
1361
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
387 |
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
388 assert(k<=8); |
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
389 |
1306 | 390 #if 0 // JPEG LS |
391 if(k==0 && 2*state->drift <= - state->count) code= v ^ (-1); | |
392 else code= v; | |
393 #else | |
394 code= v ^ ((2*state->drift + state->count)>>31); | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
395 #endif |
2967 | 396 |
1306 | 397 //printf("v:%d/%d bias:%d error:%d drift:%d count:%d k:%d\n", v, code, state->bias, state->error_sum, state->drift, state->count, k); |
2220 | 398 set_sr_golomb(pb, code, k, 12, bits); |
1306 | 399 |
400 update_vlc_state(state, v); | |
401 } | |
402 | |
1593 | 403 static inline int get_vlc_symbol(GetBitContext *gb, VlcState * const state, int bits){ |
1306 | 404 int k, i, v, ret; |
405 | |
406 i= state->count; | |
407 k=0; | |
408 while(i < state->error_sum){ //FIXME optimize | |
409 k++; | |
410 i += i; | |
411 } | |
1361
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
412 |
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
413 assert(k<=8); |
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
414 |
2220 | 415 v= get_sr_golomb(gb, k, 12, bits); |
1306 | 416 //printf("v:%d bias:%d error:%d drift:%d count:%d k:%d", v, state->bias, state->error_sum, state->drift, state->count, k); |
1361
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
417 |
1306 | 418 #if 0 // JPEG LS |
419 if(k==0 && 2*state->drift <= - state->count) v ^= (-1); | |
420 #else | |
421 v ^= ((2*state->drift + state->count)>>31); | |
422 #endif | |
423 | |
1593 | 424 ret= fold(v + state->bias, bits); |
2967 | 425 |
1306 | 426 update_vlc_state(state, v); |
427 //printf("final: %d\n", ret); | |
428 return ret; | |
429 } | |
430 | |
8590 | 431 #if CONFIG_FFV1_ENCODER |
2422 | 432 static inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
433 PlaneContext * const p= &s->plane[plane_index]; |
2338 | 434 RangeCoder * const c= &s->c; |
1593 | 435 int x; |
436 int run_index= s->run_index; | |
437 int run_count=0; | |
438 int run_mode=0; | |
439 | |
2422 | 440 if(s->ac){ |
441 if(c->bytestream_end - c->bytestream < w*20){ | |
442 av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); | |
443 return -1; | |
444 } | |
445 }else{ | |
446 if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < w*4){ | |
447 av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); | |
448 return -1; | |
449 } | |
450 } | |
451 | |
1593 | 452 for(x=0; x<w; x++){ |
453 int diff, context; | |
2967 | 454 |
1999 | 455 context= get_context(s, sample[0]+x, sample[1]+x, sample[2]+x); |
456 diff= sample[0][x] - predict(sample[0]+x, sample[1]+x); | |
1593 | 457 |
458 if(context < 0){ | |
459 context = -context; | |
460 diff= -diff; | |
461 } | |
462 | |
463 diff= fold(diff, bits); | |
2967 | 464 |
1593 | 465 if(s->ac){ |
9547
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
466 put_symbol_inline(c, p->state[context], diff, 1); |
1593 | 467 }else{ |
468 if(context == 0) run_mode=1; | |
2967 | 469 |
1593 | 470 if(run_mode){ |
471 | |
472 if(diff){ | |
7146
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
473 while(run_count >= 1<<ff_log2_run[run_index]){ |
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
474 run_count -= 1<<ff_log2_run[run_index]; |
1593 | 475 run_index++; |
476 put_bits(&s->pb, 1, 1); | |
477 } | |
2967 | 478 |
7146
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
479 put_bits(&s->pb, 1 + ff_log2_run[run_index], run_count); |
1593 | 480 if(run_index) run_index--; |
481 run_count=0; | |
482 run_mode=0; | |
483 if(diff>0) diff--; | |
484 }else{ | |
485 run_count++; | |
486 } | |
487 } | |
2967 | 488 |
1786 | 489 // printf("count:%d index:%d, mode:%d, x:%d y:%d pos:%d\n", run_count, run_index, run_mode, x, y, (int)put_bits_count(&s->pb)); |
1593 | 490 |
491 if(run_mode == 0) | |
492 put_vlc_symbol(&s->pb, &p->vlc_state[context], diff, bits); | |
493 } | |
494 } | |
495 if(run_mode){ | |
7146
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
496 while(run_count >= 1<<ff_log2_run[run_index]){ |
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
497 run_count -= 1<<ff_log2_run[run_index]; |
1593 | 498 run_index++; |
499 put_bits(&s->pb, 1, 1); | |
500 } | |
501 | |
502 if(run_count) | |
503 put_bits(&s->pb, 1, 1); | |
504 } | |
505 s->run_index= run_index; | |
2967 | 506 |
2422 | 507 return 0; |
1593 | 508 } |
509 | |
510 static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ | |
1999 | 511 int x,y,i; |
2162 | 512 const int ring_size= s->avctx->context_model ? 3 : 2; |
11965 | 513 int_fast16_t *sample[3]; |
1593 | 514 s->run_index=0; |
2967 | 515 |
11965 | 516 memset(s->sample_buffer, 0, ring_size*(w+6)*sizeof(*s->sample_buffer)); |
2967 | 517 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
518 for(y=0; y<h; y++){ |
1999 | 519 for(i=0; i<ring_size; i++) |
11965 | 520 sample[i]= s->sample_buffer + (w+6)*((h+i-y)%ring_size) + 3; |
2967 | 521 |
1999 | 522 sample[0][-1]= sample[1][0 ]; |
523 sample[1][ w]= sample[1][w-1]; | |
1593 | 524 //{START_TIMER |
9548 | 525 if(s->avctx->bits_per_raw_sample<=8){ |
9552 | 526 for(x=0; x<w; x++){ |
527 sample[0][x]= src[x + stride*y]; | |
528 } | |
529 encode_line(s, w, sample, plane_index, 8); | |
9548 | 530 }else{ |
531 for(x=0; x<w; x++){ | |
532 sample[0][x]= ((uint16_t*)(src + stride*y))[x] >> (16 - s->avctx->bits_per_raw_sample); | |
533 } | |
534 encode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); | |
535 } | |
1593 | 536 //STOP_TIMER("encode line")} |
537 } | |
538 } | |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
539 |
1593 | 540 static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ |
1999 | 541 int x, y, p, i; |
2162 | 542 const int ring_size= s->avctx->context_model ? 3 : 2; |
11965 | 543 int_fast16_t *sample[3][3]; |
1593 | 544 s->run_index=0; |
2967 | 545 |
11965 | 546 memset(s->sample_buffer, 0, ring_size*3*(w+6)*sizeof(*s->sample_buffer)); |
2967 | 547 |
1593 | 548 for(y=0; y<h; y++){ |
1999 | 549 for(i=0; i<ring_size; i++) |
550 for(p=0; p<3; p++) | |
11965 | 551 sample[p][i]= s->sample_buffer + p*ring_size*(w+6) + ((h+i-y)%ring_size)*(w+6) + 3; |
1999 | 552 |
1593 | 553 for(x=0; x<w; x++){ |
554 int v= src[x + stride*y]; | |
555 int b= v&0xFF; | |
556 int g= (v>>8)&0xFF; | |
557 int r= (v>>16)&0xFF; | |
2967 | 558 |
1593 | 559 b -= g; |
560 r -= g; | |
561 g += (b + r)>>2; | |
562 b += 0x100; | |
563 r += 0x100; | |
2967 | 564 |
1593 | 565 // assert(g>=0 && b>=0 && r>=0); |
566 // assert(g<256 && b<512 && r<512); | |
567 sample[0][0][x]= g; | |
568 sample[1][0][x]= b; | |
569 sample[2][0][x]= r; | |
570 } | |
571 for(p=0; p<3; p++){ | |
1999 | 572 sample[p][0][-1]= sample[p][1][0 ]; |
573 sample[p][1][ w]= sample[p][1][w-1]; | |
1593 | 574 encode_line(s, w, sample[p], FFMIN(p, 1), 9); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
575 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
576 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
577 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
578 |
2338 | 579 static void write_quant_table(RangeCoder *c, int16_t *quant_table){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
580 int last=0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
581 int i; |
2338 | 582 uint8_t state[CONTEXT_SIZE]; |
583 memset(state, 128, sizeof(state)); | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
584 |
1306 | 585 for(i=1; i<128 ; i++){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
586 if(quant_table[i] != quant_table[i-1]){ |
2339 | 587 put_symbol(c, state, i-last-1, 0); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
588 last= i; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
589 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
590 } |
2339 | 591 put_symbol(c, state, i-last-1, 0); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
592 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
593 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
594 static void write_header(FFV1Context *f){ |
2338 | 595 uint8_t state[CONTEXT_SIZE]; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
596 int i; |
2338 | 597 RangeCoder * const c= &f->c; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
598 |
2338 | 599 memset(state, 128, sizeof(state)); |
2967 | 600 |
2339 | 601 put_symbol(c, state, f->version, 0); |
11572 | 602 put_symbol(c, state, f->ac, 0); |
603 if(f->ac>1){ | |
604 for(i=1; i<256; i++){ | |
605 f->state_transition[i]=ver2_state[i]; | |
606 put_symbol(c, state, ver2_state[i] - c->one_state[i], 1); | |
607 } | |
608 } | |
2967 | 609 put_symbol(c, state, f->colorspace, 0); //YUV cs type |
9548 | 610 if(f->version>0) |
611 put_symbol(c, state, f->avctx->bits_per_raw_sample, 0); | |
2338 | 612 put_rac(c, state, 1); //chroma planes |
2339 | 613 put_symbol(c, state, f->chroma_h_shift, 0); |
614 put_symbol(c, state, f->chroma_v_shift, 0); | |
2338 | 615 put_rac(c, state, 0); //no transparency plane |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
616 |
1306 | 617 for(i=0; i<5; i++) |
618 write_quant_table(c, f->quant_table[i]); | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
619 } |
7782
6efb15a24e91
Replace generic CONFIG_ENCODERS preprocessor conditionals by more specific
diego
parents:
7146
diff
changeset
|
620 #endif /* CONFIG_FFV1_ENCODER */ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
621 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6234
diff
changeset
|
622 static av_cold int common_init(AVCodecContext *avctx){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
623 FFV1Context *s = avctx->priv_data; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
624 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
625 s->avctx= avctx; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
626 s->flags= avctx->flags; |
2967 | 627 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
628 dsputil_init(&s->dsp, avctx); |
2967 | 629 |
9468
71608a4f9eb7
Remove 2 unneeded variables from common_init() found by CSA.
michael
parents:
9428
diff
changeset
|
630 s->width = avctx->width; |
71608a4f9eb7
Remove 2 unneeded variables from common_init() found by CSA.
michael
parents:
9428
diff
changeset
|
631 s->height= avctx->height; |
2967 | 632 |
9468
71608a4f9eb7
Remove 2 unneeded variables from common_init() found by CSA.
michael
parents:
9428
diff
changeset
|
633 assert(s->width && s->height); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
634 |
11965 | 635 s->sample_buffer = av_malloc(6 * (s->width+6) * sizeof(*s->sample_buffer)); |
636 if (!s->sample_buffer) | |
637 return AVERROR(ENOMEM); | |
638 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
639 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
640 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
641 |
8590 | 642 #if CONFIG_FFV1_ENCODER |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6234
diff
changeset
|
643 static av_cold int encode_init(AVCodecContext *avctx) |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
644 { |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
645 FFV1Context *s = avctx->priv_data; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
646 int i; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
647 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
648 common_init(avctx); |
2967 | 649 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
650 s->version=0; |
11572 | 651 s->ac= avctx->coder_type ? 2:0; |
2967 | 652 |
1345
daf951f32697
merge U and V statistics, 33% reduction in memory requirement, compression rate better for some files worse for others, worst compression rate loss 0.05%
michaelni
parents:
1337
diff
changeset
|
653 s->plane_count=2; |
1306 | 654 for(i=0; i<256; i++){ |
9548 | 655 if(avctx->bits_per_raw_sample <=8){ |
9552 | 656 s->quant_table[0][i]= quant11[i]; |
657 s->quant_table[1][i]= 11*quant11[i]; | |
658 if(avctx->context_model==0){ | |
659 s->quant_table[2][i]= 11*11*quant11[i]; | |
660 s->quant_table[3][i]= | |
661 s->quant_table[4][i]=0; | |
662 }else{ | |
663 s->quant_table[2][i]= 11*11*quant5 [i]; | |
664 s->quant_table[3][i]= 5*11*11*quant5 [i]; | |
665 s->quant_table[4][i]= 5*5*11*11*quant5 [i]; | |
666 } | |
9548 | 667 }else{ |
668 s->quant_table[0][i]= quant9_10bit[i]; | |
669 s->quant_table[1][i]= 11*quant9_10bit[i]; | |
670 if(avctx->context_model==0){ | |
671 s->quant_table[2][i]= 11*11*quant9_10bit[i]; | |
672 s->quant_table[3][i]= | |
673 s->quant_table[4][i]=0; | |
674 }else{ | |
675 s->quant_table[2][i]= 11*11*quant5_10bit[i]; | |
676 s->quant_table[3][i]= 5*11*11*quant5_10bit[i]; | |
677 s->quant_table[4][i]= 5*5*11*11*quant5_10bit[i]; | |
678 } | |
679 } | |
1306 | 680 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
681 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
682 for(i=0; i<s->plane_count; i++){ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
683 PlaneContext * const p= &s->plane[i]; |
2967 | 684 |
1306 | 685 if(avctx->context_model==0){ |
686 p->context_count= (11*11*11+1)/2; | |
2967 | 687 }else{ |
1306 | 688 p->context_count= (11*11*5*5*5+1)/2; |
689 } | |
690 | |
691 if(s->ac){ | |
692 if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t)); | |
693 }else{ | |
694 if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState)); | |
695 } | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
696 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
697 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
698 avctx->coded_frame= &s->picture; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
699 switch(avctx->pix_fmt){ |
9548 | 700 case PIX_FMT_YUV444P16: |
701 case PIX_FMT_YUV422P16: | |
702 case PIX_FMT_YUV420P16: | |
703 if(avctx->bits_per_raw_sample <=8){ | |
10048 | 704 av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample invalid\n"); |
9548 | 705 return -1; |
706 } | |
11530
86e4be64519e
Disallow VLC coding with more than 8 bits as there are several bugs
michael
parents:
11529
diff
changeset
|
707 if(!s->ac){ |
86e4be64519e
Disallow VLC coding with more than 8 bits as there are several bugs
michael
parents:
11529
diff
changeset
|
708 av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample of more than 8 needs -coder 1 currently\n"); |
86e4be64519e
Disallow VLC coding with more than 8 bits as there are several bugs
michael
parents:
11529
diff
changeset
|
709 return -1; |
86e4be64519e
Disallow VLC coding with more than 8 bits as there are several bugs
michael
parents:
11529
diff
changeset
|
710 } |
9548 | 711 s->version= 1; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
712 case PIX_FMT_YUV444P: |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
713 case PIX_FMT_YUV422P: |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
714 case PIX_FMT_YUV420P: |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
715 case PIX_FMT_YUV411P: |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
716 case PIX_FMT_YUV410P: |
1593 | 717 s->colorspace= 0; |
718 break; | |
4494
ce643a22f049
Replace deprecated PIX_FMT names by the newer variants.
diego
parents:
4283
diff
changeset
|
719 case PIX_FMT_RGB32: |
1593 | 720 s->colorspace= 1; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
721 break; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
722 default: |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
723 av_log(avctx, AV_LOG_ERROR, "format not supported\n"); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
724 return -1; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
725 } |
1593 | 726 avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); |
727 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
728 s->picture_number=0; |
2967 | 729 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
730 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
731 } |
7782
6efb15a24e91
Replace generic CONFIG_ENCODERS preprocessor conditionals by more specific
diego
parents:
7146
diff
changeset
|
732 #endif /* CONFIG_FFV1_ENCODER */ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
733 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
734 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
735 static void clear_state(FFV1Context *f){ |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
736 int i, j; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
737 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
738 for(i=0; i<f->plane_count; i++){ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
739 PlaneContext *p= &f->plane[i]; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
740 |
2338 | 741 p->interlace_bit_state[0]= 128; |
742 p->interlace_bit_state[1]= 128; | |
2967 | 743 |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
744 for(j=0; j<p->context_count; j++){ |
1306 | 745 if(f->ac){ |
2338 | 746 memset(p->state[j], 128, sizeof(uint8_t)*CONTEXT_SIZE); |
1306 | 747 }else{ |
748 p->vlc_state[j].drift= 0; | |
749 p->vlc_state[j].error_sum= 4; //FFMAX((RANGE + 32)/64, 2); | |
750 p->vlc_state[j].bias= 0; | |
751 p->vlc_state[j].count= 1; | |
752 } | |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
753 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
754 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
755 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
756 |
8590 | 757 #if CONFIG_FFV1_ENCODER |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
758 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
759 FFV1Context *f = avctx->priv_data; |
2338 | 760 RangeCoder * const c= &f->c; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
761 AVFrame *pict = data; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
762 const int width= f->width; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
763 const int height= f->height; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
764 AVFrame * const p= &f->picture; |
1306 | 765 int used_count= 0; |
2338 | 766 uint8_t keystate=128; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
767 |
2338 | 768 ff_init_range_encoder(c, buf, buf_size); |
769 ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); | |
770 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
771 *p = *pict; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
772 p->pict_type= FF_I_TYPE; |
2967 | 773 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
774 if(avctx->gop_size==0 || f->picture_number % avctx->gop_size == 0){ |
2338 | 775 put_rac(c, &keystate, 1); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
776 p->key_frame= 1; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
777 write_header(f); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
778 clear_state(f); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
779 }else{ |
2338 | 780 put_rac(c, &keystate, 0); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
781 p->key_frame= 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
782 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
783 |
1306 | 784 if(!f->ac){ |
2338 | 785 used_count += ff_rac_terminate(c); |
1306 | 786 //printf("pos=%d\n", used_count); |
1522
79dddc5cd990
removed the obsolete and unused parameters of init_put_bits
alex
parents:
1453
diff
changeset
|
787 init_put_bits(&f->pb, buf + used_count, buf_size - used_count); |
11572 | 788 }else if (f->ac>1){ |
789 int i; | |
790 for(i=1; i<256; i++){ | |
791 c->one_state[i]= f->state_transition[i]; | |
792 c->zero_state[256-i]= 256-c->one_state[i]; | |
793 } | |
1306 | 794 } |
2967 | 795 |
1593 | 796 if(f->colorspace==0){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
797 const int chroma_width = -((-width )>>f->chroma_h_shift); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
798 const int chroma_height= -((-height)>>f->chroma_v_shift); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
799 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
800 encode_plane(f, p->data[0], width, height, p->linesize[0], 0); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
801 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
802 encode_plane(f, p->data[1], chroma_width, chroma_height, p->linesize[1], 1); |
1345
daf951f32697
merge U and V statistics, 33% reduction in memory requirement, compression rate better for some files worse for others, worst compression rate loss 0.05%
michaelni
parents:
1337
diff
changeset
|
803 encode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 1); |
1593 | 804 }else{ |
805 encode_rgb_frame(f, (uint32_t*)(p->data[0]), width, height, p->linesize[0]/4); | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
806 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
807 emms_c(); |
2967 | 808 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
809 f->picture_number++; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
810 |
1306 | 811 if(f->ac){ |
2338 | 812 return ff_rac_terminate(c); |
1306 | 813 }else{ |
814 flush_put_bits(&f->pb); //nicer padding FIXME | |
1786 | 815 return used_count + (put_bits_count(&f->pb)+7)/8; |
1306 | 816 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
817 } |
7782
6efb15a24e91
Replace generic CONFIG_ENCODERS preprocessor conditionals by more specific
diego
parents:
7146
diff
changeset
|
818 #endif /* CONFIG_FFV1_ENCODER */ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
819 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6234
diff
changeset
|
820 static av_cold int common_end(AVCodecContext *avctx){ |
3283 | 821 FFV1Context *s = avctx->priv_data; |
2967 | 822 int i; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
823 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
824 for(i=0; i<s->plane_count; i++){ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
825 PlaneContext *p= &s->plane[i]; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
826 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
827 av_freep(&p->state); |
5222 | 828 av_freep(&p->vlc_state); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
829 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
830 |
11965 | 831 av_freep(&s->sample_buffer); |
832 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
833 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
834 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
835 |
9547
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
836 static av_always_inline void decode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
837 PlaneContext * const p= &s->plane[plane_index]; |
2338 | 838 RangeCoder * const c= &s->c; |
1593 | 839 int x; |
840 int run_count=0; | |
841 int run_mode=0; | |
842 int run_index= s->run_index; | |
843 | |
844 for(x=0; x<w; x++){ | |
845 int diff, context, sign; | |
2967 | 846 |
1593 | 847 context= get_context(s, sample[1] + x, sample[0] + x, sample[1] + x); |
848 if(context < 0){ | |
849 context= -context; | |
850 sign=1; | |
851 }else | |
852 sign=0; | |
2967 | 853 |
1593 | 854 |
2339 | 855 if(s->ac){ |
9547
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
856 diff= get_symbol_inline(c, p->state[context], 1); |
2339 | 857 }else{ |
1593 | 858 if(context == 0 && run_mode==0) run_mode=1; |
2967 | 859 |
1593 | 860 if(run_mode){ |
861 if(run_count==0 && run_mode==1){ | |
862 if(get_bits1(&s->gb)){ | |
7146
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
863 run_count = 1<<ff_log2_run[run_index]; |
1593 | 864 if(x + run_count <= w) run_index++; |
865 }else{ | |
7146
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
866 if(ff_log2_run[run_index]) run_count = get_bits(&s->gb, ff_log2_run[run_index]); |
1593 | 867 else run_count=0; |
868 if(run_index) run_index--; | |
869 run_mode=2; | |
870 } | |
871 } | |
872 run_count--; | |
873 if(run_count < 0){ | |
874 run_mode=0; | |
875 run_count=0; | |
876 diff= get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); | |
877 if(diff>=0) diff++; | |
878 }else | |
879 diff=0; | |
880 }else | |
881 diff= get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); | |
2967 | 882 |
1593 | 883 // printf("count:%d index:%d, mode:%d, x:%d y:%d pos:%d\n", run_count, run_index, run_mode, x, y, get_bits_count(&s->gb)); |
884 } | |
885 | |
886 if(sign) diff= -diff; | |
887 | |
888 sample[1][x]= (predict(sample[1] + x, sample[0] + x) + diff) & ((1<<bits)-1); | |
889 } | |
2967 | 890 s->run_index= run_index; |
1593 | 891 } |
892 | |
893 static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ | |
894 int x, y; | |
6847 | 895 int_fast16_t *sample[2]; |
11965 | 896 sample[0]=s->sample_buffer +3; |
897 sample[1]=s->sample_buffer+w+6+3; | |
1593 | 898 |
899 s->run_index=0; | |
2967 | 900 |
11965 | 901 memset(s->sample_buffer, 0, 2*(w+6)*sizeof(*s->sample_buffer)); |
2967 | 902 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
903 for(y=0; y<h; y++){ |
1593 | 904 int_fast16_t *temp= sample[0]; //FIXME try a normal buffer |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
905 |
1337 | 906 sample[0]= sample[1]; |
907 sample[1]= temp; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
908 |
1337 | 909 sample[1][-1]= sample[0][0 ]; |
910 sample[0][ w]= sample[0][w-1]; | |
2967 | 911 |
1593 | 912 //{START_TIMER |
9548 | 913 if(s->avctx->bits_per_raw_sample <= 8){ |
9552 | 914 decode_line(s, w, sample, plane_index, 8); |
915 for(x=0; x<w; x++){ | |
916 src[x + stride*y]= sample[1][x]; | |
917 } | |
9548 | 918 }else{ |
919 decode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); | |
920 for(x=0; x<w; x++){ | |
921 ((uint16_t*)(src + stride*y))[x]= sample[1][x] << (16 - s->avctx->bits_per_raw_sample); | |
922 } | |
923 } | |
1593 | 924 //STOP_TIMER("decode-line")} |
925 } | |
926 } | |
927 | |
928 static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ | |
929 int x, y, p; | |
6847 | 930 int_fast16_t *sample[3][2]; |
931 for(x=0; x<3; x++){ | |
11965 | 932 sample[x][0] = s->sample_buffer + x*2 *(w+6) + 3; |
933 sample[x][1] = s->sample_buffer + (x*2+1)*(w+6) + 3; | |
6847 | 934 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
935 |
1593 | 936 s->run_index=0; |
2967 | 937 |
11965 | 938 memset(s->sample_buffer, 0, 6*(w+6)*sizeof(*s->sample_buffer)); |
2967 | 939 |
1593 | 940 for(y=0; y<h; y++){ |
941 for(p=0; p<3; p++){ | |
942 int_fast16_t *temp= sample[p][0]; //FIXME try a normal buffer | |
943 | |
944 sample[p][0]= sample[p][1]; | |
945 sample[p][1]= temp; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
946 |
1593 | 947 sample[p][1][-1]= sample[p][0][0 ]; |
948 sample[p][0][ w]= sample[p][0][w-1]; | |
949 decode_line(s, w, sample[p], FFMIN(p, 1), 9); | |
950 } | |
951 for(x=0; x<w; x++){ | |
952 int g= sample[0][1][x]; | |
953 int b= sample[1][1][x]; | |
954 int r= sample[2][1][x]; | |
1306 | 955 |
1593 | 956 // assert(g>=0 && b>=0 && r>=0); |
957 // assert(g<256 && b<512 && r<512); | |
2967 | 958 |
1593 | 959 b -= 0x100; |
960 r -= 0x100; | |
961 g -= (b + r)>>2; | |
962 b += g; | |
963 r += g; | |
2967 | 964 |
11945
1acf2841dc5f
Set an opaque alpha value when decoding rgba ffv1.
benoit
parents:
11644
diff
changeset
|
965 src[x + stride*y]= b + (g<<8) + (r<<16) + (0xFF<<24); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
966 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
967 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
968 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
969 |
2338 | 970 static int read_quant_table(RangeCoder *c, int16_t *quant_table, int scale){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
971 int v; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
972 int i=0; |
2338 | 973 uint8_t state[CONTEXT_SIZE]; |
974 | |
975 memset(state, 128, sizeof(state)); | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
976 |
1306 | 977 for(v=0; i<128 ; v++){ |
2339 | 978 int len= get_symbol(c, state, 0) + 1; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
979 |
1306 | 980 if(len + i > 128) return -1; |
2967 | 981 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
982 while(len--){ |
1306 | 983 quant_table[i] = scale*v; |
984 i++; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
985 //printf("%2d ",v); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
986 //if(i%16==0) printf("\n"); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
987 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
988 } |
1306 | 989 |
990 for(i=1; i<128; i++){ | |
991 quant_table[256-i]= -quant_table[i]; | |
992 } | |
993 quant_table[128]= -quant_table[127]; | |
2967 | 994 |
1306 | 995 return 2*v - 1; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
996 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
997 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
998 static int read_header(FFV1Context *f){ |
2338 | 999 uint8_t state[CONTEXT_SIZE]; |
1306 | 1000 int i, context_count; |
2338 | 1001 RangeCoder * const c= &f->c; |
2967 | 1002 |
2338 | 1003 memset(state, 128, sizeof(state)); |
1004 | |
2339 | 1005 f->version= get_symbol(c, state, 0); |
1006 f->ac= f->avctx->coder_type= get_symbol(c, state, 0); | |
11572 | 1007 if(f->ac>1){ |
1008 for(i=1; i<256; i++){ | |
1009 f->state_transition[i]= get_symbol(c, state, 1) + c->one_state[i]; | |
1010 } | |
1011 } | |
2339 | 1012 f->colorspace= get_symbol(c, state, 0); //YUV cs type |
9548 | 1013 if(f->version>0) |
1014 f->avctx->bits_per_raw_sample= get_symbol(c, state, 0); | |
2338 | 1015 get_rac(c, state); //no chroma = false |
2339 | 1016 f->chroma_h_shift= get_symbol(c, state, 0); |
1017 f->chroma_v_shift= get_symbol(c, state, 0); | |
2338 | 1018 get_rac(c, state); //transparency plane |
1345
daf951f32697
merge U and V statistics, 33% reduction in memory requirement, compression rate better for some files worse for others, worst compression rate loss 0.05%
michaelni
parents:
1337
diff
changeset
|
1019 f->plane_count= 2; |
1336
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1020 |
1593 | 1021 if(f->colorspace==0){ |
9548 | 1022 if(f->avctx->bits_per_raw_sample<=8){ |
9552 | 1023 switch(16*f->chroma_h_shift + f->chroma_v_shift){ |
1024 case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P; break; | |
1025 case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P; break; | |
1026 case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P; break; | |
1027 case 0x20: f->avctx->pix_fmt= PIX_FMT_YUV411P; break; | |
1028 case 0x22: f->avctx->pix_fmt= PIX_FMT_YUV410P; break; | |
1029 default: | |
1030 av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); | |
1031 return -1; | |
1032 } | |
9548 | 1033 }else{ |
1034 switch(16*f->chroma_h_shift + f->chroma_v_shift){ | |
1035 case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break; | |
1036 case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P16; break; | |
1037 case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P16; break; | |
1038 default: | |
1039 av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); | |
1040 return -1; | |
1041 } | |
1042 } | |
1593 | 1043 }else if(f->colorspace==1){ |
1044 if(f->chroma_h_shift || f->chroma_v_shift){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
1045 av_log(f->avctx, AV_LOG_ERROR, "chroma subsampling not supported in this colorspace\n"); |
1593 | 1046 return -1; |
1047 } | |
4494
ce643a22f049
Replace deprecated PIX_FMT names by the newer variants.
diego
parents:
4283
diff
changeset
|
1048 f->avctx->pix_fmt= PIX_FMT_RGB32; |
1593 | 1049 }else{ |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
1050 av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n"); |
1336
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1051 return -1; |
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1052 } |
1593 | 1053 |
1336
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1054 //printf("%d %d %d\n", f->chroma_h_shift, f->chroma_v_shift,f->avctx->pix_fmt); |
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1055 |
1306 | 1056 context_count=1; |
1057 for(i=0; i<5; i++){ | |
1058 context_count*= read_quant_table(c, f->quant_table[i], context_count); | |
2422 | 1059 if(context_count < 0 || context_count > 32768){ |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
1060 av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n"); |
1336
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1061 return -1; |
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1062 } |
1306 | 1063 } |
1064 context_count= (context_count+1)/2; | |
2967 | 1065 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1066 for(i=0; i<f->plane_count; i++){ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1067 PlaneContext * const p= &f->plane[i]; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1068 |
1306 | 1069 p->context_count= context_count; |
1070 | |
1071 if(f->ac){ | |
1072 if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t)); | |
1073 }else{ | |
1074 if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState)); | |
1075 } | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1076 } |
2967 | 1077 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1078 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1079 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1080 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6234
diff
changeset
|
1081 static av_cold int decode_init(AVCodecContext *avctx) |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1082 { |
1306 | 1083 // FFV1Context *s = avctx->priv_data; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1084 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1085 common_init(avctx); |
2967 | 1086 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1087 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1088 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1089 |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
1090 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt){ |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
1091 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
1092 int buf_size = avpkt->size; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1093 FFV1Context *f = avctx->priv_data; |
2338 | 1094 RangeCoder * const c= &f->c; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1095 const int width= f->width; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1096 const int height= f->height; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1097 AVFrame * const p= &f->picture; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1098 int bytes_read; |
2338 | 1099 uint8_t keystate= 128; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1100 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1101 AVFrame *picture = data; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1102 |
2338 | 1103 ff_init_range_decoder(c, buf, buf_size); |
1104 ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); | |
1908
e20fd60b215c
h264 - progressive I frame CABAC support patch by (Laurent Aimar <fenrir at via dot ecp dot fr>)
michael
parents:
1786
diff
changeset
|
1105 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1106 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1107 p->pict_type= FF_I_TYPE; //FIXME I vs. P |
2338 | 1108 if(get_rac(c, &keystate)){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1109 p->key_frame= 1; |
3103 | 1110 if(read_header(f) < 0) |
1111 return -1; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1112 clear_state(f); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1113 }else{ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1114 p->key_frame= 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1115 } |
11572 | 1116 if(f->ac>1){ |
1117 int i; | |
1118 for(i=1; i<256; i++){ | |
1119 c->one_state[i]= f->state_transition[i]; | |
1120 c->zero_state[256-i]= 256-c->one_state[i]; | |
1121 } | |
1122 } | |
1123 | |
3103 | 1124 if(!f->plane[0].state && !f->plane[0].vlc_state) |
1125 return -1; | |
1336
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1126 |
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1127 p->reference= 0; |
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1128 if(avctx->get_buffer(avctx, p) < 0){ |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
1129 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
1336
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1130 return -1; |
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1131 } |
c16ac5b7ac79
20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
michaelni
parents:
1325
diff
changeset
|
1132 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1133 if(avctx->debug&FF_DEBUG_PICT_INFO) |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
1134 av_log(avctx, AV_LOG_ERROR, "keyframe:%d coder:%d\n", p->key_frame, f->ac); |
2967 | 1135 |
1306 | 1136 if(!f->ac){ |
2338 | 1137 bytes_read = c->bytestream - c->bytestream_start - 1; |
1138 if(bytes_read ==0) av_log(avctx, AV_LOG_ERROR, "error at end of AC stream\n"); //FIXME | |
1306 | 1139 //printf("pos=%d\n", bytes_read); |
1140 init_get_bits(&f->gb, buf + bytes_read, buf_size - bytes_read); | |
1453 | 1141 } else { |
1142 bytes_read = 0; /* avoid warning */ | |
1306 | 1143 } |
2967 | 1144 |
1593 | 1145 if(f->colorspace==0){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1146 const int chroma_width = -((-width )>>f->chroma_h_shift); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1147 const int chroma_height= -((-height)>>f->chroma_v_shift); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1148 decode_plane(f, p->data[0], width, height, p->linesize[0], 0); |
2967 | 1149 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1150 decode_plane(f, p->data[1], chroma_width, chroma_height, p->linesize[1], 1); |
1345
daf951f32697
merge U and V statistics, 33% reduction in memory requirement, compression rate better for some files worse for others, worst compression rate loss 0.05%
michaelni
parents:
1337
diff
changeset
|
1151 decode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 1); |
1593 | 1152 }else{ |
1153 decode_rgb_frame(f, (uint32_t*)p->data[0], width, height, p->linesize[0]/4); | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1154 } |
2967 | 1155 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1156 emms_c(); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1157 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1158 f->picture_number++; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1159 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1160 *picture= *p; |
2967 | 1161 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1162 avctx->release_buffer(avctx, p); //FIXME |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1163 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1164 *data_size = sizeof(AVFrame); |
2967 | 1165 |
1306 | 1166 if(f->ac){ |
2338 | 1167 bytes_read= c->bytestream - c->bytestream_start - 1; |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
1168 if(bytes_read ==0) av_log(f->avctx, AV_LOG_ERROR, "error at end of frame\n"); |
1306 | 1169 }else{ |
1170 bytes_read+= (get_bits_count(&f->gb)+7)/8; | |
1171 } | |
1172 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1173 return bytes_read; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1174 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1175 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1176 AVCodec ffv1_decoder = { |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1177 "ffv1", |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
11530
diff
changeset
|
1178 AVMEDIA_TYPE_VIDEO, |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1179 CODEC_ID_FFV1, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1180 sizeof(FFV1Context), |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1181 decode_init, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1182 NULL, |
3283 | 1183 common_end, |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1184 decode_frame, |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
1185 CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/, |
6713 | 1186 NULL, |
10121
3ae2df444cdb
Use "FFmpeg video codec #1" instead of "FFmpeg codec #1" as codec long name.
diego
parents:
10098
diff
changeset
|
1187 .long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1188 }; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1189 |
8590 | 1190 #if CONFIG_FFV1_ENCODER |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1191 AVCodec ffv1_encoder = { |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1192 "ffv1", |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
11530
diff
changeset
|
1193 AVMEDIA_TYPE_VIDEO, |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1194 CODEC_ID_FFV1, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1195 sizeof(FFV1Context), |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1196 encode_init, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1197 encode_frame, |
3283 | 1198 common_end, |
10146
38cfe222e1a4
Mark all pix_fmts and supported_framerates compound literals as const.
reimar
parents:
10121
diff
changeset
|
1199 .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_RGB32, PIX_FMT_YUV420P16, PIX_FMT_YUV422P16, PIX_FMT_YUV444P16, PIX_FMT_NONE}, |
10121
3ae2df444cdb
Use "FFmpeg video codec #1" instead of "FFmpeg codec #1" as codec long name.
diego
parents:
10098
diff
changeset
|
1200 .long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1201 }; |
1325 | 1202 #endif |