FFmpeg: libavcodec/clearvideo.c Source File
Go to the documentation of this file. 1 /*
2 * ClearVideo decoder
3 * Copyright (c) 2012-2018 Konstantin Shishkov
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg 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.
11 *
12 * FFmpeg 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.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * ClearVideo decoder
25 */
26
29
38
39 #define CLV_VLC_BITS 9
40
46
50
52
61
77
81
83 int ac_quant)
84 {
86 int idx = 1, last = 0,
val,
skip;
87
88 memset(
blk, 0,
sizeof(*
blk) * 64);
90
91 if (!has_ac)
92 return 0;
93
94 while (idx < 64 && !last) {
104 } else {
108 }
111 val = ac_quant * (2 * aval + 1);
112 if (!(ac_quant & 1))
114 if (sign)
116 }
118 if (idx >= 64)
121 }
122
123 return (idx <= 64 && last) ? 0 : -1;
124 }
125
126 #define DCT_TEMPLATE(blk, step, bias, shift, dshift, OP) \
127 const int t0 = OP(2841 * blk[1 * step] + 565 * blk[7 * step]); \
128 const int t1 = OP( 565 * blk[1 * step] - 2841 * blk[7 * step]); \
129 const int t2 = OP(1609 * blk[5 * step] + 2408 * blk[3 * step]); \
130 const int t3 = OP(2408 * blk[5 * step] - 1609 * blk[3 * step]); \
131 const int t4 = OP(1108 * blk[2 * step] - 2676 * blk[6 * step]); \
132 const int t5 = OP(2676 * blk[2 * step] + 1108 * blk[6 * step]); \
133 const int t6 = ((blk[0 * step] + blk[4 * step]) * (1 << dshift)) + bias; \
134 const int t7 = ((blk[0 * step] - blk[4 * step]) * (1 << dshift)) + bias; \
135 const int t8 = t0 + t2; \
136 const int t9 = t0 - t2; \
137 const int tA = (int)(181U * (t9 + (t1 - t3)) + 0x80) >> 8; \
138 const int tB = (int)(181U * (t9 - (t1 - t3)) + 0x80) >> 8; \
139 const int tC = t1 + t3; \
140 \
141 blk[0 * step] = (t6 + t5 + t8) >> shift; \
142 blk[1 * step] = (t7 + t4 + tA) >> shift; \
143 blk[2 * step] = (t7 - t4 + tB) >> shift; \
144 blk[3 * step] = (t6 - t5 + tC) >> shift; \
145 blk[4 * step] = (t6 - t5 - tC) >> shift; \
146 blk[5 * step] = (t7 - t4 - tB) >> shift; \
147 blk[6 * step] = (t7 + t4 - tA) >> shift; \
148 blk[7 * step] = (t6 + t5 - t8) >> shift; \
149
151 #define COP(x) (((x) + 4) >> 3)
152
154 {
156 int16_t *ptr;
157
159 for (
i = 0;
i < 8;
i++) {
161 ptr += 8;
162 }
163
165 for (
i = 0;
i < 8;
i++) {
167 ptr++;
168 }
169 }
170
172 {
173 int i, has_ac[6], off;
174
175 for (
i = 0;
i < 6;
i++)
177
178 off = x * 16 + y * 16 *
c->pic->linesize[0];
179 for (
i = 0;
i < 4;
i++) {
182 if (!x && !(
i & 1)) {
183 c->block[0] +=
c->top_dc[0];
184 c->top_dc[0] =
c->block[0];
185 } else {
186 c->block[0] +=
c->left_dc[(
i & 2) >> 1];
187 }
188 c->left_dc[(
i & 2) >> 1] =
c->block[0];
189 c->block[0] *=
c->luma_dc_quant;
192 off +=
c->pic->linesize[0] * 8;
193 c->idsp.put_pixels_clamped(
c->block,
194 c->pic->data[0] + off + (
i & 1) * 8,
195 c->pic->linesize[0]);
196 }
197
198 off = x * 8 + y * 8 *
c->pic->linesize[1];
199 for (
i = 1;
i < 3;
i++) {
202 if (!x) {
203 c->block[0] +=
c->top_dc[
i];
204 c->top_dc[
i] =
c->block[0];
205 } else {
206 c->block[0] +=
c->left_dc[
i + 1];
207 }
208 c->left_dc[
i + 1] =
c->block[0];
209 c->block[0] *=
c->chroma_dc_quant;
211 c->idsp.put_pixels_clamped(
c->block,
c->pic->data[
i] + off,
212 c->pic->linesize[
i]);
213 }
214
215 return 0;
216 }
217
219 int plane,
int x,
int y,
int dx,
int dy,
int size)
220 {
221 int shift = plane > 0;
222 int sx = x + dx;
223 int sy = y + dy;
224 int sstride, dstride, soff, doff;
225 uint8_t *dbuf;
226 const uint8_t *sbuf;
228
229 if (x < 0 || sx < 0 || y < 0 || sy < 0 ||
235
236 sstride =
src->linesize[plane];
238 soff = sx + sy * sstride;
239 sbuf =
src->data[plane];
240 doff = x + y * dstride;
241 dbuf = dst->
data[plane];
242
244 uint8_t *dptr = &dbuf[doff];
245 const uint8_t *sptr = &sbuf[soff];
246
247 memcpy(dptr, sptr,
size);
248 doff += dstride;
249 soff += sstride;
250 }
251
252 return 0;
253 }
254
256 int plane,
int x,
int y,
int dx,
int dy,
int size,
int bias)
257 {
258 int shift = plane > 0;
259 int sx = x + dx;
260 int sy = y + dy;
261 int sstride =
src->linesize[plane];
263 int soff = sx + sy * sstride;
264 const uint8_t *sbuf =
src->data[plane];
265 int doff = x + y * dstride;
266 uint8_t *dbuf = dst->
data[plane];
268
269 if (x < 0 || sx < 0 || y < 0 || sy < 0 ||
275
276 for (j = 0; j <
size; j++) {
277 uint8_t *dptr = &dbuf[doff];
278 const uint8_t *sptr = &sbuf[soff];
279
282
284 }
285
286 doff += dstride;
287 soff += sstride;
288 }
289
290 return 0;
291 }
292
294 {
296 int left_mv, right_mv, top_mv, bot_mv;
297
299 if (mb_x > 0) {
301 } else {
303 }
304 }
else if ((mb_x == 0) || (mb_x == mvi->
mb_w - 1)) {
306 } else {
308 MV B = mvi->
mv[ mb_x ];
309 MV C = mvi->
mv[ mb_x + 1];
312 }
313
315
316 left_mv = -((mb_x * mvi->
mb_size));
317 right_mv = ((mvi->
mb_w - mb_x - 1) * mvi->
mb_size);
318 if (res.
x < left_mv) {
320 }
321 if (res.
x > right_mv) {
323 }
324 top_mv = -((mb_y * mvi->
mb_size));
326 if (res.
y < top_mv) {
328 }
329 if (res.
y > bot_mv) {
331 }
332
335
337 }
338
340 {
343 }
344
346 {
353 }
354
356 {
358
362 }
363 }
364
366 int plane,
int x,
int y,
int dx,
int dy,
int size,
int bias)
367 {
369
372 } else {
374 }
375
377 }
378
382 int plane,
int x,
int y,
int size,
384 {
388 int err;
389
392
395
397 mv.x = (int8_t)(mv_code & 0xff);
398 mv.y = (int8_t)(mv_code >> 8);
399 } else {
402 }
405 }
408
411
413 bias = (int16_t)(bias_val);
414 } else {
416 }
417 }
418
420 int hsize =
size >> 1;
421 for (
i = 0;
i < 4;
i++) {
422 int xoff = (
i & 2) == 0 ? 0 : hsize;
423 int yoff = (
i & 1) == 0 ? 0 : hsize;
424
427 x + xoff, y + yoff, hsize, root_mv,
NULL);
428 } else {
431 }
432 if (err < 0)
433 return err;
434 }
435 } else {
437 if (err < 0)
438 return err;
439 }
440
441 return 0;
442 }
443
445 {
447
452 int size =
comp == 0 ? tile_size : tile_size >> 1;
454 uint8_t *framebuf = buf->
data[
comp];
455
458
459 if ((right ==
size) && (bottom ==
size)) {
460 return;
461 }
464 for (j = 0; j <
h; j++) {
465 for (
i = 0;
i < right;
i++) {
466 framebuf[off +
i] = 0x80;
467 }
469 }
470 }
471 if (bottom !=
size) {
473 for (j = 0; j < bottom; j++) {
475 framebuf[off +
i] = 0x80;
476 }
478 }
479 }
480 }
481 }
482
485 {
486 const uint8_t *buf = avpkt->
data;
487 int buf_size = avpkt->
size;
492 int mb_ret = 0;
493
496 int skip = bytestream2_get_byte(&gb);
498 }
499
501
503 *got_frame = 0;
504 return buf_size;
506 if (buf_size < c->mb_width *
c->mb_height) {
509 }
510
513
514 c->pic->key_frame = 1;
516
517 bytestream2_get_be32(&gb); // frame size;
518 c->ac_quant = bytestream2_get_byte(&gb);
519 c->luma_dc_quant = 32;
520 c->chroma_dc_quant = 32;
521
525
526 for (
i = 0;
i < 3;
i++)
530
531 for (j = 0; j <
c->mb_height; j++) {
532 for (
i = 0;
i <
c->mb_width;
i++) {
536 }
537 }
539 } else {
540 int plane;
541
544
547
551
555
556 mvi_reset(&
c->mvi,
c->pmb_width,
c->pmb_height, 1 <<
c->tile_shift);
557
558 for (j = 0; j <
c->pmb_height; j++) {
559 for (
i = 0;
i <
c->pmb_width;
i++) {
563
567 for (plane = 0; plane < 3; plane++) {
568 int16_t x = plane == 0 ?
i <<
c->tile_shift :
i << (
c->tile_shift - 1);
569 int16_t y = plane == 0 ? j <<
c->tile_shift : j << (
c->tile_shift - 1);
570 int16_t
size = plane == 0 ? 1 <<
c->tile_shift : 1 << (
c->tile_shift - 1);
571 int16_t mx = plane == 0 ?
mv.x :
mv.x / 2;
572 int16_t my = plane == 0 ?
mv.y :
mv.y / 2;
573
577 }
578 } else {
579 int x =
i <<
c->tile_shift;
580 int y = j <<
c->tile_shift;
581 int size = 1 <<
c->tile_shift;
583
588 x =
i << (
c->tile_shift - 1);
589 y = j << (
c->tile_shift - 1);
590 size = 1 << (
c->tile_shift - 1);
591 cmv = *mvp;
602 }
603 }
605 }
607
608 c->pic->key_frame = 0;
610 }
611
614
616
617 *got_frame = 1;
618
621
622 return mb_ret < 0 ? mb_ret : buf_size;
623 }
624
626 const uint16_t **syms,
unsigned *
offset)
627 {
629 unsigned num = 0;
630
631 for (
int i = 0;
i < 16;
i++) {
632 unsigned count = counts[
i];
633 if (count == 255) /* Special case for Y_3 table */
634 count = 303;
635 for (count += num; num < count; num++)
637 }
642 *syms += num;
644 }
645
647 {
649
656 for (
unsigned i = 0, j = 0, k = 0,
offset = 0;;
i++) {
657 if (0x36F & (1 <<
i)) {
659 k++;
660 }
662 break;
663 if (0x1B7 & (1 <<
i)) {
671
674 j++;
675 }
676 }
677 }
678
680 {
684
691 } else {
694 }
695
697 if (1
U <<
c->tile_shift !=
c->tile_size ||
c->tile_shift < 1 ||
c->tile_shift > 30) {
698 av_log(avctx,
AV_LOG_ERROR,
"Tile size: %d, is not power of 2 > 1 and < 2^31\n",
c->tile_size);
700 }
701
710
714 c->pmb_width = (
w +
c->tile_size - 1) >>
c->tile_shift;
715 c->pmb_height = (
h +
c->tile_size - 1) >>
c->tile_shift;
718 c->mvi.mv =
av_calloc(
c->pmb_width * 2,
sizeof(*
c->mvi.mv));
719 if (!
c->pic || !
c->prev || !
c->mvi.mv)
721
723
725
726 return 0;
727 }
728
730 {
732
735
737
738 return 0;
739 }
740
742 .
p.
name =
"clearvideo",
752 };
#define AV_LOG_WARNING
Something somehow does not look correct.
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
static int get_bits_left(GetBitContext *gb)
Filter the word "frame" indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
static const uint8_t clv_dc_syms[NUM_DC_CODES]
static const int8_t mv[256][2]
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
This structure describes decoded (raw) audio or video data.
static const uint16_t clv_mv_syms[]
static int clv_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt)
static void mvi_update_prediction(MV *mv, MV diff)
static const uint8_t clv_flags_syms[][16]
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
static av_cold int clv_decode_init(AVCodecContext *avctx)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
static void extend_edges(AVFrame *buf, int tile_size)
AVCodec p
The public AVCodec.
static int decode_mb(CLVContext *c, int x, int y)
static const uint8_t clv_dc_lens[NUM_DC_CODES]
static double val(void *priv, double ch)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
static av_cold void clv_init_static(void)
s EdgeDetect Foobar g libavfilter vf_edgedetect c libavfilter vf_foobar c edit libavfilter and add an entry for foobar following the pattern of the other filters edit libavfilter allfilters and add an entry for foobar following the pattern of the other filters configure make j< whatever > ffmpeg ffmpeg i you should get a foobar png with Lena edge detected That s your new playground is ready Some little details about what s going which in turn will define variables for the build system and the C
static int ff_thread_once(char *control, void(*routine)(void))
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static const uint16_t clv_bias_syms[]
#define FF_ARRAY_ELEMS(a)
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
#define FF_CODEC_DECODE_CB(func)
int(* init)(AVBSFContext *ctx)
static void clv_dct(int16_t *block)
static VLCElem vlc_buf[16716]
static int get_sbits(GetBitContext *s, int n)
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
#define CODEC_LONG_NAME(str)
static MV * mvi_predict(MVInfo *mvi, int mb_x, int mb_y)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static int bias(int x, int c)
#define INIT_VLC_STATIC_FROM_LENGTHS(vlc, bits, nb_codes, lens, len_wrap, symbols, symbols_wrap, symbols_size, offset, flags, static_size)
@ AV_PICTURE_TYPE_I
Intra.
static unsigned int get_bits1(GetBitContext *s)
int ff_init_vlc_from_lengths(VLC *vlc, int nb_bits, int nb_codes, const int8_t *lens, int lens_wrap, const void *symbols, int symbols_wrap, int symbols_size, int offset, int flags, void *logctx)
Build VLC decoding tables suitable for use with get_vlc2()
static av_cold int clv_decode_end(AVCodecContext *avctx)
static int copyadd_block(AVCodecContext *avctx, AVFrame *dst, const AVFrame *src, int plane, int x, int y, int dx, int dy, int size, int bias)
static av_always_inline int get_vlc2(GetBitContext *s, const VLCElem *table, int bits, int max_depth)
Parse a vlc code.
static void mvi_update_row(MVInfo *mvi)
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
static av_always_inline int bytestream2_tell(GetByteContext *g)
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
#define DECLARE_ALIGNED(n, t, v)
static int shift(int a, int b)
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
const FFCodec ff_clearvideo_decoder
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
#define i(width, name, range_min, range_max)
static void pred_mv(DiracBlock *block, int stride, int x, int y, int ref)
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
static const uint8_t clv_ac_bits[NUM_AC_CODES]
const char * name
Name of the codec implementation.
static LevelCodes lev[4+3+3]
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
void * av_calloc(size_t nmemb, size_t size)
static const uint8_t clv_flags_bits[][16]
const uint8_t ff_zigzag_direct[64]
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available.
#define INIT_VLC_STATIC_OVERLONG
static const float pred[4]
#define FFSWAP(type, a, b)
static int copy_block(AVCodecContext *avctx, AVFrame *dst, const AVFrame *src, int plane, int x, int y, int dx, int dy, int size)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
main external API structure.
static int decode_block(CLVContext *ctx, int16_t *blk, int has_ac, int ac_quant)
#define DCT_TEMPLATE(blk, step, bias, shift, dshift, OP)
int coded_width
Bitstream width / height, may be different from width/height e.g.
@ AV_PICTURE_TYPE_P
Predicted.
static void mvi_reset(MVInfo *mvi, int mb_w, int mb_h, int mb_size)
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
This structure stores compressed data.
static const uint8_t clv_mv_len_counts[][16]
int width
picture width / height.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
#define flags(name, subs,...)
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
The exact code depends on how similar the blocks are and how related they are to the block
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define MKTAG(a, b, c, d)
static int tile_do_block(AVCodecContext *avctx, AVFrame *dst, const AVFrame *src, int plane, int x, int y, int dx, int dy, int size, int bias)
static int decode_tile(AVCodecContext *avctx, GetBitContext *gb, const LevelCodes *lc, AVFrame *dst, const AVFrame *src, int plane, int x, int y, int size, MV root_mv, MV *pred)
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
static const uint16_t clv_ac_syms[NUM_AC_CODES]
static av_cold void build_vlc(VLC *vlc, const uint8_t counts[16], const uint16_t **syms, unsigned *offset)
static const uint8_t clv_bias_len_counts[][16]
static const uint8_t mv_syms[2][16][10]
Generated on Tue Feb 28 2023 21:33:11 for FFmpeg by
doxygen
1.8.17