2 * Copyright (c) 2012 Konstantin Shishkov
4 * This file is part of FFmpeg.
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.
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.
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
23 * Common functions for Microsoft Screen 1 and 2
28 #include "libavutil/intfloat.h"
29 #include "libavutil/intreadwrite.h"
39 static const int sec_order_sizes
[4] = { 1, 7, 6, 1 };
41 enum ContextDirection
{
48 static int model_calc_threshold(Model
*m
)
52 thr
= 2 * m
->weights
[m
->num_syms
] - 1;
53 thr
= ((thr
>> 1) + 4 * m
->cum_prob
[0]) / thr
;
55 return FFMIN(thr
, 0x3FFF);
58 static void model_reset(Model
*m
)
62 for (i
= 0; i
<= m
->num_syms
; i
++) {
64 m
->cum_prob
[i
] = m
->num_syms
- i
;
67 for (i
= 0; i
< m
->num_syms
; i
++)
68 m
->idx2sym
[i
+ 1] = i
;
71 static av_cold
void model_init(Model
*m
, int num_syms
, int thr_weight
)
73 m
->num_syms
= num_syms
;
74 m
->thr_weight
= thr_weight
;
75 m
->threshold
= num_syms
* thr_weight
;
78 static void model_rescale_weights(Model
*m
)
83 if (m
->thr_weight
== THRESH_ADAPTIVE
)
84 m
->threshold
= model_calc_threshold(m
);
85 while (m
->cum_prob
[0] > m
->threshold
) {
87 for (i
= m
->num_syms
; i
>= 0; i
--) {
88 m
->cum_prob
[i
] = cum_prob
;
89 m
->weights
[i
] = (m
->weights
[i
] + 1) >> 1;
90 cum_prob
+= m
->weights
[i
];
95 void ff_mss12_model_update(Model
*m
, int val
)
99 if (m
->weights
[val
] == m
->weights
[val
- 1]) {
100 for (i
= val
; m
->weights
[i
- 1] == m
->weights
[val
]; i
--);
104 sym1
= m
->idx2sym
[val
];
105 sym2
= m
->idx2sym
[i
];
107 m
->idx2sym
[val
] = sym2
;
108 m
->idx2sym
[i
] = sym1
;
114 for (i
= val
- 1; i
>= 0; i
--)
116 model_rescale_weights(m
);
119 static void pixctx_reset(PixContext
*ctx
)
123 if (!ctx
->special_initial_cache
)
124 for (i
= 0; i
< ctx
->cache_size
; i
++)
132 model_reset(&ctx
->cache_model
);
133 model_reset(&ctx
->full_model
);
135 for (i
= 0; i
< 15; i
++)
136 for (j
= 0; j
< 4; j
++)
137 model_reset(&ctx
->sec_models
[i
][j
]);
140 static av_cold
void pixctx_init(PixContext
*ctx
, int cache_size
,
141 int full_model_syms
, int special_initial_cache
)
145 ctx
->cache_size
= cache_size
+ 4;
146 ctx
->num_syms
= cache_size
;
147 ctx
->special_initial_cache
= special_initial_cache
;
149 model_init(&ctx
->cache_model
, ctx
->num_syms
+ 1, THRESH_LOW
);
150 model_init(&ctx
->full_model
, full_model_syms
, THRESH_HIGH
);
152 for (i
= 0, idx
= 0; i
< 4; i
++)
153 for (j
= 0; j
< sec_order_sizes
[i
]; j
++, idx
++)
154 for (k
= 0; k
< 4; k
++)
155 model_init(&ctx
->sec_models
[idx
][k
], 2 + i
,
156 i
? THRESH_LOW
: THRESH_ADAPTIVE
);
159 static av_always_inline
int decode_pixel(ArithCoder
*acoder
, PixContext
*pctx
,
160 uint8_t *ngb
, int num_ngb
, int any_ngb
)
164 val
= acoder
->get_model_sym(acoder
, &pctx
->cache_model
);
165 if (val
< pctx
->num_syms
) {
170 for (i
= 0; i
< pctx
->cache_size
; i
++) {
171 for (j
= 0; j
< num_ngb
; j
++)
172 if (pctx
->cache
[i
] == ngb
[j
])
180 val
= FFMIN(i
, pctx
->cache_size
- 1);
182 pix
= pctx
->cache
[val
];
184 pix
= acoder
->get_model_sym(acoder
, &pctx
->full_model
);
185 for (i
= 0; i
< pctx
->cache_size
- 1; i
++)
186 if (pctx
->cache
[i
] == pix
)
191 for (i
= val
; i
> 0; i
--)
192 pctx
->cache
[i
] = pctx
->cache
[i
- 1];
193 pctx
->cache
[0] = pix
;
199 static int decode_pixel_in_context(ArithCoder
*acoder
, PixContext
*pctx
,
200 uint8_t *src
, int stride
, int x
, int y
,
203 uint8_t neighbours
[4];
211 memset(neighbours
, src
[-1], 4);
213 neighbours
[TOP
] = src
[-stride
];
215 neighbours
[TOP_LEFT
] = neighbours
[LEFT
] = neighbours
[TOP
];
217 neighbours
[TOP_LEFT
] = src
[-stride
- 1];
218 neighbours
[ LEFT
] = src
[-1];
221 neighbours
[TOP_RIGHT
] = src
[-stride
+ 1];
223 neighbours
[TOP_RIGHT
] = neighbours
[TOP
];
227 if (x
>= 2 && src
[-2] == neighbours
[LEFT
])
229 if (y
>= 2 && src
[-2 * stride
] == neighbours
[TOP
])
233 ref_pix
[0] = neighbours
[0];
234 for (i
= 1; i
< 4; i
++) {
235 for (j
= 0; j
< nlen
; j
++)
236 if (ref_pix
[j
] == neighbours
[i
])
239 ref_pix
[nlen
++] = neighbours
[i
];
247 if (neighbours
[TOP
] == neighbours
[TOP_LEFT
]) {
248 if (neighbours
[TOP_RIGHT
] == neighbours
[TOP_LEFT
])
250 else if (neighbours
[LEFT
] == neighbours
[TOP_LEFT
])
254 } else if (neighbours
[TOP_RIGHT
] == neighbours
[TOP_LEFT
]) {
255 if (neighbours
[LEFT
] == neighbours
[TOP_LEFT
])
259 } else if (neighbours
[LEFT
] == neighbours
[TOP_LEFT
]) {
266 if (neighbours
[TOP
] == neighbours
[TOP_LEFT
])
268 else if (neighbours
[TOP_RIGHT
] == neighbours
[TOP_LEFT
])
270 else if (neighbours
[LEFT
] == neighbours
[TOP_LEFT
])
272 else if (neighbours
[TOP_RIGHT
] == neighbours
[TOP
])
274 else if (neighbours
[TOP
] == neighbours
[LEFT
])
284 pix
= acoder
->get_model_sym(acoder
,
285 &pctx
->sec_models
[layer
][sub
]);
289 return decode_pixel(acoder
, pctx
, ref_pix
, nlen
, 1);
292 static int decode_region(ArithCoder
*acoder
, uint8_t *dst
, uint8_t *rgb_pic
,
293 int x
, int y
, int width
, int height
, int stride
,
294 int rgb_stride
, PixContext
*pctx
, const uint32_t *pal
)
297 uint8_t *rgb_dst
= rgb_pic
+ x
* 3 + y
* rgb_stride
;
299 dst
+= x
+ y
* stride
;
301 for (j
= 0; j
< height
; j
++) {
302 for (i
= 0; i
< width
; i
++) {
304 p
= decode_pixel(acoder
, pctx
, NULL
, 0, 0);
306 p
= decode_pixel_in_context(acoder
, pctx
, dst
+ i
, stride
,
307 i
, j
, width
- i
- 1);
311 AV_WB24(rgb_dst
+ i
* 3, pal
[p
]);
314 rgb_dst
+= rgb_stride
;
320 static void copy_rectangles(MSS12Context
const *c
,
321 int x
, int y
, int width
, int height
)
326 for (j
= y
; j
< y
+ height
; j
++) {
327 memcpy(c
->rgb_pic
+ j
* c
->rgb_stride
+ x
* 3,
328 c
->last_rgb_pic
+ j
* c
->rgb_stride
+ x
* 3,
330 memcpy(c
->pal_pic
+ j
* c
->pal_stride
+ x
,
331 c
->last_pal_pic
+ j
* c
->pal_stride
+ x
,
336 static int motion_compensation(MSS12Context
const *c
,
337 int x
, int y
, int width
, int height
)
339 if (x
+ c
->mvX
< 0 || x
+ c
->mvX
+ width
> c
->avctx
->width
||
340 y
+ c
->mvY
< 0 || y
+ c
->mvY
+ height
> c
->avctx
->height
||
344 uint8_t *dst
= c
->pal_pic
+ x
+ y
* c
->pal_stride
;
345 uint8_t *rgb_dst
= c
->rgb_pic
+ x
* 3 + y
* c
->rgb_stride
;
351 if (c
->last_rgb_pic
) {
352 src
= c
->last_pal_pic
+ x
+ y
* c
->pal_stride
;
353 rgb_src
= c
->last_rgb_pic
+ x
* 3 + y
* c
->rgb_stride
;
355 src
= c
->pal_pic
+ x
+ y
* c
->pal_stride
;
356 rgb_src
= c
->rgb_pic
+ x
* 3 + y
* c
->rgb_stride
;
358 for (j
= 0; j
< height
; j
++) {
359 memmove(dst
, src
, width
);
360 memmove(rgb_dst
, rgb_src
, width
* 3);
361 dst
+= c
->pal_stride
;
362 src
+= c
->pal_stride
;
363 rgb_dst
+= c
->rgb_stride
;
364 rgb_src
+= c
->rgb_stride
;
370 static int decode_region_masked(MSS12Context
const *c
, ArithCoder
*acoder
,
371 uint8_t *dst
, int stride
, uint8_t *mask
,
372 int mask_stride
, int x
, int y
,
373 int width
, int height
,
377 uint8_t *rgb_dst
= c
->rgb_pic
+ x
* 3 + y
* c
->rgb_stride
;
379 dst
+= x
+ y
* stride
;
380 mask
+= x
+ y
* mask_stride
;
382 for (j
= 0; j
< height
; j
++) {
383 for (i
= 0; i
< width
; i
++) {
384 if (c
->avctx
->err_recognition
& AV_EF_EXPLODE
&&
385 ( c
->rgb_pic
&& mask
[i
] != 0x01 && mask
[i
] != 0x02 && mask
[i
] != 0x04 ||
386 !c
->rgb_pic
&& mask
[i
] != 0x80 && mask
[i
] != 0xFF))
389 if (mask
[i
] == 0x02) {
390 copy_rectangles(c
, x
+ i
, y
+ j
, 1, 1);
391 } else if (mask
[i
] == 0x04) {
392 if (motion_compensation(c
, x
+ i
, y
+ j
, 1, 1))
394 } else if (mask
[i
] != 0x80) {
396 p
= decode_pixel(acoder
, pctx
, NULL
, 0, 0);
398 p
= decode_pixel_in_context(acoder
, pctx
, dst
+ i
, stride
,
399 i
, j
, width
- i
- 1);
402 AV_WB24(rgb_dst
+ i
* 3, c
->pal
[p
]);
407 rgb_dst
+= c
->rgb_stride
;
413 static av_cold
void slicecontext_init(SliceContext
*sc
,
414 int version
, int full_model_syms
)
416 model_init(&sc
->intra_region
, 2, THRESH_ADAPTIVE
);
417 model_init(&sc
->inter_region
, 2, THRESH_ADAPTIVE
);
418 model_init(&sc
->split_mode
, 3, THRESH_HIGH
);
419 model_init(&sc
->edge_mode
, 2, THRESH_HIGH
);
420 model_init(&sc
->pivot
, 3, THRESH_LOW
);
422 pixctx_init(&sc
->intra_pix_ctx
, 8, full_model_syms
, 0);
424 pixctx_init(&sc
->inter_pix_ctx
, version
? 3 : 2,
425 full_model_syms
, version
? 1 : 0);
428 void ff_mss12_slicecontext_reset(SliceContext
*sc
)
430 model_reset(&sc
->intra_region
);
431 model_reset(&sc
->inter_region
);
432 model_reset(&sc
->split_mode
);
433 model_reset(&sc
->edge_mode
);
434 model_reset(&sc
->pivot
);
435 pixctx_reset(&sc
->intra_pix_ctx
);
436 pixctx_reset(&sc
->inter_pix_ctx
);
439 static int decode_pivot(SliceContext
*sc
, ArithCoder
*acoder
, int base
)
443 inv
= acoder
->get_model_sym(acoder
, &sc
->edge_mode
);
444 val
= acoder
->get_model_sym(acoder
, &sc
->pivot
) + 1;
447 if ((base
+ 1) / 2 - 2 <= 0)
450 val
= acoder
->get_number(acoder
, (base
+ 1) / 2 - 2) + 3;
453 if ((unsigned)val
>= base
)
456 return inv
? base
- val
: val
;
459 static int decode_region_intra(SliceContext
*sc
, ArithCoder
*acoder
,
460 int x
, int y
, int width
, int height
)
462 MSS12Context
const *c
= sc
->c
;
465 mode
= acoder
->get_model_sym(acoder
, &sc
->intra_region
);
468 int i
, j
, pix
, rgb_pix
;
469 int stride
= c
->pal_stride
;
470 int rgb_stride
= c
->rgb_stride
;
471 uint8_t *dst
= c
->pal_pic
+ x
+ y
* stride
;
472 uint8_t *rgb_dst
= c
->rgb_pic
+ x
* 3 + y
* rgb_stride
;
474 pix
= decode_pixel(acoder
, &sc
->intra_pix_ctx
, NULL
, 0, 0);
475 rgb_pix
= c
->pal
[pix
];
476 for (i
= 0; i
< height
; i
++, dst
+= stride
, rgb_dst
+= rgb_stride
) {
477 memset(dst
, pix
, width
);
479 for (j
= 0; j
< width
* 3; j
+= 3)
480 AV_WB24(rgb_dst
+ j
, rgb_pix
);
483 return decode_region(acoder
, c
->pal_pic
, c
->rgb_pic
,
484 x
, y
, width
, height
, c
->pal_stride
, c
->rgb_stride
,
485 &sc
->intra_pix_ctx
, &c
->pal
[0]);
491 static int decode_region_inter(SliceContext
*sc
, ArithCoder
*acoder
,
492 int x
, int y
, int width
, int height
)
494 MSS12Context
const *c
= sc
->c
;
497 mode
= acoder
->get_model_sym(acoder
, &sc
->inter_region
);
500 mode
= decode_pixel(acoder
, &sc
->inter_pix_ctx
, NULL
, 0, 0);
502 if (c
->avctx
->err_recognition
& AV_EF_EXPLODE
&&
503 ( c
->rgb_pic
&& mode
!= 0x01 && mode
!= 0x02 && mode
!= 0x04 ||
504 !c
->rgb_pic
&& mode
!= 0x80 && mode
!= 0xFF))
508 copy_rectangles(c
, x
, y
, width
, height
);
509 else if (mode
== 0x04)
510 return motion_compensation(c
, x
, y
, width
, height
);
511 else if (mode
!= 0x80)
512 return decode_region_intra(sc
, acoder
, x
, y
, width
, height
);
514 if (decode_region(acoder
, c
->mask
, NULL
,
515 x
, y
, width
, height
, c
->mask_stride
, 0,
516 &sc
->inter_pix_ctx
, &c
->pal
[0]) < 0)
518 return decode_region_masked(c
, acoder
, c
->pal_pic
,
519 c
->pal_stride
, c
->mask
,
528 int ff_mss12_decode_rect(SliceContext
*sc
, ArithCoder
*acoder
,
529 int x
, int y
, int width
, int height
)
533 mode
= acoder
->get_model_sym(acoder
, &sc
->split_mode
);
537 if ((pivot
= decode_pivot(sc
, acoder
, height
)) < 1)
539 if (ff_mss12_decode_rect(sc
, acoder
, x
, y
, width
, pivot
))
541 if (ff_mss12_decode_rect(sc
, acoder
, x
, y
+ pivot
, width
, height
- pivot
))
545 if ((pivot
= decode_pivot(sc
, acoder
, width
)) < 1)
547 if (ff_mss12_decode_rect(sc
, acoder
, x
, y
, pivot
, height
))
549 if (ff_mss12_decode_rect(sc
, acoder
, x
+ pivot
, y
, width
- pivot
, height
))
554 return decode_region_intra(sc
, acoder
, x
, y
, width
, height
);
556 return decode_region_inter(sc
, acoder
, x
, y
, width
, height
);
564 av_cold
int ff_mss12_decode_init(MSS12Context
*c
, int version
,
565 SliceContext
* sc1
, SliceContext
*sc2
)
567 AVCodecContext
*avctx
= c
->avctx
;
570 if (avctx
->extradata_size
< 52 + 256 * 3) {
571 av_log(avctx
, AV_LOG_ERROR
, "Insufficient extradata size %d\n",
572 avctx
->extradata_size
);
573 return AVERROR_INVALIDDATA
;
576 if (AV_RB32(avctx
->extradata
) < avctx
->extradata_size
) {
577 av_log(avctx
, AV_LOG_ERROR
,
578 "Insufficient extradata size: expected %"PRIu32
" got %d\n",
579 AV_RB32(avctx
->extradata
),
580 avctx
->extradata_size
);
581 return AVERROR_INVALIDDATA
;
584 avctx
->coded_width
= AV_RB32(avctx
->extradata
+ 20);
585 avctx
->coded_height
= AV_RB32(avctx
->extradata
+ 24);
586 if (avctx
->coded_width
> 4096 || avctx
->coded_height
> 4096) {
587 av_log(avctx
, AV_LOG_ERROR
, "Frame dimensions %dx%d too large",
588 avctx
->coded_width
, avctx
->coded_height
);
589 return AVERROR_INVALIDDATA
;
591 if (avctx
->coded_width
< 1 || avctx
->coded_height
< 1) {
592 av_log(avctx
, AV_LOG_ERROR
, "Frame dimensions %dx%d too small",
593 avctx
->coded_width
, avctx
->coded_height
);
594 return AVERROR_INVALIDDATA
;
597 av_log(avctx
, AV_LOG_DEBUG
, "Encoder version %"PRIu32
".%"PRIu32
"\n",
598 AV_RB32(avctx
->extradata
+ 4), AV_RB32(avctx
->extradata
+ 8));
599 if (version
!= AV_RB32(avctx
->extradata
+ 4) > 1) {
600 av_log(avctx
, AV_LOG_ERROR
,
601 "Header version doesn't match codec tag\n");
605 c
->free_colours
= AV_RB32(avctx
->extradata
+ 48);
606 if ((unsigned)c
->free_colours
> 256) {
607 av_log(avctx
, AV_LOG_ERROR
,
608 "Incorrect number of changeable palette entries: %d\n",
610 return AVERROR_INVALIDDATA
;
612 av_log(avctx
, AV_LOG_DEBUG
, "%d free colour(s)\n", c
->free_colours
);
614 av_log(avctx
, AV_LOG_DEBUG
, "Display dimensions %"PRIu32
"x%"PRIu32
"\n",
615 AV_RB32(avctx
->extradata
+ 12), AV_RB32(avctx
->extradata
+ 16));
616 av_log(avctx
, AV_LOG_DEBUG
, "Coded dimensions %dx%d\n",
617 avctx
->coded_width
, avctx
->coded_height
);
618 av_log(avctx
, AV_LOG_DEBUG
, "%g frames per second\n",
619 av_int2float(AV_RB32(avctx
->extradata
+ 28)));
620 av_log(avctx
, AV_LOG_DEBUG
, "Bitrate %"PRIu32
" bps\n",
621 AV_RB32(avctx
->extradata
+ 32));
622 av_log(avctx
, AV_LOG_DEBUG
, "Max. lead time %g ms\n",
623 av_int2float(AV_RB32(avctx
->extradata
+ 36)));
624 av_log(avctx
, AV_LOG_DEBUG
, "Max. lag time %g ms\n",
625 av_int2float(AV_RB32(avctx
->extradata
+ 40)));
626 av_log(avctx
, AV_LOG_DEBUG
, "Max. seek time %g ms\n",
627 av_int2float(AV_RB32(avctx
->extradata
+ 44)));
630 if (avctx
->extradata_size
< 60 + 256 * 3) {
631 av_log(avctx
, AV_LOG_ERROR
,
632 "Insufficient extradata size %d for v2\n",
633 avctx
->extradata_size
);
634 return AVERROR_INVALIDDATA
;
637 c
->slice_split
= AV_RB32(avctx
->extradata
+ 52);
638 av_log(avctx
, AV_LOG_DEBUG
, "Slice split %d\n", c
->slice_split
);
640 c
->full_model_syms
= AV_RB32(avctx
->extradata
+ 56);
641 if (c
->full_model_syms
< 2 || c
->full_model_syms
> 256) {
642 av_log(avctx
, AV_LOG_ERROR
,
643 "Incorrect number of used colours %d\n",
645 return AVERROR_INVALIDDATA
;
647 av_log(avctx
, AV_LOG_DEBUG
, "Used colours %d\n",
651 c
->full_model_syms
= 256;
654 for (i
= 0; i
< 256; i
++)
655 c
->pal
[i
] = 0xFFU
<< 24 | AV_RB24(avctx
->extradata
+ 52 +
656 (version
? 8 : 0) + i
* 3);
658 c
->mask_stride
= FFALIGN(avctx
->width
, 16);
659 c
->mask
= av_malloc(c
->mask_stride
* avctx
->height
);
661 av_log(avctx
, AV_LOG_ERROR
, "Cannot allocate mask plane\n");
662 return AVERROR(ENOMEM
);
666 slicecontext_init(sc1
, version
, c
->full_model_syms
);
667 if (c
->slice_split
) {
669 slicecontext_init(sc2
, version
, c
->full_model_syms
);
676 av_cold
int ff_mss12_decode_end(MSS12Context
*c
)