Mercurial > libavcodec.hg
annotate ffv1.c @ 10345:294c444866f7 libavcodec
Make avcodec_open set codec_id and codec_type if they haven't been set.
This fixes the API breakage introduced by the check that avctx codec id and type
match the opened codec and should make (almost?) all applications work again.
author | reimar |
---|---|
date | Thu, 01 Oct 2009 15:54:55 +0000 |
parents | 38cfe222e1a4 |
children | 9bd282dec604 |
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 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8627
diff
changeset
|
24 * @file libavcodec/ffv1.c |
1545
b340e83b8d0d
gcc->C99 and warning fixes patch by (Dan Christiansen <danchr at daimi dot au dot dk>)
michael
parents:
1522
diff
changeset
|
25 * FF Video Codec 1 (an experimental 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 |
1306 | 189 typedef struct VlcState{ |
190 int16_t drift; | |
191 uint16_t error_sum; | |
192 int8_t bias; | |
193 uint8_t count; | |
194 } VlcState; | |
195 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
196 typedef struct PlaneContext{ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
197 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
|
198 uint8_t (*state)[CONTEXT_SIZE]; |
1306 | 199 VlcState *vlc_state; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
200 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
|
201 } PlaneContext; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
202 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
203 typedef struct FFV1Context{ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
204 AVCodecContext *avctx; |
2338 | 205 RangeCoder c; |
1306 | 206 GetBitContext gb; |
207 PutBitContext pb; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
208 int version; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
209 int width, height; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
210 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
|
211 int flags; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
212 int picture_number; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
213 AVFrame picture; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
214 int plane_count; |
10098
fef90da31453
Fix comments after switching from CABAC to range coder in r3658.
cehoyos
parents:
10048
diff
changeset
|
215 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
|
216 PlaneContext plane[MAX_PLANES]; |
1306 | 217 int16_t quant_table[5][256]; |
1593 | 218 int run_index; |
219 int colorspace; | |
2967 | 220 |
221 DSPContext dsp; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
222 }FFV1Context; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
223 |
4283
d6f83e2f8804
rename always_inline to av_always_inline and move to common.h
mru
parents:
4001
diff
changeset
|
224 static av_always_inline int fold(int diff, int bits){ |
1593 | 225 if(bits==8) |
226 diff= (int8_t)diff; | |
227 else{ | |
228 diff+= 1<<(bits-1); | |
229 diff&=(1<<bits)-1; | |
230 diff-= 1<<(bits-1); | |
231 } | |
232 | |
233 return diff; | |
234 } | |
235 | |
236 static inline int predict(int_fast16_t *src, int_fast16_t *last){ | |
1306 | 237 const int LT= last[-1]; |
238 const int T= last[ 0]; | |
239 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
|
240 |
1360 | 241 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
|
242 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
243 |
1593 | 244 static inline int get_context(FFV1Context *f, int_fast16_t *src, int_fast16_t *last, int_fast16_t *last2){ |
1306 | 245 const int LT= last[-1]; |
246 const int T= last[ 0]; | |
247 const int RT= last[ 1]; | |
248 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
|
249 |
1306 | 250 if(f->quant_table[3][127]){ |
251 const int TT= last2[0]; | |
252 const int LL= src[-2]; | |
253 return f->quant_table[0][(L-LT) & 0xFF] + f->quant_table[1][(LT-T) & 0xFF] + f->quant_table[2][(T-RT) & 0xFF] | |
254 +f->quant_table[3][(LL-L) & 0xFF] + f->quant_table[4][(TT-T) & 0xFF]; | |
255 }else | |
256 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
|
257 } |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
258 |
9547
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
259 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
|
260 int i; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
261 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
262 if(v){ |
4001 | 263 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
|
264 const int e= av_log2(a); |
2338 | 265 put_rac(c, state+0, 0); |
9548 | 266 if(e<=9){ |
9552 | 267 for(i=0; i<e; i++){ |
268 put_rac(c, state+1+i, 1); //1..10 | |
269 } | |
270 put_rac(c, state+1+i, 0); | |
2339 | 271 |
9552 | 272 for(i=e-1; i>=0; i--){ |
273 put_rac(c, state+22+i, (a>>i)&1); //22..31 | |
274 } | |
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
|
275 |
9552 | 276 if(is_signed) |
277 put_rac(c, state+11 + e, v < 0); //11..21 | |
9548 | 278 }else{ |
279 for(i=0; i<e; i++){ | |
280 put_rac(c, state+1+FFMIN(i,9), 1); //1..10 | |
281 } | |
282 put_rac(c, state+1+9, 0); | |
283 | |
284 for(i=e-1; i>=0; i--){ | |
285 put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31 | |
286 } | |
287 | |
288 if(is_signed) | |
289 put_rac(c, state+11 + 10, v < 0); //11..21 | |
290 } | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
291 }else{ |
2338 | 292 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
|
293 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
294 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
295 |
9547
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
296 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
|
297 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
|
298 } |
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
299 |
9548 | 300 static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state, int is_signed){ |
2338 | 301 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
|
302 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
303 else{ |
2339 | 304 int i, e, a; |
305 e= 0; | |
9548 | 306 while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10 |
2339 | 307 e++; |
308 } | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
309 |
2339 | 310 a= 1; |
311 for(i=e-1; i>=0; i--){ | |
9548 | 312 a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31 |
2339 | 313 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
314 |
9548 | 315 e= -(is_signed && get_rac(c, state+11 + FFMIN(e, 10))); //11..21 |
9546 | 316 return (a^e)-e; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
317 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
318 } |
1306 | 319 |
9547
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
320 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
|
321 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
|
322 } |
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
323 |
1306 | 324 static inline void update_vlc_state(VlcState * const state, const int v){ |
325 int drift= state->drift; | |
326 int count= state->count; | |
4001 | 327 state->error_sum += FFABS(v); |
1306 | 328 drift += v; |
329 | |
330 if(count == 128){ //FIXME variable | |
331 count >>= 1; | |
332 drift >>= 1; | |
333 state->error_sum >>= 1; | |
334 } | |
335 count++; | |
336 | |
337 if(drift <= -count){ | |
338 if(state->bias > -128) state->bias--; | |
2967 | 339 |
1306 | 340 drift += count; |
341 if(drift <= -count) | |
342 drift= -count + 1; | |
343 }else if(drift > 0){ | |
344 if(state->bias < 127) state->bias++; | |
2967 | 345 |
1306 | 346 drift -= count; |
2967 | 347 if(drift > 0) |
1306 | 348 drift= 0; |
349 } | |
350 | |
351 state->drift= drift; | |
352 state->count= count; | |
353 } | |
354 | |
1593 | 355 static inline void put_vlc_symbol(PutBitContext *pb, VlcState * const state, int v, int bits){ |
1306 | 356 int i, k, code; |
357 //printf("final: %d ", v); | |
1593 | 358 v = fold(v - state->bias, bits); |
359 | |
1306 | 360 i= state->count; |
361 k=0; | |
362 while(i < state->error_sum){ //FIXME optimize | |
363 k++; | |
364 i += i; | |
365 } | |
1361
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
366 |
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
367 assert(k<=8); |
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
368 |
1306 | 369 #if 0 // JPEG LS |
370 if(k==0 && 2*state->drift <= - state->count) code= v ^ (-1); | |
371 else code= v; | |
372 #else | |
373 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
|
374 #endif |
2967 | 375 |
1306 | 376 //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 | 377 set_sr_golomb(pb, code, k, 12, bits); |
1306 | 378 |
379 update_vlc_state(state, v); | |
380 } | |
381 | |
1593 | 382 static inline int get_vlc_symbol(GetBitContext *gb, VlcState * const state, int bits){ |
1306 | 383 int k, i, v, ret; |
384 | |
385 i= state->count; | |
386 k=0; | |
387 while(i < state->error_sum){ //FIXME optimize | |
388 k++; | |
389 i += i; | |
390 } | |
1361
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
391 |
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
392 assert(k<=8); |
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
393 |
2220 | 394 v= get_sr_golomb(gb, k, 12, bits); |
1306 | 395 //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
|
396 |
1306 | 397 #if 0 // JPEG LS |
398 if(k==0 && 2*state->drift <= - state->count) v ^= (-1); | |
399 #else | |
400 v ^= ((2*state->drift + state->count)>>31); | |
401 #endif | |
402 | |
1593 | 403 ret= fold(v + state->bias, bits); |
2967 | 404 |
1306 | 405 update_vlc_state(state, v); |
406 //printf("final: %d\n", ret); | |
407 return ret; | |
408 } | |
409 | |
8590 | 410 #if CONFIG_FFV1_ENCODER |
2422 | 411 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
|
412 PlaneContext * const p= &s->plane[plane_index]; |
2338 | 413 RangeCoder * const c= &s->c; |
1593 | 414 int x; |
415 int run_index= s->run_index; | |
416 int run_count=0; | |
417 int run_mode=0; | |
418 | |
2422 | 419 if(s->ac){ |
420 if(c->bytestream_end - c->bytestream < w*20){ | |
421 av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); | |
422 return -1; | |
423 } | |
424 }else{ | |
425 if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < w*4){ | |
426 av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); | |
427 return -1; | |
428 } | |
429 } | |
430 | |
1593 | 431 for(x=0; x<w; x++){ |
432 int diff, context; | |
2967 | 433 |
1999 | 434 context= get_context(s, sample[0]+x, sample[1]+x, sample[2]+x); |
435 diff= sample[0][x] - predict(sample[0]+x, sample[1]+x); | |
1593 | 436 |
437 if(context < 0){ | |
438 context = -context; | |
439 diff= -diff; | |
440 } | |
441 | |
442 diff= fold(diff, bits); | |
2967 | 443 |
1593 | 444 if(s->ac){ |
9547
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
445 put_symbol_inline(c, p->state[context], diff, 1); |
1593 | 446 }else{ |
447 if(context == 0) run_mode=1; | |
2967 | 448 |
1593 | 449 if(run_mode){ |
450 | |
451 if(diff){ | |
7146
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
452 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
|
453 run_count -= 1<<ff_log2_run[run_index]; |
1593 | 454 run_index++; |
455 put_bits(&s->pb, 1, 1); | |
456 } | |
2967 | 457 |
7146
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
458 put_bits(&s->pb, 1 + ff_log2_run[run_index], run_count); |
1593 | 459 if(run_index) run_index--; |
460 run_count=0; | |
461 run_mode=0; | |
462 if(diff>0) diff--; | |
463 }else{ | |
464 run_count++; | |
465 } | |
466 } | |
2967 | 467 |
1786 | 468 // 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 | 469 |
470 if(run_mode == 0) | |
471 put_vlc_symbol(&s->pb, &p->vlc_state[context], diff, bits); | |
472 } | |
473 } | |
474 if(run_mode){ | |
7146
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
475 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
|
476 run_count -= 1<<ff_log2_run[run_index]; |
1593 | 477 run_index++; |
478 put_bits(&s->pb, 1, 1); | |
479 } | |
480 | |
481 if(run_count) | |
482 put_bits(&s->pb, 1, 1); | |
483 } | |
484 s->run_index= run_index; | |
2967 | 485 |
2422 | 486 return 0; |
1593 | 487 } |
488 | |
489 static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ | |
1999 | 490 int x,y,i; |
2162 | 491 const int ring_size= s->avctx->context_model ? 3 : 2; |
1999 | 492 int_fast16_t sample_buffer[ring_size][w+6], *sample[ring_size]; |
1593 | 493 s->run_index=0; |
2967 | 494 |
1337 | 495 memset(sample_buffer, 0, sizeof(sample_buffer)); |
2967 | 496 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
497 for(y=0; y<h; y++){ |
1999 | 498 for(i=0; i<ring_size; i++) |
499 sample[i]= sample_buffer[(h+i-y)%ring_size]+3; | |
2967 | 500 |
1999 | 501 sample[0][-1]= sample[1][0 ]; |
502 sample[1][ w]= sample[1][w-1]; | |
1593 | 503 //{START_TIMER |
9548 | 504 if(s->avctx->bits_per_raw_sample<=8){ |
9552 | 505 for(x=0; x<w; x++){ |
506 sample[0][x]= src[x + stride*y]; | |
507 } | |
508 encode_line(s, w, sample, plane_index, 8); | |
9548 | 509 }else{ |
510 for(x=0; x<w; x++){ | |
511 sample[0][x]= ((uint16_t*)(src + stride*y))[x] >> (16 - s->avctx->bits_per_raw_sample); | |
512 } | |
513 encode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); | |
514 } | |
1593 | 515 //STOP_TIMER("encode line")} |
516 } | |
517 } | |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
518 |
1593 | 519 static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ |
1999 | 520 int x, y, p, i; |
2162 | 521 const int ring_size= s->avctx->context_model ? 3 : 2; |
1999 | 522 int_fast16_t sample_buffer[3][ring_size][w+6], *sample[3][ring_size]; |
1593 | 523 s->run_index=0; |
2967 | 524 |
1593 | 525 memset(sample_buffer, 0, sizeof(sample_buffer)); |
2967 | 526 |
1593 | 527 for(y=0; y<h; y++){ |
1999 | 528 for(i=0; i<ring_size; i++) |
529 for(p=0; p<3; p++) | |
530 sample[p][i]= sample_buffer[p][(h+i-y)%ring_size]+3; | |
531 | |
1593 | 532 for(x=0; x<w; x++){ |
533 int v= src[x + stride*y]; | |
534 int b= v&0xFF; | |
535 int g= (v>>8)&0xFF; | |
536 int r= (v>>16)&0xFF; | |
2967 | 537 |
1593 | 538 b -= g; |
539 r -= g; | |
540 g += (b + r)>>2; | |
541 b += 0x100; | |
542 r += 0x100; | |
2967 | 543 |
1593 | 544 // assert(g>=0 && b>=0 && r>=0); |
545 // assert(g<256 && b<512 && r<512); | |
546 sample[0][0][x]= g; | |
547 sample[1][0][x]= b; | |
548 sample[2][0][x]= r; | |
549 } | |
550 for(p=0; p<3; p++){ | |
1999 | 551 sample[p][0][-1]= sample[p][1][0 ]; |
552 sample[p][1][ w]= sample[p][1][w-1]; | |
1593 | 553 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
|
554 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
555 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
556 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
557 |
2338 | 558 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
|
559 int last=0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
560 int i; |
2338 | 561 uint8_t state[CONTEXT_SIZE]; |
562 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
|
563 |
1306 | 564 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
|
565 if(quant_table[i] != quant_table[i-1]){ |
2339 | 566 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
|
567 last= i; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
568 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
569 } |
2339 | 570 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
|
571 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
572 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
573 static void write_header(FFV1Context *f){ |
2338 | 574 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
|
575 int i; |
2338 | 576 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
|
577 |
2338 | 578 memset(state, 128, sizeof(state)); |
2967 | 579 |
2339 | 580 put_symbol(c, state, f->version, 0); |
581 put_symbol(c, state, f->avctx->coder_type, 0); | |
2967 | 582 put_symbol(c, state, f->colorspace, 0); //YUV cs type |
9548 | 583 if(f->version>0) |
584 put_symbol(c, state, f->avctx->bits_per_raw_sample, 0); | |
2338 | 585 put_rac(c, state, 1); //chroma planes |
2339 | 586 put_symbol(c, state, f->chroma_h_shift, 0); |
587 put_symbol(c, state, f->chroma_v_shift, 0); | |
2338 | 588 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
|
589 |
1306 | 590 for(i=0; i<5; i++) |
591 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
|
592 } |
7782
6efb15a24e91
Replace generic CONFIG_ENCODERS preprocessor conditionals by more specific
diego
parents:
7146
diff
changeset
|
593 #endif /* CONFIG_FFV1_ENCODER */ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
594 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6234
diff
changeset
|
595 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
|
596 FFV1Context *s = avctx->priv_data; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
597 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
598 s->avctx= avctx; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
599 s->flags= avctx->flags; |
2967 | 600 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
601 dsputil_init(&s->dsp, avctx); |
2967 | 602 |
9468
71608a4f9eb7
Remove 2 unneeded variables from common_init() found by CSA.
michael
parents:
9428
diff
changeset
|
603 s->width = avctx->width; |
71608a4f9eb7
Remove 2 unneeded variables from common_init() found by CSA.
michael
parents:
9428
diff
changeset
|
604 s->height= avctx->height; |
2967 | 605 |
9468
71608a4f9eb7
Remove 2 unneeded variables from common_init() found by CSA.
michael
parents:
9428
diff
changeset
|
606 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
|
607 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
608 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
609 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
610 |
8590 | 611 #if CONFIG_FFV1_ENCODER |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6234
diff
changeset
|
612 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
|
613 { |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
614 FFV1Context *s = avctx->priv_data; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
615 int i; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
616 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
617 common_init(avctx); |
2967 | 618 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
619 s->version=0; |
1306 | 620 s->ac= avctx->coder_type; |
2967 | 621 |
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
|
622 s->plane_count=2; |
1306 | 623 for(i=0; i<256; i++){ |
9548 | 624 if(avctx->bits_per_raw_sample <=8){ |
9552 | 625 s->quant_table[0][i]= quant11[i]; |
626 s->quant_table[1][i]= 11*quant11[i]; | |
627 if(avctx->context_model==0){ | |
628 s->quant_table[2][i]= 11*11*quant11[i]; | |
629 s->quant_table[3][i]= | |
630 s->quant_table[4][i]=0; | |
631 }else{ | |
632 s->quant_table[2][i]= 11*11*quant5 [i]; | |
633 s->quant_table[3][i]= 5*11*11*quant5 [i]; | |
634 s->quant_table[4][i]= 5*5*11*11*quant5 [i]; | |
635 } | |
9548 | 636 }else{ |
637 s->quant_table[0][i]= quant9_10bit[i]; | |
638 s->quant_table[1][i]= 11*quant9_10bit[i]; | |
639 if(avctx->context_model==0){ | |
640 s->quant_table[2][i]= 11*11*quant9_10bit[i]; | |
641 s->quant_table[3][i]= | |
642 s->quant_table[4][i]=0; | |
643 }else{ | |
644 s->quant_table[2][i]= 11*11*quant5_10bit[i]; | |
645 s->quant_table[3][i]= 5*11*11*quant5_10bit[i]; | |
646 s->quant_table[4][i]= 5*5*11*11*quant5_10bit[i]; | |
647 } | |
648 } | |
1306 | 649 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
650 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
651 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
|
652 PlaneContext * const p= &s->plane[i]; |
2967 | 653 |
1306 | 654 if(avctx->context_model==0){ |
655 p->context_count= (11*11*11+1)/2; | |
2967 | 656 }else{ |
1306 | 657 p->context_count= (11*11*5*5*5+1)/2; |
658 } | |
659 | |
660 if(s->ac){ | |
661 if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t)); | |
662 }else{ | |
663 if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState)); | |
664 } | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
665 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
666 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
667 avctx->coded_frame= &s->picture; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
668 switch(avctx->pix_fmt){ |
9548 | 669 case PIX_FMT_YUV444P16: |
670 case PIX_FMT_YUV422P16: | |
671 case PIX_FMT_YUV420P16: | |
672 if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ | |
673 av_log(avctx, AV_LOG_ERROR, "More than 8 bit per component is still experimental and no gurantee is yet made for future compatibility\n" | |
674 "Use vstrict=-2 / -strict -2 to use it anyway.\n"); | |
675 return -1; | |
676 } | |
677 if(avctx->bits_per_raw_sample <=8){ | |
10048 | 678 av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample invalid\n"); |
9548 | 679 return -1; |
680 } | |
681 s->version= 1; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
682 case PIX_FMT_YUV444P: |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
683 case PIX_FMT_YUV422P: |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
684 case PIX_FMT_YUV420P: |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
685 case PIX_FMT_YUV411P: |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
686 case PIX_FMT_YUV410P: |
1593 | 687 s->colorspace= 0; |
688 break; | |
4494
ce643a22f049
Replace deprecated PIX_FMT names by the newer variants.
diego
parents:
4283
diff
changeset
|
689 case PIX_FMT_RGB32: |
1593 | 690 s->colorspace= 1; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
691 break; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
692 default: |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
693 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
|
694 return -1; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
695 } |
1593 | 696 avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); |
697 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
698 s->picture_number=0; |
2967 | 699 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
700 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
701 } |
7782
6efb15a24e91
Replace generic CONFIG_ENCODERS preprocessor conditionals by more specific
diego
parents:
7146
diff
changeset
|
702 #endif /* CONFIG_FFV1_ENCODER */ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
703 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
704 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
705 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
|
706 int i, j; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
707 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
708 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
|
709 PlaneContext *p= &f->plane[i]; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
710 |
2338 | 711 p->interlace_bit_state[0]= 128; |
712 p->interlace_bit_state[1]= 128; | |
2967 | 713 |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
714 for(j=0; j<p->context_count; j++){ |
1306 | 715 if(f->ac){ |
2338 | 716 memset(p->state[j], 128, sizeof(uint8_t)*CONTEXT_SIZE); |
1306 | 717 }else{ |
718 p->vlc_state[j].drift= 0; | |
719 p->vlc_state[j].error_sum= 4; //FFMAX((RANGE + 32)/64, 2); | |
720 p->vlc_state[j].bias= 0; | |
721 p->vlc_state[j].count= 1; | |
722 } | |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
723 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
724 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
725 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
726 |
8590 | 727 #if CONFIG_FFV1_ENCODER |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
728 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
|
729 FFV1Context *f = avctx->priv_data; |
2338 | 730 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
|
731 AVFrame *pict = data; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
732 const int width= f->width; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
733 const int height= f->height; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
734 AVFrame * const p= &f->picture; |
1306 | 735 int used_count= 0; |
2338 | 736 uint8_t keystate=128; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
737 |
2338 | 738 ff_init_range_encoder(c, buf, buf_size); |
739 ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); | |
740 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
741 *p = *pict; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
742 p->pict_type= FF_I_TYPE; |
2967 | 743 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
744 if(avctx->gop_size==0 || f->picture_number % avctx->gop_size == 0){ |
2338 | 745 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
|
746 p->key_frame= 1; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
747 write_header(f); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
748 clear_state(f); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
749 }else{ |
2338 | 750 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
|
751 p->key_frame= 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
752 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
753 |
1306 | 754 if(!f->ac){ |
2338 | 755 used_count += ff_rac_terminate(c); |
1306 | 756 //printf("pos=%d\n", used_count); |
1522
79dddc5cd990
removed the obsolete and unused parameters of init_put_bits
alex
parents:
1453
diff
changeset
|
757 init_put_bits(&f->pb, buf + used_count, buf_size - used_count); |
1306 | 758 } |
2967 | 759 |
1593 | 760 if(f->colorspace==0){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
761 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
|
762 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
|
763 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
764 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
|
765 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
766 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
|
767 encode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 1); |
1593 | 768 }else{ |
769 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
|
770 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
771 emms_c(); |
2967 | 772 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
773 f->picture_number++; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
774 |
1306 | 775 if(f->ac){ |
2338 | 776 return ff_rac_terminate(c); |
1306 | 777 }else{ |
778 flush_put_bits(&f->pb); //nicer padding FIXME | |
1786 | 779 return used_count + (put_bits_count(&f->pb)+7)/8; |
1306 | 780 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
781 } |
7782
6efb15a24e91
Replace generic CONFIG_ENCODERS preprocessor conditionals by more specific
diego
parents:
7146
diff
changeset
|
782 #endif /* CONFIG_FFV1_ENCODER */ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
783 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6234
diff
changeset
|
784 static av_cold int common_end(AVCodecContext *avctx){ |
3283 | 785 FFV1Context *s = avctx->priv_data; |
2967 | 786 int i; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
787 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
788 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
|
789 PlaneContext *p= &s->plane[i]; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
790 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
791 av_freep(&p->state); |
5222 | 792 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
|
793 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
794 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
795 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
796 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
797 |
9547
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
798 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
|
799 PlaneContext * const p= &s->plane[plane_index]; |
2338 | 800 RangeCoder * const c= &s->c; |
1593 | 801 int x; |
802 int run_count=0; | |
803 int run_mode=0; | |
804 int run_index= s->run_index; | |
805 | |
806 for(x=0; x<w; x++){ | |
807 int diff, context, sign; | |
2967 | 808 |
1593 | 809 context= get_context(s, sample[1] + x, sample[0] + x, sample[1] + x); |
810 if(context < 0){ | |
811 context= -context; | |
812 sign=1; | |
813 }else | |
814 sign=0; | |
2967 | 815 |
1593 | 816 |
2339 | 817 if(s->ac){ |
9547
df1827eb3aaa
Force speed irrelevant calls to get/put_symbol() to be noinline.
michael
parents:
9546
diff
changeset
|
818 diff= get_symbol_inline(c, p->state[context], 1); |
2339 | 819 }else{ |
1593 | 820 if(context == 0 && run_mode==0) run_mode=1; |
2967 | 821 |
1593 | 822 if(run_mode){ |
823 if(run_count==0 && run_mode==1){ | |
824 if(get_bits1(&s->gb)){ | |
7146
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
825 run_count = 1<<ff_log2_run[run_index]; |
1593 | 826 if(x + run_count <= w) run_index++; |
827 }else{ | |
7146
d3a1ac3e227b
move ff_log2_run to bitstream.c and reuse in ffv1.c
stefang
parents:
7040
diff
changeset
|
828 if(ff_log2_run[run_index]) run_count = get_bits(&s->gb, ff_log2_run[run_index]); |
1593 | 829 else run_count=0; |
830 if(run_index) run_index--; | |
831 run_mode=2; | |
832 } | |
833 } | |
834 run_count--; | |
835 if(run_count < 0){ | |
836 run_mode=0; | |
837 run_count=0; | |
838 diff= get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); | |
839 if(diff>=0) diff++; | |
840 }else | |
841 diff=0; | |
842 }else | |
843 diff= get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); | |
2967 | 844 |
1593 | 845 // 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)); |
846 } | |
847 | |
848 if(sign) diff= -diff; | |
849 | |
850 sample[1][x]= (predict(sample[1] + x, sample[0] + x) + diff) & ((1<<bits)-1); | |
851 } | |
2967 | 852 s->run_index= run_index; |
1593 | 853 } |
854 | |
855 static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ | |
856 int x, y; | |
857 int_fast16_t sample_buffer[2][w+6]; | |
6847 | 858 int_fast16_t *sample[2]; |
859 sample[0]=sample_buffer[0]+3; | |
860 sample[1]=sample_buffer[1]+3; | |
1593 | 861 |
862 s->run_index=0; | |
2967 | 863 |
1337 | 864 memset(sample_buffer, 0, sizeof(sample_buffer)); |
2967 | 865 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
866 for(y=0; y<h; y++){ |
1593 | 867 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
|
868 |
1337 | 869 sample[0]= sample[1]; |
870 sample[1]= temp; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
871 |
1337 | 872 sample[1][-1]= sample[0][0 ]; |
873 sample[0][ w]= sample[0][w-1]; | |
2967 | 874 |
1593 | 875 //{START_TIMER |
9548 | 876 if(s->avctx->bits_per_raw_sample <= 8){ |
9552 | 877 decode_line(s, w, sample, plane_index, 8); |
878 for(x=0; x<w; x++){ | |
879 src[x + stride*y]= sample[1][x]; | |
880 } | |
9548 | 881 }else{ |
882 decode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); | |
883 for(x=0; x<w; x++){ | |
884 ((uint16_t*)(src + stride*y))[x]= sample[1][x] << (16 - s->avctx->bits_per_raw_sample); | |
885 } | |
886 } | |
1593 | 887 //STOP_TIMER("decode-line")} |
888 } | |
889 } | |
890 | |
891 static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ | |
892 int x, y, p; | |
893 int_fast16_t sample_buffer[3][2][w+6]; | |
6847 | 894 int_fast16_t *sample[3][2]; |
895 for(x=0; x<3; x++){ | |
896 sample[x][0] = sample_buffer[x][0]+3; | |
897 sample[x][1] = sample_buffer[x][1]+3; | |
898 } | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
899 |
1593 | 900 s->run_index=0; |
2967 | 901 |
1593 | 902 memset(sample_buffer, 0, sizeof(sample_buffer)); |
2967 | 903 |
1593 | 904 for(y=0; y<h; y++){ |
905 for(p=0; p<3; p++){ | |
906 int_fast16_t *temp= sample[p][0]; //FIXME try a normal buffer | |
907 | |
908 sample[p][0]= sample[p][1]; | |
909 sample[p][1]= temp; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
910 |
1593 | 911 sample[p][1][-1]= sample[p][0][0 ]; |
912 sample[p][0][ w]= sample[p][0][w-1]; | |
913 decode_line(s, w, sample[p], FFMIN(p, 1), 9); | |
914 } | |
915 for(x=0; x<w; x++){ | |
916 int g= sample[0][1][x]; | |
917 int b= sample[1][1][x]; | |
918 int r= sample[2][1][x]; | |
1306 | 919 |
1593 | 920 // assert(g>=0 && b>=0 && r>=0); |
921 // assert(g<256 && b<512 && r<512); | |
2967 | 922 |
1593 | 923 b -= 0x100; |
924 r -= 0x100; | |
925 g -= (b + r)>>2; | |
926 b += g; | |
927 r += g; | |
2967 | 928 |
1593 | 929 src[x + stride*y]= b + (g<<8) + (r<<16); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
930 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
931 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
932 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
933 |
2338 | 934 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
|
935 int v; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
936 int i=0; |
2338 | 937 uint8_t state[CONTEXT_SIZE]; |
938 | |
939 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
|
940 |
1306 | 941 for(v=0; i<128 ; v++){ |
2339 | 942 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
|
943 |
1306 | 944 if(len + i > 128) return -1; |
2967 | 945 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
946 while(len--){ |
1306 | 947 quant_table[i] = scale*v; |
948 i++; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
949 //printf("%2d ",v); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
950 //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
|
951 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
952 } |
1306 | 953 |
954 for(i=1; i<128; i++){ | |
955 quant_table[256-i]= -quant_table[i]; | |
956 } | |
957 quant_table[128]= -quant_table[127]; | |
2967 | 958 |
1306 | 959 return 2*v - 1; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
960 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
961 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
962 static int read_header(FFV1Context *f){ |
2338 | 963 uint8_t state[CONTEXT_SIZE]; |
1306 | 964 int i, context_count; |
2338 | 965 RangeCoder * const c= &f->c; |
2967 | 966 |
2338 | 967 memset(state, 128, sizeof(state)); |
968 | |
2339 | 969 f->version= get_symbol(c, state, 0); |
970 f->ac= f->avctx->coder_type= get_symbol(c, state, 0); | |
971 f->colorspace= get_symbol(c, state, 0); //YUV cs type | |
9548 | 972 if(f->version>0) |
973 f->avctx->bits_per_raw_sample= get_symbol(c, state, 0); | |
2338 | 974 get_rac(c, state); //no chroma = false |
2339 | 975 f->chroma_h_shift= get_symbol(c, state, 0); |
976 f->chroma_v_shift= get_symbol(c, state, 0); | |
2338 | 977 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
|
978 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
|
979 |
1593 | 980 if(f->colorspace==0){ |
9548 | 981 if(f->avctx->bits_per_raw_sample<=8){ |
9552 | 982 switch(16*f->chroma_h_shift + f->chroma_v_shift){ |
983 case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P; break; | |
984 case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P; break; | |
985 case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P; break; | |
986 case 0x20: f->avctx->pix_fmt= PIX_FMT_YUV411P; break; | |
987 case 0x22: f->avctx->pix_fmt= PIX_FMT_YUV410P; break; | |
988 default: | |
989 av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); | |
990 return -1; | |
991 } | |
9548 | 992 }else{ |
993 switch(16*f->chroma_h_shift + f->chroma_v_shift){ | |
994 case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break; | |
995 case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P16; break; | |
996 case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P16; break; | |
997 default: | |
998 av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); | |
999 return -1; | |
1000 } | |
1001 } | |
1593 | 1002 }else if(f->colorspace==1){ |
1003 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
|
1004 av_log(f->avctx, AV_LOG_ERROR, "chroma subsampling not supported in this colorspace\n"); |
1593 | 1005 return -1; |
1006 } | |
4494
ce643a22f049
Replace deprecated PIX_FMT names by the newer variants.
diego
parents:
4283
diff
changeset
|
1007 f->avctx->pix_fmt= PIX_FMT_RGB32; |
1593 | 1008 }else{ |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
1009 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
|
1010 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
|
1011 } |
1593 | 1012 |
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
|
1013 //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
|
1014 |
1306 | 1015 context_count=1; |
1016 for(i=0; i<5; i++){ | |
1017 context_count*= read_quant_table(c, f->quant_table[i], context_count); | |
2422 | 1018 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
|
1019 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
|
1020 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
|
1021 } |
1306 | 1022 } |
1023 context_count= (context_count+1)/2; | |
2967 | 1024 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1025 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
|
1026 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
|
1027 |
1306 | 1028 p->context_count= context_count; |
1029 | |
1030 if(f->ac){ | |
1031 if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t)); | |
1032 }else{ | |
1033 if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState)); | |
1034 } | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1035 } |
2967 | 1036 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1037 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1038 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1039 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6234
diff
changeset
|
1040 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
|
1041 { |
1306 | 1042 // 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
|
1043 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1044 common_init(avctx); |
2967 | 1045 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1046 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1047 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1048 |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
1049 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
|
1050 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
1051 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
|
1052 FFV1Context *f = avctx->priv_data; |
2338 | 1053 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
|
1054 const int width= f->width; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1055 const int height= f->height; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1056 AVFrame * const p= &f->picture; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1057 int bytes_read; |
2338 | 1058 uint8_t keystate= 128; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1059 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1060 AVFrame *picture = data; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1061 |
2338 | 1062 ff_init_range_decoder(c, buf, buf_size); |
1063 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
|
1064 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1065 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1066 p->pict_type= FF_I_TYPE; //FIXME I vs. P |
2338 | 1067 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
|
1068 p->key_frame= 1; |
3103 | 1069 if(read_header(f) < 0) |
1070 return -1; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1071 clear_state(f); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1072 }else{ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1073 p->key_frame= 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1074 } |
3103 | 1075 if(!f->plane[0].state && !f->plane[0].vlc_state) |
1076 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
|
1077 |
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
|
1078 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
|
1079 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
|
1080 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
|
1081 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
|
1082 } |
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
|
1083 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1084 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
|
1085 av_log(avctx, AV_LOG_ERROR, "keyframe:%d coder:%d\n", p->key_frame, f->ac); |
2967 | 1086 |
1306 | 1087 if(!f->ac){ |
2338 | 1088 bytes_read = c->bytestream - c->bytestream_start - 1; |
1089 if(bytes_read ==0) av_log(avctx, AV_LOG_ERROR, "error at end of AC stream\n"); //FIXME | |
1306 | 1090 //printf("pos=%d\n", bytes_read); |
1091 init_get_bits(&f->gb, buf + bytes_read, buf_size - bytes_read); | |
1453 | 1092 } else { |
1093 bytes_read = 0; /* avoid warning */ | |
1306 | 1094 } |
2967 | 1095 |
1593 | 1096 if(f->colorspace==0){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1097 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
|
1098 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
|
1099 decode_plane(f, p->data[0], width, height, p->linesize[0], 0); |
2967 | 1100 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1101 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
|
1102 decode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 1); |
1593 | 1103 }else{ |
1104 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
|
1105 } |
2967 | 1106 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1107 emms_c(); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1108 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1109 f->picture_number++; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1110 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1111 *picture= *p; |
2967 | 1112 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1113 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
|
1114 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1115 *data_size = sizeof(AVFrame); |
2967 | 1116 |
1306 | 1117 if(f->ac){ |
2338 | 1118 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
|
1119 if(bytes_read ==0) av_log(f->avctx, AV_LOG_ERROR, "error at end of frame\n"); |
1306 | 1120 }else{ |
1121 bytes_read+= (get_bits_count(&f->gb)+7)/8; | |
1122 } | |
1123 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1124 return bytes_read; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1125 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1126 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1127 AVCodec ffv1_decoder = { |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1128 "ffv1", |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1129 CODEC_TYPE_VIDEO, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1130 CODEC_ID_FFV1, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1131 sizeof(FFV1Context), |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1132 decode_init, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1133 NULL, |
3283 | 1134 common_end, |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1135 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
|
1136 CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/, |
6713 | 1137 NULL, |
10121
3ae2df444cdb
Use "FFmpeg video codec #1" instead of "FFmpeg codec #1" as codec long name.
diego
parents:
10098
diff
changeset
|
1138 .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
|
1139 }; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1140 |
8590 | 1141 #if CONFIG_FFV1_ENCODER |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1142 AVCodec ffv1_encoder = { |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1143 "ffv1", |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1144 CODEC_TYPE_VIDEO, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1145 CODEC_ID_FFV1, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1146 sizeof(FFV1Context), |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1147 encode_init, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1148 encode_frame, |
3283 | 1149 common_end, |
10146
38cfe222e1a4
Mark all pix_fmts and supported_framerates compound literals as const.
reimar
parents:
10121
diff
changeset
|
1150 .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
|
1151 .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
|
1152 }; |
1325 | 1153 #endif |