Mercurial > libavcodec.hg
annotate ffv1.c @ 2338:37516ec97cd6 libavcodec
switch ffv1 from CABAC to the range coder
author | michael |
---|---|
date | Sun, 31 Oct 2004 10:08:50 +0000 |
parents | 21947e176d4d |
children | b7bb00973f99 |
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 * |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
6 * This library is free software; you can redistribute it and/or |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
7 * 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
|
8 * License as published by the Free Software Foundation; either |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
9 * version 2 of the License, or (at your option) any later version. |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
10 * |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
11 * This library is distributed in the hope that it will be useful, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
12 * 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
|
13 * 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
|
14 * 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
|
15 * |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
16 * You should have received a copy 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
|
17 * License along with this library; if not, write to the Free Software |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
19 * |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
20 */ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
21 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
22 /** |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
23 * @file 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
|
24 * 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
|
25 */ |
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 #include "common.h" |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
28 #include "avcodec.h" |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
29 #include "dsputil.h" |
2338 | 30 #include "rangecoder.h" |
1306 | 31 #include "golomb.h" |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
32 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
33 #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
|
34 #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
|
35 |
1306 | 36 static const int8_t quant3[256]={ |
37 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
38 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
39 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
40 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
41 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
42 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
|
43 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
|
44 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1306 | 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, | |
48 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
49 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, | |
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, 0, | |
53 }; | |
54 static const int8_t quant5[256]={ | |
55 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
|
56 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
1306 | 57 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
58 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
59 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
60 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
61 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
62 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
63 -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, | |
64 -2,-2,-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,-1,-1,-1, | |
71 }; | |
72 static const int8_t quant7[256]={ | |
73 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
74 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
75 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, | |
76 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
77 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
78 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
79 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
80 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
81 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, | |
82 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, | |
83 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, | |
84 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, | |
85 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, | |
86 -3,-3,-3,-3,-3,-3,-3,-3,-3,-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,-1,-1, | |
89 }; | |
90 static const int8_t quant9[256]={ | |
91 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
92 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
93 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
94 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
95 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
96 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
97 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
98 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
99 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
100 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
101 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
102 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
103 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
104 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, | |
105 -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3, | |
106 -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1, | |
107 }; | |
108 static const int8_t quant11[256]={ | |
109 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, | |
110 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
111 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
112 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
113 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
114 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
115 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
116 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
117 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
118 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
119 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
120 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
121 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
122 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-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,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-1, | |
125 }; | |
126 static const int8_t quant13[256]={ | |
127 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, | |
128 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
129 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | |
130 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | |
131 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | |
132 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | |
133 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | |
134 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | |
135 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6, | |
136 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6, | |
137 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6, | |
138 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6, | |
139 -6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-5, | |
140 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
141 -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, | |
142 -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
|
143 }; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
144 |
1306 | 145 static const uint8_t log2_run[32]={ |
146 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, | |
147 4, 4, 5, 5, 6, 6, 7, 7, | |
148 8, 9,10,11,12,13,14,15, | |
149 }; | |
150 | |
151 typedef struct VlcState{ | |
152 int16_t drift; | |
153 uint16_t error_sum; | |
154 int8_t bias; | |
155 uint8_t count; | |
156 } VlcState; | |
157 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
158 typedef struct PlaneContext{ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
159 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
|
160 uint8_t (*state)[CONTEXT_SIZE]; |
1306 | 161 VlcState *vlc_state; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
162 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
|
163 } PlaneContext; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
164 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
165 typedef struct FFV1Context{ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
166 AVCodecContext *avctx; |
2338 | 167 RangeCoder c; |
1306 | 168 GetBitContext gb; |
169 PutBitContext pb; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
170 int version; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
171 int width, height; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
172 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
|
173 int flags; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
174 int picture_number; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
175 AVFrame picture; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
176 int plane_count; |
1306 | 177 int ac; ///< 1-> CABAC 0-> golomb rice |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
178 PlaneContext plane[MAX_PLANES]; |
1306 | 179 int16_t quant_table[5][256]; |
1593 | 180 int run_index; |
181 int colorspace; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
182 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
183 DSPContext dsp; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
184 }FFV1Context; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
185 |
1593 | 186 static always_inline int fold(int diff, int bits){ |
187 if(bits==8) | |
188 diff= (int8_t)diff; | |
189 else{ | |
190 diff+= 1<<(bits-1); | |
191 diff&=(1<<bits)-1; | |
192 diff-= 1<<(bits-1); | |
193 } | |
194 | |
195 return diff; | |
196 } | |
197 | |
198 static inline int predict(int_fast16_t *src, int_fast16_t *last){ | |
1306 | 199 const int LT= last[-1]; |
200 const int T= last[ 0]; | |
201 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
|
202 |
1360 | 203 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
|
204 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
205 |
1593 | 206 static inline int get_context(FFV1Context *f, int_fast16_t *src, int_fast16_t *last, int_fast16_t *last2){ |
1306 | 207 const int LT= last[-1]; |
208 const int T= last[ 0]; | |
209 const int RT= last[ 1]; | |
210 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
|
211 |
1306 | 212 if(f->quant_table[3][127]){ |
213 const int TT= last2[0]; | |
214 const int LL= src[-2]; | |
215 return f->quant_table[0][(L-LT) & 0xFF] + f->quant_table[1][(LT-T) & 0xFF] + f->quant_table[2][(T-RT) & 0xFF] | |
216 +f->quant_table[3][(LL-L) & 0xFF] + f->quant_table[4][(TT-T) & 0xFF]; | |
217 }else | |
218 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
|
219 } |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
220 |
1300
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 * put |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
223 */ |
2338 | 224 static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed, int max_exp){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
225 int i; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
226 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
227 if(v){ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
228 const int a= ABS(v); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
229 const int e= av_log2(a); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
230 |
2338 | 231 put_rac(c, state+0, 0); |
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
|
232 |
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
|
233 for(i=0; i<e; i++){ |
2338 | 234 put_rac(c, state+1+i, 1); //1..8 |
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
|
235 } |
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
|
236 |
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
|
237 if(e<max_exp){ |
2338 | 238 put_rac(c, state+1+i, 0); //1..8 |
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
|
239 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
240 for(i=e-1; i>=0; i--){ |
2338 | 241 put_rac(c, state+16+e+i, (a>>i)&1); //17..29 |
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 if(is_signed) |
2338 | 244 put_rac(c, state+9 + e, v < 0); //9..16 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
245 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
246 }else{ |
2338 | 247 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
|
248 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
249 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
250 |
2338 | 251 static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed, int max_exp){ |
252 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
|
253 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
254 else{ |
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
|
255 int i, e; |
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
|
256 |
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
|
257 for(e=0; e<max_exp; e++){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
258 int a= 1<<e; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
259 |
2338 | 260 if(get_rac(c, state + 1 + e)==0){ // 1..8 |
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
|
261 for(i=e-1; i>=0; i--){ |
2338 | 262 a += get_rac(c, state+16+e+i)<<i; //17..29 |
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
|
263 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
264 |
2338 | 265 if(is_signed && get_rac(c, state+9 + e)) //9..16 |
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
|
266 return -a; |
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
|
267 else |
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
|
268 return a; |
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
|
269 } |
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
|
270 } |
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
|
271 return -(1<<e); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
272 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
273 } |
1306 | 274 |
275 static inline void update_vlc_state(VlcState * const state, const int v){ | |
276 int drift= state->drift; | |
277 int count= state->count; | |
278 state->error_sum += ABS(v); | |
279 drift += v; | |
280 | |
281 if(count == 128){ //FIXME variable | |
282 count >>= 1; | |
283 drift >>= 1; | |
284 state->error_sum >>= 1; | |
285 } | |
286 count++; | |
287 | |
288 if(drift <= -count){ | |
289 if(state->bias > -128) state->bias--; | |
290 | |
291 drift += count; | |
292 if(drift <= -count) | |
293 drift= -count + 1; | |
294 }else if(drift > 0){ | |
295 if(state->bias < 127) state->bias++; | |
296 | |
297 drift -= count; | |
298 if(drift > 0) | |
299 drift= 0; | |
300 } | |
301 | |
302 state->drift= drift; | |
303 state->count= count; | |
304 } | |
305 | |
1593 | 306 static inline void put_vlc_symbol(PutBitContext *pb, VlcState * const state, int v, int bits){ |
1306 | 307 int i, k, code; |
308 //printf("final: %d ", v); | |
1593 | 309 v = fold(v - state->bias, bits); |
310 | |
1306 | 311 i= state->count; |
312 k=0; | |
313 while(i < state->error_sum){ //FIXME optimize | |
314 k++; | |
315 i += i; | |
316 } | |
1361
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
317 |
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
318 assert(k<=8); |
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
319 |
1306 | 320 #if 0 // JPEG LS |
321 if(k==0 && 2*state->drift <= - state->count) code= v ^ (-1); | |
322 else code= v; | |
323 #else | |
324 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
|
325 #endif |
1306 | 326 |
327 //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 | 328 set_sr_golomb(pb, code, k, 12, bits); |
1306 | 329 |
330 update_vlc_state(state, v); | |
331 } | |
332 | |
1593 | 333 static inline int get_vlc_symbol(GetBitContext *gb, VlcState * const state, int bits){ |
1306 | 334 int k, i, v, ret; |
335 | |
336 i= state->count; | |
337 k=0; | |
338 while(i < state->error_sum){ //FIXME optimize | |
339 k++; | |
340 i += i; | |
341 } | |
1361
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
342 |
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
343 assert(k<=8); |
8479b875a989
golomb rice code cleanup / simplify (~0.5% compression gain and slightly faster)
michaelni
parents:
1360
diff
changeset
|
344 |
2220 | 345 v= get_sr_golomb(gb, k, 12, bits); |
1306 | 346 //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
|
347 |
1306 | 348 #if 0 // JPEG LS |
349 if(k==0 && 2*state->drift <= - state->count) v ^= (-1); | |
350 #else | |
351 v ^= ((2*state->drift + state->count)>>31); | |
352 #endif | |
353 | |
1593 | 354 ret= fold(v + state->bias, bits); |
1306 | 355 |
356 update_vlc_state(state, v); | |
357 //printf("final: %d\n", ret); | |
358 return ret; | |
359 } | |
360 | |
1605 | 361 static inline void 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
|
362 PlaneContext * const p= &s->plane[plane_index]; |
2338 | 363 RangeCoder * const c= &s->c; |
1593 | 364 int x; |
365 int run_index= s->run_index; | |
366 int run_count=0; | |
367 int run_mode=0; | |
368 | |
369 for(x=0; x<w; x++){ | |
370 int diff, context; | |
371 | |
1999 | 372 context= get_context(s, sample[0]+x, sample[1]+x, sample[2]+x); |
373 diff= sample[0][x] - predict(sample[0]+x, sample[1]+x); | |
1593 | 374 |
375 if(context < 0){ | |
376 context = -context; | |
377 diff= -diff; | |
378 } | |
379 | |
380 diff= fold(diff, bits); | |
381 | |
382 if(s->ac){ | |
383 put_symbol(c, p->state[context], diff, 1, bits-1); | |
384 }else{ | |
385 if(context == 0) run_mode=1; | |
386 | |
387 if(run_mode){ | |
388 | |
389 if(diff){ | |
390 while(run_count >= 1<<log2_run[run_index]){ | |
391 run_count -= 1<<log2_run[run_index]; | |
392 run_index++; | |
393 put_bits(&s->pb, 1, 1); | |
394 } | |
395 | |
396 put_bits(&s->pb, 1 + log2_run[run_index], run_count); | |
397 if(run_index) run_index--; | |
398 run_count=0; | |
399 run_mode=0; | |
400 if(diff>0) diff--; | |
401 }else{ | |
402 run_count++; | |
403 } | |
404 } | |
405 | |
1786 | 406 // 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 | 407 |
408 if(run_mode == 0) | |
409 put_vlc_symbol(&s->pb, &p->vlc_state[context], diff, bits); | |
410 } | |
411 } | |
412 if(run_mode){ | |
413 while(run_count >= 1<<log2_run[run_index]){ | |
414 run_count -= 1<<log2_run[run_index]; | |
415 run_index++; | |
416 put_bits(&s->pb, 1, 1); | |
417 } | |
418 | |
419 if(run_count) | |
420 put_bits(&s->pb, 1, 1); | |
421 } | |
422 s->run_index= run_index; | |
423 } | |
424 | |
425 static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ | |
1999 | 426 int x,y,i; |
2162 | 427 const int ring_size= s->avctx->context_model ? 3 : 2; |
1999 | 428 int_fast16_t sample_buffer[ring_size][w+6], *sample[ring_size]; |
1593 | 429 s->run_index=0; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
430 |
1337 | 431 memset(sample_buffer, 0, sizeof(sample_buffer)); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
432 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
433 for(y=0; y<h; y++){ |
1999 | 434 for(i=0; i<ring_size; i++) |
435 sample[i]= sample_buffer[(h+i-y)%ring_size]+3; | |
1306 | 436 |
1999 | 437 sample[0][-1]= sample[1][0 ]; |
438 sample[1][ w]= sample[1][w-1]; | |
1593 | 439 //{START_TIMER |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
440 for(x=0; x<w; x++){ |
1999 | 441 sample[0][x]= src[x + stride*y]; |
1593 | 442 } |
443 encode_line(s, w, sample, plane_index, 8); | |
444 //STOP_TIMER("encode line")} | |
445 } | |
446 } | |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
447 |
1593 | 448 static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ |
1999 | 449 int x, y, p, i; |
2162 | 450 const int ring_size= s->avctx->context_model ? 3 : 2; |
1999 | 451 int_fast16_t sample_buffer[3][ring_size][w+6], *sample[3][ring_size]; |
1593 | 452 s->run_index=0; |
453 | |
454 memset(sample_buffer, 0, sizeof(sample_buffer)); | |
455 | |
456 for(y=0; y<h; y++){ | |
1999 | 457 for(i=0; i<ring_size; i++) |
458 for(p=0; p<3; p++) | |
459 sample[p][i]= sample_buffer[p][(h+i-y)%ring_size]+3; | |
460 | |
1593 | 461 for(x=0; x<w; x++){ |
462 int v= src[x + stride*y]; | |
463 int b= v&0xFF; | |
464 int g= (v>>8)&0xFF; | |
465 int r= (v>>16)&0xFF; | |
466 | |
467 b -= g; | |
468 r -= g; | |
469 g += (b + r)>>2; | |
470 b += 0x100; | |
471 r += 0x100; | |
472 | |
473 // assert(g>=0 && b>=0 && r>=0); | |
474 // assert(g<256 && b<512 && r<512); | |
475 sample[0][0][x]= g; | |
476 sample[1][0][x]= b; | |
477 sample[2][0][x]= r; | |
478 } | |
479 for(p=0; p<3; p++){ | |
1999 | 480 sample[p][0][-1]= sample[p][1][0 ]; |
481 sample[p][1][ w]= sample[p][1][w-1]; | |
1593 | 482 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
|
483 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
484 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
485 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
486 |
2338 | 487 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
|
488 int last=0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
489 int i; |
2338 | 490 uint8_t state[CONTEXT_SIZE]; |
491 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
|
492 |
1306 | 493 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
|
494 if(quant_table[i] != quant_table[i-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
|
495 put_symbol(c, state, i-last-1, 0, 7); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
496 last= i; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
497 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
498 } |
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
|
499 put_symbol(c, state, i-last-1, 0, 7); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
500 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
501 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
502 static void write_header(FFV1Context *f){ |
2338 | 503 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
|
504 int i; |
2338 | 505 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
|
506 |
2338 | 507 memset(state, 128, sizeof(state)); |
508 | |
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
|
509 put_symbol(c, state, f->version, 0, 7); |
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
|
510 put_symbol(c, state, f->avctx->coder_type, 0, 7); |
1593 | 511 put_symbol(c, state, f->colorspace, 0, 7); //YUV cs type |
2338 | 512 put_rac(c, state, 1); //chroma planes |
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
|
513 put_symbol(c, state, f->chroma_h_shift, 0, 7); |
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
|
514 put_symbol(c, state, f->chroma_v_shift, 0, 7); |
2338 | 515 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
|
516 |
1306 | 517 for(i=0; i<5; i++) |
518 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
|
519 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
520 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
521 static int common_init(AVCodecContext *avctx){ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
522 FFV1Context *s = avctx->priv_data; |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
523 int width, height; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
524 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
525 s->avctx= avctx; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
526 s->flags= avctx->flags; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
527 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
528 dsputil_init(&s->dsp, avctx); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
529 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
530 width= s->width= avctx->width; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
531 height= s->height= avctx->height; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
532 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
533 assert(width && height); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
534 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
535 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
536 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
537 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
538 static int encode_init(AVCodecContext *avctx) |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
539 { |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
540 FFV1Context *s = avctx->priv_data; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
541 int i; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
542 |
2218 | 543 if(avctx->strict_std_compliance >= 0){ |
544 av_log(avctx, AV_LOG_ERROR, "this codec is under development, files encoded with it wont be decodeable with future versions!!!\n" | |
545 "use vstrict=-1 to use it anyway\n"); | |
546 return -1; | |
547 } | |
548 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
549 common_init(avctx); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
550 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
551 s->version=0; |
1306 | 552 s->ac= avctx->coder_type; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
553 |
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
|
554 s->plane_count=2; |
1306 | 555 for(i=0; i<256; i++){ |
556 s->quant_table[0][i]= quant11[i]; | |
557 s->quant_table[1][i]= 11*quant11[i]; | |
558 if(avctx->context_model==0){ | |
559 s->quant_table[2][i]= 11*11*quant11[i]; | |
560 s->quant_table[3][i]= | |
561 s->quant_table[4][i]=0; | |
562 }else{ | |
563 s->quant_table[2][i]= 11*11*quant5 [i]; | |
564 s->quant_table[3][i]= 5*11*11*quant5 [i]; | |
565 s->quant_table[4][i]= 5*5*11*11*quant5 [i]; | |
566 } | |
567 } | |
1300
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 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
|
570 PlaneContext * const p= &s->plane[i]; |
1306 | 571 |
572 if(avctx->context_model==0){ | |
573 p->context_count= (11*11*11+1)/2; | |
574 }else{ | |
575 p->context_count= (11*11*5*5*5+1)/2; | |
576 } | |
577 | |
578 if(s->ac){ | |
579 if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t)); | |
580 }else{ | |
581 if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState)); | |
582 } | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
583 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
584 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
585 avctx->coded_frame= &s->picture; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
586 switch(avctx->pix_fmt){ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
587 case PIX_FMT_YUV444P: |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
588 case PIX_FMT_YUV422P: |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
589 case PIX_FMT_YUV420P: |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
590 case PIX_FMT_YUV411P: |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
591 case PIX_FMT_YUV410P: |
1593 | 592 s->colorspace= 0; |
593 break; | |
594 case PIX_FMT_RGBA32: | |
595 s->colorspace= 1; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
596 break; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
597 default: |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
598 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
|
599 return -1; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
600 } |
1593 | 601 avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); |
602 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
603 s->picture_number=0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
604 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
605 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
606 } |
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 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
609 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
|
610 int i, j; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
611 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
612 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
|
613 PlaneContext *p= &f->plane[i]; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
614 |
2338 | 615 p->interlace_bit_state[0]= 128; |
616 p->interlace_bit_state[1]= 128; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
617 |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
618 for(j=0; j<p->context_count; j++){ |
1306 | 619 if(f->ac){ |
2338 | 620 memset(p->state[j], 128, sizeof(uint8_t)*CONTEXT_SIZE); |
621 p->state[j][7] = 256-8; | |
1306 | 622 }else{ |
623 p->vlc_state[j].drift= 0; | |
624 p->vlc_state[j].error_sum= 4; //FFMAX((RANGE + 32)/64, 2); | |
625 p->vlc_state[j].bias= 0; | |
626 p->vlc_state[j].count= 1; | |
627 } | |
1302
c41f51b5d5d6
reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
michaelni
parents:
1300
diff
changeset
|
628 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
629 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
630 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
631 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
632 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
|
633 FFV1Context *f = avctx->priv_data; |
2338 | 634 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
|
635 AVFrame *pict = data; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
636 const int width= f->width; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
637 const int height= f->height; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
638 AVFrame * const p= &f->picture; |
1306 | 639 int used_count= 0; |
2338 | 640 uint8_t keystate=128; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
641 |
2338 | 642 ff_init_range_encoder(c, buf, buf_size); |
643 // ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); | |
644 ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); | |
645 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
646 *p = *pict; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
647 p->pict_type= FF_I_TYPE; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
648 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
649 if(avctx->gop_size==0 || f->picture_number % avctx->gop_size == 0){ |
2338 | 650 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
|
651 p->key_frame= 1; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
652 write_header(f); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
653 clear_state(f); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
654 }else{ |
2338 | 655 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
|
656 p->key_frame= 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
657 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
658 |
1306 | 659 if(!f->ac){ |
2338 | 660 used_count += ff_rac_terminate(c); |
1306 | 661 //printf("pos=%d\n", used_count); |
1522
79dddc5cd990
removed the obsolete and unused parameters of init_put_bits
alex
parents:
1453
diff
changeset
|
662 init_put_bits(&f->pb, buf + used_count, buf_size - used_count); |
1306 | 663 } |
664 | |
1593 | 665 if(f->colorspace==0){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
666 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
|
667 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
|
668 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
669 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
|
670 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
671 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
|
672 encode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 1); |
1593 | 673 }else{ |
674 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
|
675 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
676 emms_c(); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
677 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
678 f->picture_number++; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
679 |
1306 | 680 if(f->ac){ |
2338 | 681 return ff_rac_terminate(c); |
1306 | 682 }else{ |
683 flush_put_bits(&f->pb); //nicer padding FIXME | |
1786 | 684 return used_count + (put_bits_count(&f->pb)+7)/8; |
1306 | 685 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
686 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
687 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
688 static void common_end(FFV1Context *s){ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
689 int i; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
690 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
691 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
|
692 PlaneContext *p= &s->plane[i]; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
693 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
694 av_freep(&p->state); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
695 } |
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 static int encode_end(AVCodecContext *avctx) |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
699 { |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
700 FFV1Context *s = avctx->priv_data; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
701 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
702 common_end(s); |
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 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
705 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
706 |
1605 | 707 static 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
|
708 PlaneContext * const p= &s->plane[plane_index]; |
2338 | 709 RangeCoder * const c= &s->c; |
1593 | 710 int x; |
711 int run_count=0; | |
712 int run_mode=0; | |
713 int run_index= s->run_index; | |
714 | |
715 for(x=0; x<w; x++){ | |
716 int diff, context, sign; | |
717 | |
718 context= get_context(s, sample[1] + x, sample[0] + x, sample[1] + x); | |
719 if(context < 0){ | |
720 context= -context; | |
721 sign=1; | |
722 }else | |
723 sign=0; | |
724 | |
725 | |
726 if(s->ac) | |
727 diff= get_symbol(c, p->state[context], 1, bits-1); | |
728 else{ | |
729 if(context == 0 && run_mode==0) run_mode=1; | |
730 | |
731 if(run_mode){ | |
732 if(run_count==0 && run_mode==1){ | |
733 if(get_bits1(&s->gb)){ | |
734 run_count = 1<<log2_run[run_index]; | |
735 if(x + run_count <= w) run_index++; | |
736 }else{ | |
737 if(log2_run[run_index]) run_count = get_bits(&s->gb, log2_run[run_index]); | |
738 else run_count=0; | |
739 if(run_index) run_index--; | |
740 run_mode=2; | |
741 } | |
742 } | |
743 run_count--; | |
744 if(run_count < 0){ | |
745 run_mode=0; | |
746 run_count=0; | |
747 diff= get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); | |
748 if(diff>=0) diff++; | |
749 }else | |
750 diff=0; | |
751 }else | |
752 diff= get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); | |
753 | |
754 // 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)); | |
755 } | |
756 | |
757 if(sign) diff= -diff; | |
758 | |
759 sample[1][x]= (predict(sample[1] + x, sample[0] + x) + diff) & ((1<<bits)-1); | |
760 } | |
761 s->run_index= run_index; | |
762 } | |
763 | |
764 static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ | |
765 int x, y; | |
766 int_fast16_t sample_buffer[2][w+6]; | |
767 int_fast16_t *sample[2]= {sample_buffer[0]+3, sample_buffer[1]+3}; | |
768 | |
769 s->run_index=0; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
770 |
1337 | 771 memset(sample_buffer, 0, sizeof(sample_buffer)); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
772 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
773 for(y=0; y<h; y++){ |
1593 | 774 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
|
775 |
1337 | 776 sample[0]= sample[1]; |
777 sample[1]= temp; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
778 |
1337 | 779 sample[1][-1]= sample[0][0 ]; |
780 sample[0][ w]= sample[0][w-1]; | |
1593 | 781 |
782 //{START_TIMER | |
783 decode_line(s, w, sample, plane_index, 8); | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
784 for(x=0; x<w; x++){ |
1593 | 785 src[x + stride*y]= sample[1][x]; |
786 } | |
787 //STOP_TIMER("decode-line")} | |
788 } | |
789 } | |
790 | |
791 static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ | |
792 int x, y, p; | |
793 int_fast16_t sample_buffer[3][2][w+6]; | |
794 int_fast16_t *sample[3][2]= { | |
795 {sample_buffer[0][0]+3, sample_buffer[0][1]+3}, | |
796 {sample_buffer[1][0]+3, sample_buffer[1][1]+3}, | |
797 {sample_buffer[2][0]+3, sample_buffer[2][1]+3}}; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
798 |
1593 | 799 s->run_index=0; |
800 | |
801 memset(sample_buffer, 0, sizeof(sample_buffer)); | |
802 | |
803 for(y=0; y<h; y++){ | |
804 for(p=0; p<3; p++){ | |
805 int_fast16_t *temp= sample[p][0]; //FIXME try a normal buffer | |
806 | |
807 sample[p][0]= sample[p][1]; | |
808 sample[p][1]= temp; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
809 |
1593 | 810 sample[p][1][-1]= sample[p][0][0 ]; |
811 sample[p][0][ w]= sample[p][0][w-1]; | |
812 decode_line(s, w, sample[p], FFMIN(p, 1), 9); | |
813 } | |
814 for(x=0; x<w; x++){ | |
815 int g= sample[0][1][x]; | |
816 int b= sample[1][1][x]; | |
817 int r= sample[2][1][x]; | |
1306 | 818 |
1593 | 819 // assert(g>=0 && b>=0 && r>=0); |
820 // assert(g<256 && b<512 && r<512); | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
821 |
1593 | 822 b -= 0x100; |
823 r -= 0x100; | |
824 g -= (b + r)>>2; | |
825 b += g; | |
826 r += g; | |
827 | |
828 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
|
829 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
830 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
831 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
832 |
2338 | 833 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
|
834 int v; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
835 int i=0; |
2338 | 836 uint8_t state[CONTEXT_SIZE]; |
837 | |
838 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
|
839 |
1306 | 840 for(v=0; i<128 ; v++){ |
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
|
841 int len= get_symbol(c, state, 0, 7) + 1; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
842 |
1306 | 843 if(len + i > 128) return -1; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
844 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
845 while(len--){ |
1306 | 846 quant_table[i] = scale*v; |
847 i++; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
848 //printf("%2d ",v); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
849 //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
|
850 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
851 } |
1306 | 852 |
853 for(i=1; i<128; i++){ | |
854 quant_table[256-i]= -quant_table[i]; | |
855 } | |
856 quant_table[128]= -quant_table[127]; | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
857 |
1306 | 858 return 2*v - 1; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
859 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
860 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
861 static int read_header(FFV1Context *f){ |
2338 | 862 uint8_t state[CONTEXT_SIZE]; |
1306 | 863 int i, context_count; |
2338 | 864 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
|
865 |
2338 | 866 memset(state, 128, sizeof(state)); |
867 | |
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
|
868 f->version= get_symbol(c, state, 0, 7); |
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
|
869 f->ac= f->avctx->coder_type= get_symbol(c, state, 0, 7); |
1593 | 870 f->colorspace= get_symbol(c, state, 0, 7); //YUV cs type |
2338 | 871 get_rac(c, state); //no chroma = false |
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
|
872 f->chroma_h_shift= get_symbol(c, state, 0, 7); |
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
|
873 f->chroma_v_shift= get_symbol(c, state, 0, 7); |
2338 | 874 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
|
875 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
|
876 |
1593 | 877 if(f->colorspace==0){ |
878 switch(16*f->chroma_h_shift + f->chroma_v_shift){ | |
879 case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P; break; | |
880 case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P; break; | |
881 case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P; break; | |
882 case 0x20: f->avctx->pix_fmt= PIX_FMT_YUV411P; break; | |
883 case 0x33: f->avctx->pix_fmt= PIX_FMT_YUV410P; break; | |
884 default: | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
885 av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); |
1593 | 886 return -1; |
887 } | |
888 }else if(f->colorspace==1){ | |
889 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
|
890 av_log(f->avctx, AV_LOG_ERROR, "chroma subsampling not supported in this colorspace\n"); |
1593 | 891 return -1; |
892 } | |
893 f->avctx->pix_fmt= PIX_FMT_RGBA32; | |
894 }else{ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
895 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
|
896 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
|
897 } |
1593 | 898 |
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
|
899 //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
|
900 |
1306 | 901 context_count=1; |
902 for(i=0; i<5; i++){ | |
903 context_count*= read_quant_table(c, f->quant_table[i], context_count); | |
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
|
904 if(context_count < 0){ |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1593
diff
changeset
|
905 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
|
906 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
|
907 } |
1306 | 908 } |
909 context_count= (context_count+1)/2; | |
910 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
911 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
|
912 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
|
913 |
1306 | 914 p->context_count= context_count; |
915 | |
916 if(f->ac){ | |
917 if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t)); | |
918 }else{ | |
919 if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState)); | |
920 } | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
921 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
922 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
923 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
924 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
925 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
926 static int decode_init(AVCodecContext *avctx) |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
927 { |
1306 | 928 // 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
|
929 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
930 common_init(avctx); |
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 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
933 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
934 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
935 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
936 FFV1Context *f = avctx->priv_data; |
2338 | 937 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
|
938 const int width= f->width; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
939 const int height= f->height; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
940 AVFrame * const p= &f->picture; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
941 int bytes_read; |
2338 | 942 uint8_t keystate= 128; |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
943 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
944 AVFrame *picture = data; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
945 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
946 /* no supplementary picture */ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
947 if (buf_size == 0) |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
948 return 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
949 |
2338 | 950 ff_init_range_decoder(c, buf, buf_size); |
951 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
|
952 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
953 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
954 p->pict_type= FF_I_TYPE; //FIXME I vs. P |
2338 | 955 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
|
956 p->key_frame= 1; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
957 read_header(f); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
958 clear_state(f); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
959 }else{ |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
960 p->key_frame= 0; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
961 } |
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
|
962 |
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
|
963 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
|
964 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
|
965 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
|
966 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
|
967 } |
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
|
968 |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
969 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
|
970 av_log(avctx, AV_LOG_ERROR, "keyframe:%d coder:%d\n", p->key_frame, f->ac); |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
971 |
1306 | 972 if(!f->ac){ |
2338 | 973 bytes_read = c->bytestream - c->bytestream_start - 1; |
974 if(bytes_read ==0) av_log(avctx, AV_LOG_ERROR, "error at end of AC stream\n"); //FIXME | |
1306 | 975 //printf("pos=%d\n", bytes_read); |
976 init_get_bits(&f->gb, buf + bytes_read, buf_size - bytes_read); | |
1453 | 977 } else { |
978 bytes_read = 0; /* avoid warning */ | |
1306 | 979 } |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
980 |
1593 | 981 if(f->colorspace==0){ |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
982 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
|
983 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
|
984 decode_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
|
985 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
986 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
|
987 decode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 1); |
1593 | 988 }else{ |
989 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
|
990 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
991 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
992 emms_c(); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
993 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
994 f->picture_number++; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
995 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
996 *picture= *p; |
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 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
|
999 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1000 *data_size = sizeof(AVFrame); |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1001 |
1306 | 1002 if(f->ac){ |
2338 | 1003 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
|
1004 if(bytes_read ==0) av_log(f->avctx, AV_LOG_ERROR, "error at end of frame\n"); |
1306 | 1005 }else{ |
1006 bytes_read+= (get_bits_count(&f->gb)+7)/8; | |
1007 } | |
1008 | |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1009 return bytes_read; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1010 } |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1011 |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1012 AVCodec ffv1_decoder = { |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1013 "ffv1", |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1014 CODEC_TYPE_VIDEO, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1015 CODEC_ID_FFV1, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1016 sizeof(FFV1Context), |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1017 decode_init, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1018 NULL, |
1994 | 1019 NULL, |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1020 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
|
1021 CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/, |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1022 NULL |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1023 }; |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1024 |
1325 | 1025 #ifdef CONFIG_ENCODERS |
1300
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1026 AVCodec ffv1_encoder = { |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1027 "ffv1", |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1028 CODEC_TYPE_VIDEO, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1029 CODEC_ID_FFV1, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1030 sizeof(FFV1Context), |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1031 encode_init, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1032 encode_frame, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1033 encode_end, |
e18667d1e94d
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
michaelni
parents:
diff
changeset
|
1034 }; |
1325 | 1035 #endif |