History

avcodec: add YUY2 Lossless Codec decoder

Paul B Mahol committed 10 years ago

Commit 8fb92ea1 parent 074fdf48 files · +488 −1Browse files

Unified · Split

8 files
  1. Changelog +4 −0
  2. libavcodec/Makefile +1 −0
  3. libavcodec/allcodecs.c +1 −0
  4. libavcodec/avcodec.h +1 −0
  5. libavcodec/codec_desc.c +7 −0
  6. libavcodec/version.h +1 −1
  7. libavcodec/ylc.c +472 −0
  8. libavformat/riff.c +1 −0
Changelog+4−0
@@ -2,6 +2,10 @@ Entries are sorted chronologically from oldest to youngest within each release, · 1 unmodified line
2releases are sorted from youngest to oldest.2releases are sorted from youngest to oldest.
3 3
4version <next>:4version <next>:
5- YUY2 Lossless Codec decoder
6
7
8version 3.1:
5- DXVA2-accelerated HEVC Main10 decoding9- DXVA2-accelerated HEVC Main10 decoding
6- fieldhint filter10- fieldhint filter
7- loop video filter and aloop audio filter11- loop video filter and aloop audio filter
libavcodec/Makefile+1−0
@@ -633,6 +633,7 @@ OBJS-$(CONFIG_XWD_DECODER) += xwddec.o · 632 unmodified lines
633OBJS-$(CONFIG_XWD_ENCODER) += xwdenc.o633OBJS-$(CONFIG_XWD_ENCODER) += xwdenc.o
634OBJS-$(CONFIG_Y41P_DECODER) += y41pdec.o634OBJS-$(CONFIG_Y41P_DECODER) += y41pdec.o
635OBJS-$(CONFIG_Y41P_ENCODER) += y41penc.o635OBJS-$(CONFIG_Y41P_ENCODER) += y41penc.o
636OBJS-$(CONFIG_YLC_DECODER) += ylc.o
636OBJS-$(CONFIG_YOP_DECODER) += yop.o637OBJS-$(CONFIG_YOP_DECODER) += yop.o
637OBJS-$(CONFIG_YUV4_DECODER) += yuv4dec.o638OBJS-$(CONFIG_YUV4_DECODER) += yuv4dec.o
638OBJS-$(CONFIG_YUV4_ENCODER) += yuv4enc.o639OBJS-$(CONFIG_YUV4_ENCODER) += yuv4enc.o
libavcodec/allcodecs.c+1−0
@@ -370,6 +370,7 @@ void avcodec_register_all(void) · 369 unmodified lines
370 REGISTER_DECODER(XL, xl);370 REGISTER_DECODER(XL, xl);
371 REGISTER_ENCDEC (XWD, xwd);371 REGISTER_ENCDEC (XWD, xwd);
372 REGISTER_ENCDEC (Y41P, y41p);372 REGISTER_ENCDEC (Y41P, y41p);
373 REGISTER_DECODER(YLC, ylc);
373 REGISTER_DECODER(YOP, yop);374 REGISTER_DECODER(YOP, yop);
374 REGISTER_ENCDEC (YUV4, yuv4);375 REGISTER_ENCDEC (YUV4, yuv4);
375 REGISTER_DECODER(ZERO12V, zero12v);376 REGISTER_DECODER(ZERO12V, zero12v);
libavcodec/avcodec.h+1−0
@@ -408,6 +408,7 @@ enum AVCodecID { · 407 unmodified lines
408 AV_CODEC_ID_M101,408 AV_CODEC_ID_M101,
409 AV_CODEC_ID_MAGICYUV,409 AV_CODEC_ID_MAGICYUV,
410 AV_CODEC_ID_SHEERVIDEO,410 AV_CODEC_ID_SHEERVIDEO,
411 AV_CODEC_ID_YLC,
411 412
412 /* various PCM "codecs" */413 /* various PCM "codecs" */
413 AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs414 AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
libavcodec/codec_desc.c+7−0
@@ -1556,6 +1556,13 @@ static const AVCodecDescriptor codec_descriptors[] = { · 1555 unmodified lines
1556 .long_name = NULL_IF_CONFIG_SMALL("BitJazz SheerVideo"),1556 .long_name = NULL_IF_CONFIG_SMALL("BitJazz SheerVideo"),
1557 .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,1557 .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
1558 },1558 },
1559 {
1560 .id = AV_CODEC_ID_YLC,
1561 .type = AVMEDIA_TYPE_VIDEO,
1562 .name = "ylc",
1563 .long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"),
1564 .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
1565 },
1559 1566
1560 /* various PCM "codecs" */1567 /* various PCM "codecs" */
1561 {1568 {
libavcodec/version.h+1−1
@@ -28,7 +28,7 @@ · 27 unmodified lines
28#include "libavutil/version.h"28#include "libavutil/version.h"
29 29
30#define LIBAVCODEC_VERSION_MAJOR 5730#define LIBAVCODEC_VERSION_MAJOR 57
31#define LIBAVCODEC_VERSION_MINOR 4731#define LIBAVCODEC_VERSION_MINOR 48
32#define LIBAVCODEC_VERSION_MICRO 10032#define LIBAVCODEC_VERSION_MICRO 100
33 33
34#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \34#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
libavcodec/ylc.c+472−0
@@ -0,0 +1,472 @@
1/*
2 * YUY2 Lossless Codec
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include "libavutil/imgutils.h"
26#include "libavutil/internal.h"
27#include "libavutil/intreadwrite.h"
28#include "libavutil/mem.h"
29#include "avcodec.h"
30#include "bswapdsp.h"
31#include "get_bits.h"
32#include "huffyuvdsp.h"
33#include "internal.h"
34#include "unary.h"
35
36typedef struct YLCContext {
37 VLC vlc[4];
38 uint32_t table[1024];
39 uint8_t *table_bits;
40 uint8_t *bitstream_bits;
41 int table_bits_size;
42 int bitstream_bits_size;
43 BswapDSPContext bdsp;
44} YLCContext;
45
46static av_cold int decode_init(AVCodecContext *avctx)
47{
48 YLCContext *s = avctx->priv_data;
49
50 avctx->pix_fmt = AV_PIX_FMT_YUYV422;
51 ff_bswapdsp_init(&s->bdsp);
52
53 return 0;
54}
55
56typedef struct Node {
57 int16_t sym;
58 int16_t n0;
59 uint32_t count;
60 int16_t l, r;
61} Node;
62
63static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat,
64 Node *nodes, int node,
65 uint32_t pfx, int pl, int *pos)
66{
67 int s;
68
69 s = nodes[node].sym;
70 if (s != -1) {
71 bits[*pos] = (~pfx) & ((1 << FFMAX(pl, 1)) - 1);
72 lens[*pos] = FFMAX(pl, 1);
73 xlat[*pos] = s + (pl == 0);
74 (*pos)++;
75 } else {
76 pfx <<= 1;
77 pl++;
78 get_tree_codes(bits, lens, xlat, nodes, nodes[node].l, pfx, pl,
79 pos);
80 pfx |= 1;
81 get_tree_codes(bits, lens, xlat, nodes, nodes[node].r, pfx, pl,
82 pos);
83 }
84}
85
86static int build_vlc(AVCodecContext *avctx, VLC *vlc, const uint32_t *table)
87{
88 Node nodes[512];
89 uint32_t bits[256];
90 int16_t lens[256];
91 uint8_t xlat[256];
92 int cur_node, i, j, pos = 0;
93
94 ff_free_vlc(vlc);
95
96 for (i = 0; i < 256; i++) {
97 nodes[i].count = table[i];
98 nodes[i].sym = i;
99 nodes[i].n0 = -2;
100 nodes[i].l = i;
101 nodes[i].r = i;
102 }
103
104 cur_node = 256;
105 j = 0;
106 do {
107 for (i = 0; ; i++) {
108 int new_node = j;
109 int first_node = cur_node;
110 int second_node = cur_node;
111 int nd, st;
112
113 nodes[cur_node].count = -1;
114
115 do {
116 int val = nodes[new_node].count;
117 if (val && (val < nodes[first_node].count)) {
118 if (val >= nodes[second_node].count) {
119 first_node = new_node;
120 } else {
121 first_node = second_node;
122 second_node = new_node;
123 }
124 }
125 new_node += 1;
126 } while (new_node != cur_node);
127
128 if (first_node == cur_node)
129 break;
130
131 nd = nodes[second_node].count;
132 st = nodes[first_node].count;
133 nodes[second_node].count = 0;
134 nodes[first_node].count = 0;
135 nodes[cur_node].count = nd + st;
136 nodes[cur_node].sym = -1;
137 nodes[cur_node].n0 = cur_node;
138 nodes[cur_node].l = first_node;
139 nodes[cur_node].r = second_node;
140 cur_node++;
141 }
142 j++;
143 } while (cur_node - 256 == j);
144
145 get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos);
146
147 return ff_init_vlc_sparse(vlc, 10, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0);
148}
149
150static const uint8_t table_y1[] = {
151 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
152 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
153 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
154 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
155 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
156 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
157 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
158 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
160 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
161 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
162 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
168 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
169 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
170 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
171 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
172 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
173 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
174 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
175 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
176 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
177 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
178 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
179 0x02, 0x00,
180};
181
182static const uint8_t table_u[] = {
183 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
184 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
187 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
188 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF,
189 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
190 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
193 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
194 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
195 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
196 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
199 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF,
200 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
201 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
204 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
205 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
206 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
207 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
210 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
211 0x01, 0x00,
212};
213
214static const uint8_t table_y2[] = {
215 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
216 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC,
217 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE,
218 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, 0xFC,
219 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF,
220 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD,
221 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
222 0x00, 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE,
223 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
224 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE,
225 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
226 0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
227 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
228 0x02, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00,
229 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
230 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
231 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0xFF,
232 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
233 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF,
234 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
235 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF,
236 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
237 0x02, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01,
238 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
239 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01,
240 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04,
241 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
242 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04,
243 0x04, 0x00,
244};
245
246static const uint8_t table_v[] = {
247 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
248 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
249 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
250 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
251 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
252 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
253 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
254 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
255 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
256 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
257 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
258 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
259 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
260 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
261 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
262 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
263 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
264 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
265 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
266 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
267 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
268 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
269 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
270 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
271 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
272 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF,
273 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01,
274 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00,
275 0x01, 0x00,
276};
277
278static int decode_frame(AVCodecContext *avctx,
279 void *data, int *got_frame,
280 AVPacket *avpkt)
281{
282 int TL[4] = { 128, 128, 128, 128 };
283 int L[4] = { 128, 128, 128, 128 };
284 YLCContext *s = avctx->priv_data;
285 const uint8_t *buf = avpkt->data;
286 int ret, x, y, toffset, boffset;
287 AVFrame * const p = data;
288 GetBitContext gb;
289 uint8_t *dst;
290
291 if (avpkt->size <= 16)
292 return AVERROR_INVALIDDATA;
293
294 if (AV_RL32(buf) != MKTAG('Y', 'L', 'C', '0') ||
295 AV_RL32(buf + 4) != 0)
296 return AVERROR_INVALIDDATA;
297
298 toffset = AV_RL32(buf + 8);
299 if (toffset < 16 || toffset >= avpkt->size)
300 return AVERROR_INVALIDDATA;
301
302 boffset = AV_RL32(buf + 12);
303 if (toffset >= boffset || boffset >= avpkt->size)
304 return AVERROR_INVALIDDATA;
305
306 if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
307 return ret;
308
309 av_fast_malloc(&s->table_bits, &s->table_bits_size,
310 boffset - toffset + AV_INPUT_BUFFER_PADDING_SIZE);
311 if (!s->table_bits)
312 return AVERROR(ENOMEM);
313
314 memcpy(s->table_bits, avpkt->data + toffset, boffset - toffset);
315 memset(s->table_bits + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
316 s->bdsp.bswap_buf((uint32_t *) s->table_bits,
317 (uint32_t *) s->table_bits,
318 (boffset - toffset + 3) >> 2);
319 if ((ret = init_get_bits8(&gb, s->table_bits, boffset - toffset)) < 0)
320 return ret;
321
322 for (x = 0; x < 1024; x++) {
323 unsigned len = get_unary(&gb, 1, 31);
324 uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len);
325
326 s->table[x] = val;
327 }
328
329 ret = build_vlc(avctx, &s->vlc[0], &s->table[0 ]);
330 if (ret < 0)
331 return ret;
332 ret = build_vlc(avctx, &s->vlc[1], &s->table[256]);
333 if (ret < 0)
334 return ret;
335 ret = build_vlc(avctx, &s->vlc[2], &s->table[512]);
336 if (ret < 0)
337 return ret;
338 ret = build_vlc(avctx, &s->vlc[3], &s->table[768]);
339 if (ret < 0)
340 return ret;
341
342 av_fast_malloc(&s->bitstream_bits, &s->bitstream_bits_size,
343 avpkt->size - boffset + AV_INPUT_BUFFER_PADDING_SIZE);
344 if (!s->bitstream_bits)
345 return AVERROR(ENOMEM);
346
347 memcpy(s->bitstream_bits, avpkt->data + boffset, avpkt->size - boffset);
348 memset(s->bitstream_bits + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE);
349 s->bdsp.bswap_buf((uint32_t *) s->bitstream_bits,
350 (uint32_t *) s->bitstream_bits,
351 (avpkt->size - boffset) >> 2);
352 if ((ret = init_get_bits8(&gb, s->bitstream_bits, avpkt->size - boffset)) < 0)
353 return ret;
354
355 dst = p->data[0];
356 for (y = 0; y < avctx->height; y++) {
357 memset(dst, 0, avctx->width * 2);
358 dst += p->linesize[0];
359 }
360
361 dst = p->data[0];
362 for (y = 0; y < avctx->height; y++) {
363 for (x = 0; x < avctx->width * 2 && y < avctx->height;) {
364 if (get_bits_left(&gb) <= 0)
365 return AVERROR_INVALIDDATA;
366
367 if (get_bits1(&gb)) {
368 int val = get_vlc2(&gb, s->vlc[0].table, s->vlc[0].bits, 3);
369 if (val < 0) {
370 return AVERROR_INVALIDDATA;
371 } else if (val < 0xE1) {
372 dst[x ] = table_y1[val];
373 dst[x + 1] = table_u[val];
374 dst[x + 2] = table_y2[val];
375 dst[x + 3] = table_v[val];
376 x += 4;
377 } else {
378 int incr = (val - 0xDF) * 4;
379 if (x + incr >= avctx->width * 2) {
380 int iy = ((x + incr) / (avctx->width * 2));
381 x = (x + incr) % (avctx->width * 2);
382 y += iy;
383 dst += iy * p->linesize[0];
384 } else {
385 x += incr;
386 }
387 }
388 } else {
389 int y1, y2, u, v;
390
391 y1 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3);
392 u = get_vlc2(&gb, s->vlc[2].table, s->vlc[2].bits, 3);
393 y2 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3);
394 v = get_vlc2(&gb, s->vlc[3].table, s->vlc[3].bits, 3);
395 if (y1 < 0 || y2 < 0 || u < 0 || v < 0)
396 return AVERROR_INVALIDDATA;
397 dst[x ] = y1;
398 dst[x + 1] = u;
399 dst[x + 2] = y1 + y2;
400 dst[x + 3] = v;
401 x += 4;
402 }
403 }
404 dst += p->linesize[0];
405 }
406
407 dst = p->data[0];
408 for (x = 0; x < avctx->width * 2; x += 4) {
409 dst[x ] = dst[x ] + L[0];
410 dst[x + 2] = L[0] = dst[x + 2] + L[0];
411 L[1] = dst[x + 1] + L[1];
412 dst[x + 1] = L[1];
413 L[2] = dst[x + 3] + L[2];
414 dst[x + 3] = L[2];
415 }
416 dst += p->linesize[0];
417
418 for (y = 1; y < avctx->height; y++) {
419 x = 0;
420 dst[x ] = dst[x ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
421 dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
422 TL[0] = dst[x + 2 - p->linesize[0]];
423 L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
424 dst[x + 1] = L[1];
425 TL[1] = dst[x + 1 - p->linesize[0]];
426 L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
427 dst[x + 3] = L[2];
428 TL[2] = dst[x + 3 - p->linesize[0]];
429 for (x = 4; x < avctx->width * 2; x += 4) {
430 dst[x ] = dst[x ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0];
431 dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0];
432 TL[0] = dst[x + 2 - p->linesize[0]];
433 L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1];
434 dst[x + 1] = L[1];
435 TL[1] = dst[x + 1 - p->linesize[0]];
436 L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2];
437 dst[x + 3] = L[2];
438 TL[2] = dst[x + 3 - p->linesize[0]];
439 }
440 dst += p->linesize[0];
441 }
442
443 p->pict_type = AV_PICTURE_TYPE_I;
444 p->key_frame = 1;
445 *got_frame = 1;
446
447 return avpkt->size;
448}
449
450static av_cold int decode_end(AVCodecContext *avctx)
451{
452 YLCContext *s = avctx->priv_data;
453
454 ff_free_vlc(&s->vlc[0]);
455 ff_free_vlc(&s->vlc[1]);
456 ff_free_vlc(&s->vlc[2]);
457 ff_free_vlc(&s->vlc[3]);
458
459 return 0;
460}
461
462AVCodec ff_ylc_decoder = {
463 .name = "ylc",
464 .long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"),
465 .type = AVMEDIA_TYPE_VIDEO,
466 .id = AV_CODEC_ID_YLC,
467 .priv_data_size = sizeof(YLCContext),
468 .init = decode_init,
469 .close = decode_end,
470 .decode = decode_frame,
471 .capabilities = AV_CODEC_CAP_DR1,
472};
libavformat/riff.c+1−0
@@ -424,6 +424,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { · 423 unmodified lines
424 { AV_CODEC_ID_M101, MKTAG('M', '1', '0', '1') },424 { AV_CODEC_ID_M101, MKTAG('M', '1', '0', '1') },
425 { AV_CODEC_ID_M101, MKTAG('M', '1', '0', '2') },425 { AV_CODEC_ID_M101, MKTAG('M', '1', '0', '2') },
426 { AV_CODEC_ID_MAGICYUV, MKTAG('M', 'A', 'G', 'Y') },426 { AV_CODEC_ID_MAGICYUV, MKTAG('M', 'A', 'G', 'Y') },
427 { AV_CODEC_ID_YLC, MKTAG('Y', 'L', 'C', '0') },
427 428
428 { AV_CODEC_ID_NONE, 0 }429 { AV_CODEC_ID_NONE, 0 }
429};430};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t