Mercurial > libavcodec.hg
annotate ffv1.c @ 12197:fbf4d5b1b664 libavcodec
Remove FF_MM_SSE2/3 flags for CPUs where this is generally not faster than
regular MMX code. Examples of this are the Core1 CPU. Instead, set a new flag,
FF_MM_SSE2/3SLOW, which can be checked for particular SSE2/3 functions that
have been checked specifically on such CPUs and are actually faster than
their MMX counterparts.
In addition, use this flag to enable particular VP8 and LPC SSE2 functions
that are faster than their MMX counterparts.
Based on a patch by Loren Merritt <lorenm AT u washington edu>.
author | rbultje |
---|---|
date | Mon, 19 Jul 2010 22:38:23 +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 |