3 * Copyright (c) 2011 Derek Buitenhuis
5 * This file is part of Libav.
7 * Libav is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * Libav is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #define BITSTREAM_READER_LE
36 AVCodecContext
*avctx
;
40 uint8_t *val
; /* First holds the lengths of vlc symbols and then their values */
43 static uint8_t vble_read_reverse_unary(GetBitContext
*gb
)
45 /* At most we need to read 9 bits total to get indices up to 8 */
46 uint8_t val
= show_bits(gb
, 8);
49 val
= 7 - av_log2_16bit(ff_reverse
[val
]);
50 skip_bits(gb
, val
+ 1);
58 /* Return something larger than 8 on error */
62 static int vble_unpack(VBLEContext
*ctx
, GetBitContext
*gb
)
66 /* Read all the lengths in first */
67 for (i
= 0; i
< ctx
->size
; i
++) {
68 ctx
->val
[i
] = vble_read_reverse_unary(gb
);
70 if (ctx
->val
[i
] == UINT8_MAX
)
74 for (i
= 0; i
< ctx
->size
; i
++) {
75 /* Check we have enough bits left */
76 if (get_bits_left(gb
) < ctx
->val
[i
])
79 /* get_bits can't take a length of 0 */
81 ctx
->val
[i
] = (1 << ctx
->val
[i
]) + get_bits(gb
, ctx
->val
[i
]) - 1;
87 static void vble_restore_plane(VBLEContext
*ctx
, AVFrame
*pic
,
88 int plane
, int offset
,
89 int width
, int height
)
91 uint8_t *dst
= pic
->data
[plane
];
92 uint8_t *val
= ctx
->val
+ offset
;
93 int stride
= pic
->linesize
[plane
];
94 int i
, j
, left
, left_top
;
96 for (i
= 0; i
< height
; i
++) {
97 for (j
= 0; j
< width
; j
++)
98 val
[j
] = (val
[j
] >> 1) ^ -(val
[j
] & 1);
102 left_top
= dst
[-stride
];
103 ctx
->dsp
.add_hfyu_median_prediction(dst
, dst
-stride
, val
,
104 width
, &left
, &left_top
);
107 for (j
= 1; j
< width
; j
++)
108 dst
[j
] = val
[j
] + dst
[j
- 1];
115 static int vble_decode_frame(AVCodecContext
*avctx
, void *data
, int *got_frame
,
118 VBLEContext
*ctx
= avctx
->priv_data
;
121 const uint8_t *src
= avpkt
->data
;
124 int width_uv
= avctx
->width
/ 2, height_uv
= avctx
->height
/ 2;
126 /* Allocate buffer */
127 if (ff_get_buffer(avctx
, pic
, 0) < 0) {
128 av_log(avctx
, AV_LOG_ERROR
, "Could not allocate buffer.\n");
129 return AVERROR(ENOMEM
);
134 pic
->pict_type
= AV_PICTURE_TYPE_I
;
136 /* Version should always be 1 */
137 version
= AV_RL32(src
);
140 av_log(avctx
, AV_LOG_WARNING
, "Unsupported VBLE Version: %d\n", version
);
142 init_get_bits(&gb
, src
+ 4, (avpkt
->size
- 4) * 8);
145 if (vble_unpack(ctx
, &gb
) < 0) {
146 av_log(avctx
, AV_LOG_ERROR
, "Invalid Code\n");
147 return AVERROR_INVALIDDATA
;
150 /* Restore planes. Should be almost identical to Huffyuv's. */
151 vble_restore_plane(ctx
, pic
, 0, offset
, avctx
->width
, avctx
->height
);
154 if (!(ctx
->avctx
->flags
& CODEC_FLAG_GRAY
)) {
155 offset
+= avctx
->width
* avctx
->height
;
156 vble_restore_plane(ctx
, pic
, 1, offset
, width_uv
, height_uv
);
158 offset
+= width_uv
* height_uv
;
159 vble_restore_plane(ctx
, pic
, 2, offset
, width_uv
, height_uv
);
167 static av_cold
int vble_decode_close(AVCodecContext
*avctx
)
169 VBLEContext
*ctx
= avctx
->priv_data
;
175 static av_cold
int vble_decode_init(AVCodecContext
*avctx
)
177 VBLEContext
*ctx
= avctx
->priv_data
;
179 /* Stash for later use */
181 ff_dsputil_init(&ctx
->dsp
, avctx
);
183 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
184 avctx
->bits_per_raw_sample
= 8;
186 ctx
->size
= avpicture_get_size(avctx
->pix_fmt
,
187 avctx
->width
, avctx
->height
);
189 ctx
->val
= av_malloc(ctx
->size
* sizeof(*ctx
->val
));
192 av_log(avctx
, AV_LOG_ERROR
, "Could not allocate values buffer.\n");
193 vble_decode_close(avctx
);
194 return AVERROR(ENOMEM
);
200 AVCodec ff_vble_decoder
= {
202 .type
= AVMEDIA_TYPE_VIDEO
,
203 .id
= AV_CODEC_ID_VBLE
,
204 .priv_data_size
= sizeof(VBLEContext
),
205 .init
= vble_decode_init
,
206 .close
= vble_decode_close
,
207 .decode
= vble_decode_frame
,
208 .capabilities
= CODEC_CAP_DR1
,
209 .long_name
= NULL_IF_CONFIG_SMALL("VBLE Lossless Codec"),