2 * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
3 * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de>
5 * This file is part of FFmpeg.
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.
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.
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
26 #include "mpegvideo.h"
28 #define SLICE_MIN_START_CODE 0x00000101
29 #define SLICE_MAX_START_CODE 0x000001af
30 #define EXT_START_CODE 0x000001b5
31 #define USER_START_CODE 0x000001b2
32 #define CAVS_START_CODE 0x000001b0
33 #define PIC_I_START_CODE 0x000001b3
34 #define PIC_PB_START_CODE 0x000001b6
44 #define ESCAPE_CODE 59
55 #define MV_BWD_OFFS 12
128 MV_BWD_D3
= MV_BWD_OFFS
,
135 MV_BWD_A3
= MV_BWD_OFFS
+8,
140 DECLARE_ALIGNED_8(typedef, struct) {
147 typedef struct dec_2dvlc_t
{
149 int8_t level_add
[27];
157 Picture picture
; ///< currently decoded frame
158 Picture DPB
[2]; ///< reference frames
159 int dist
[2]; ///< temporal distances from current frame to ref frames
162 int mb_width
, mb_height
;
166 int skip_mode_flag
; ///< select between skip_count or one skip_flag per MB
167 int loop_filter_disable
;
168 int alpha_offset
, beta_offset
;
170 int mbx
, mby
; ///< macroblock coordinates
171 int flags
; ///< availability flags of neighbouring macroblocks
172 int stc
; ///< last start code
173 uint8_t *cy
, *cu
, *cv
; ///< current MB sample pointers
177 /** mv motion vector cache
182 X are the vectors in the current macroblock (5,6,9,10)
183 A is the macroblock to the left (4,8)
184 B is the macroblock to the top (1,2)
185 C is the macroblock to the top-right (3)
186 D is the macroblock to the top-left (0)
188 the same is repeated for backward motion vectors */
193 /** luma pred mode cache
197 int pred_mode_Y
[3*3];
199 int l_stride
, c_stride
;
206 /** intra prediction is done with un-deblocked samples
207 they are saved here before deblocking the MB */
208 uint8_t *top_border_y
, *top_border_u
, *top_border_v
;
209 uint8_t left_border_y
[26], left_border_u
[10], left_border_v
[10];
210 uint8_t intern_border_y
[26];
211 uint8_t topleft_border_y
, topleft_border_u
, topleft_border_v
;
213 void (*intra_pred_l
[8])(uint8_t *d
,uint8_t *top
,uint8_t *left
,int stride
);
214 void (*intra_pred_c
[7])(uint8_t *d
,uint8_t *top
,uint8_t *left
,int stride
);
215 uint8_t *col_type_base
;
218 /* scaling factors for MV prediction */
219 int sym_factor
; ///< for scaling in symmetrical B block
220 int direct_den
[2]; ///< for scaling in direct B block
221 int scale_den
[2]; ///< for scaling neighbouring MVs
227 extern const uint8_t ff_cavs_dequant_shift
[64];
228 extern const uint16_t ff_cavs_dequant_mul
[64];
229 extern const dec_2dvlc_t ff_cavs_intra_dec
[7];
230 extern const dec_2dvlc_t ff_cavs_inter_dec
[7];
231 extern const dec_2dvlc_t ff_cavs_chroma_dec
[5];
232 extern const uint8_t ff_cavs_chroma_qp
[64];
233 extern const uint8_t ff_cavs_scan3x3
[4];
234 extern const uint8_t ff_cavs_partition_flags
[30];
235 extern const int_fast8_t ff_left_modifier_l
[8];
236 extern const int_fast8_t ff_top_modifier_l
[8];
237 extern const int_fast8_t ff_left_modifier_c
[7];
238 extern const int_fast8_t ff_top_modifier_c
[7];
239 extern const vector_t ff_cavs_intra_mv
;
240 extern const vector_t ff_cavs_un_mv
;
241 extern const vector_t ff_cavs_dir_mv
;
243 static inline void load_intra_pred_luma(AVSContext
*h
, uint8_t *top
,
244 uint8_t **left
, int block
) {
249 *left
= h
->left_border_y
;
250 h
->left_border_y
[0] = h
->left_border_y
[1];
251 memset(&h
->left_border_y
[17],h
->left_border_y
[16],9);
252 memcpy(&top
[1],&h
->top_border_y
[h
->mbx
*16],16);
255 if((h
->flags
& A_AVAIL
) && (h
->flags
& B_AVAIL
))
256 h
->left_border_y
[0] = top
[0] = h
->topleft_border_y
;
259 *left
= h
->intern_border_y
;
261 h
->intern_border_y
[i
+1] = *(h
->cy
+ 7 + i
*h
->l_stride
);
262 memset(&h
->intern_border_y
[9],h
->intern_border_y
[8],9);
263 h
->intern_border_y
[0] = h
->intern_border_y
[1];
264 memcpy(&top
[1],&h
->top_border_y
[h
->mbx
*16+8],8);
265 if(h
->flags
& C_AVAIL
)
266 memcpy(&top
[9],&h
->top_border_y
[(h
->mbx
+ 1)*16],8);
268 memset(&top
[9],top
[8],9);
271 if(h
->flags
& B_AVAIL
)
272 h
->intern_border_y
[0] = top
[0] = h
->top_border_y
[h
->mbx
*16+7];
275 *left
= &h
->left_border_y
[8];
276 memcpy(&top
[1],h
->cy
+ 7*h
->l_stride
,16);
279 if(h
->flags
& A_AVAIL
)
280 top
[0] = h
->left_border_y
[8];
283 *left
= &h
->intern_border_y
[8];
285 h
->intern_border_y
[i
+9] = *(h
->cy
+ 7 + (i
+8)*h
->l_stride
);
286 memset(&h
->intern_border_y
[17],h
->intern_border_y
[16],9);
287 memcpy(&top
[0],h
->cy
+ 7 + 7*h
->l_stride
,9);
288 memset(&top
[9],top
[8],9);
293 static inline void load_intra_pred_chroma(AVSContext
*h
) {
294 /* extend borders by one pixel */
295 h
->left_border_u
[9] = h
->left_border_u
[8];
296 h
->left_border_v
[9] = h
->left_border_v
[8];
297 h
->top_border_u
[h
->mbx
*10+9] = h
->top_border_u
[h
->mbx
*10+8];
298 h
->top_border_v
[h
->mbx
*10+9] = h
->top_border_v
[h
->mbx
*10+8];
299 if(h
->mbx
&& h
->mby
) {
300 h
->top_border_u
[h
->mbx
*10] = h
->left_border_u
[0] = h
->topleft_border_u
;
301 h
->top_border_v
[h
->mbx
*10] = h
->left_border_v
[0] = h
->topleft_border_v
;
303 h
->left_border_u
[0] = h
->left_border_u
[1];
304 h
->left_border_v
[0] = h
->left_border_v
[1];
305 h
->top_border_u
[h
->mbx
*10] = h
->top_border_u
[h
->mbx
*10+1];
306 h
->top_border_v
[h
->mbx
*10] = h
->top_border_v
[h
->mbx
*10+1];
310 static inline void modify_pred(const int_fast8_t *mod_table
, int *mode
) {
311 *mode
= mod_table
[*mode
];
313 av_log(NULL
, AV_LOG_ERROR
, "Illegal intra prediction mode\n");
318 static inline void modify_mb_i(AVSContext
*h
, int *pred_mode_uv
) {
319 /* save pred modes before they get modified */
320 h
->pred_mode_Y
[3] = h
->pred_mode_Y
[5];
321 h
->pred_mode_Y
[6] = h
->pred_mode_Y
[8];
322 h
->top_pred_Y
[h
->mbx
*2+0] = h
->pred_mode_Y
[7];
323 h
->top_pred_Y
[h
->mbx
*2+1] = h
->pred_mode_Y
[8];
325 /* modify pred modes according to availability of neighbour samples */
326 if(!(h
->flags
& A_AVAIL
)) {
327 modify_pred(ff_left_modifier_l
, &h
->pred_mode_Y
[4] );
328 modify_pred(ff_left_modifier_l
, &h
->pred_mode_Y
[7] );
329 modify_pred(ff_left_modifier_c
, pred_mode_uv
);
331 if(!(h
->flags
& B_AVAIL
)) {
332 modify_pred(ff_top_modifier_l
, &h
->pred_mode_Y
[4] );
333 modify_pred(ff_top_modifier_l
, &h
->pred_mode_Y
[5] );
334 modify_pred(ff_top_modifier_c
, pred_mode_uv
);
338 static inline void set_intra_mode_default(AVSContext
*h
) {
339 h
->pred_mode_Y
[3] = h
->pred_mode_Y
[6] = INTRA_L_LP
;
340 h
->top_pred_Y
[h
->mbx
*2+0] = h
->top_pred_Y
[h
->mbx
*2+1] = INTRA_L_LP
;
343 static inline void set_mvs(vector_t
*mv
, enum block_t size
) {
346 mv
[MV_STRIDE
] = mv
[0];
347 mv
[MV_STRIDE
+1] = mv
[0];
352 mv
[MV_STRIDE
] = mv
[0];
357 static inline void set_mv_intra(AVSContext
*h
) {
358 h
->mv
[MV_FWD_X0
] = ff_cavs_intra_mv
;
359 set_mvs(&h
->mv
[MV_FWD_X0
], BLK_16X16
);
360 h
->mv
[MV_BWD_X0
] = ff_cavs_intra_mv
;
361 set_mvs(&h
->mv
[MV_BWD_X0
], BLK_16X16
);
362 if(h
->pic_type
!= FF_B_TYPE
)
363 *h
->col_type
= I_8X8
;
368 * initialise predictors for motion vectors and intra prediction
370 static inline void init_mb(AVSContext
*h
) {
373 /* copy predictors from top line (MB B and C) into cache */
375 h
->mv
[MV_FWD_B2
+i
] = h
->top_mv
[0][h
->mbx
*2+i
];
376 h
->mv
[MV_BWD_B2
+i
] = h
->top_mv
[1][h
->mbx
*2+i
];
378 h
->pred_mode_Y
[1] = h
->top_pred_Y
[h
->mbx
*2+0];
379 h
->pred_mode_Y
[2] = h
->top_pred_Y
[h
->mbx
*2+1];
380 /* clear top predictors if MB B is not available */
381 if(!(h
->flags
& B_AVAIL
)) {
382 h
->mv
[MV_FWD_B2
] = ff_cavs_un_mv
;
383 h
->mv
[MV_FWD_B3
] = ff_cavs_un_mv
;
384 h
->mv
[MV_BWD_B2
] = ff_cavs_un_mv
;
385 h
->mv
[MV_BWD_B3
] = ff_cavs_un_mv
;
386 h
->pred_mode_Y
[1] = h
->pred_mode_Y
[2] = NOT_AVAIL
;
387 h
->flags
&= ~(C_AVAIL
|D_AVAIL
);
391 if(h
->mbx
== h
->mb_width
-1) //MB C not available
392 h
->flags
&= ~C_AVAIL
;
393 /* clear top-right predictors if MB C is not available */
394 if(!(h
->flags
& C_AVAIL
)) {
395 h
->mv
[MV_FWD_C2
] = ff_cavs_un_mv
;
396 h
->mv
[MV_BWD_C2
] = ff_cavs_un_mv
;
398 /* clear top-left predictors if MB D is not available */
399 if(!(h
->flags
& D_AVAIL
)) {
400 h
->mv
[MV_FWD_D3
] = ff_cavs_un_mv
;
401 h
->mv
[MV_BWD_D3
] = ff_cavs_un_mv
;
403 /* set pointer for co-located macroblock type */
404 h
->col_type
= &h
->col_type_base
[h
->mby
*h
->mb_width
+ h
->mbx
];
408 * save predictors for later macroblocks and increase
410 * @returns 0 if end of frame is reached, 1 otherwise
412 static inline int next_mb(AVSContext
*h
) {
419 /* copy mvs as predictors to the left */
421 h
->mv
[i
] = h
->mv
[i
+2];
422 /* copy bottom mvs from cache to top line */
423 h
->top_mv
[0][h
->mbx
*2+0] = h
->mv
[MV_FWD_X2
];
424 h
->top_mv
[0][h
->mbx
*2+1] = h
->mv
[MV_FWD_X3
];
425 h
->top_mv
[1][h
->mbx
*2+0] = h
->mv
[MV_BWD_X2
];
426 h
->top_mv
[1][h
->mbx
*2+1] = h
->mv
[MV_BWD_X3
];
427 /* next MB address */
429 if(h
->mbx
== h
->mb_width
) { //new mb line
430 h
->flags
= B_AVAIL
|C_AVAIL
;
431 /* clear left pred_modes */
432 h
->pred_mode_Y
[3] = h
->pred_mode_Y
[6] = NOT_AVAIL
;
433 /* clear left mv predictors */
435 h
->mv
[i
] = ff_cavs_un_mv
;
438 /* re-calculate sample pointers */
439 h
->cy
= h
->picture
.data
[0] + h
->mby
*16*h
->l_stride
;
440 h
->cu
= h
->picture
.data
[1] + h
->mby
*8*h
->c_stride
;
441 h
->cv
= h
->picture
.data
[2] + h
->mby
*8*h
->c_stride
;
442 if(h
->mby
== h
->mb_height
) { //frame end
445 //check_for_slice(h);
451 static inline int dequant(AVSContext
*h
, DCTELEM
*level_buf
, uint8_t *run_buf
,
452 DCTELEM
*dst
, int mul
, int shift
, int coeff_num
) {
453 int round
= 1 << (shift
- 1);
455 const uint8_t *scantab
= h
->scantable
.permutated
;
457 /* inverse scan and dequantization */
458 while(--coeff_num
>= 0){
459 pos
+= run_buf
[coeff_num
];
461 av_log(h
->s
.avctx
, AV_LOG_ERROR
,
462 "position out of block bounds at pic %d MB(%d,%d)\n",
463 h
->picture
.poc
, h
->mbx
, h
->mby
);
466 dst
[scantab
[pos
]] = (level_buf
[coeff_num
]*mul
+ round
) >> shift
;
471 void ff_cavs_filter(AVSContext
*h
, enum mb_t mb_type
);
472 void ff_cavs_inter(AVSContext
*h
, enum mb_t mb_type
);
473 void ff_cavs_mv(AVSContext
*h
, enum mv_loc_t nP
, enum mv_loc_t nC
,
474 enum mv_pred_t mode
, enum block_t size
, int ref
);
475 void ff_cavs_init_pic(AVSContext
*h
);
476 void ff_cavs_init_top_lines(AVSContext
*h
);
477 int ff_cavs_init(AVCodecContext
*avctx
);
478 int ff_cavs_end (AVCodecContext
*avctx
);