annotate indeo5.c @ 11245:1e9ff636c3db libavcodec

Make Bink decoder to stop decoding planes after all bits are used. This prevents crashes during decoding grayscale Bink files like samples from Impossible Creatures game demo.
author kostya
date Mon, 22 Feb 2010 12:35:12 +0000
parents 384b6a615a92
children b75449aaea3e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11107
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
1 /*
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
2 * Indeo Video Interactive v5 compatible decoder
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
3 * Copyright (c) 2009 Maxim Poliakovski
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
4 *
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
5 * This file is part of FFmpeg.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
6 *
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
11 *
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
15 * Lesser General Public License for more details.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
16 *
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
20 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
21
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
22 /**
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
23 * @file libavcodec/indeo5.c
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
24 * Indeo Video Interactive version 5 decoder
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
25 *
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
26 * Indeo5 data is usually transported within .avi or .mov files.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
27 * Known FOURCCs: 'IV50'
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
28 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
29
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
30 #define ALT_BITSTREAM_READER_LE
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
31 #include "avcodec.h"
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
32 #include "get_bits.h"
11213
384b6a615a92 remove ivi5_scans8x8[0], it duplicates ff_zigzag_direct
stefang
parents: 11121
diff changeset
33 #include "dsputil.h"
11107
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
34 #include "ivi_dsp.h"
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
35 #include "ivi_common.h"
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
36 #include "indeo5data.h"
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
37
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
38 /**
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
39 * Indeo5 frame types.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
40 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
41 enum {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
42 FRAMETYPE_INTRA = 0,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
43 FRAMETYPE_INTER = 1, ///< non-droppable P-frame
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
44 FRAMETYPE_INTER_SCAL = 2, ///< droppable P-frame used in the scalability mode
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
45 FRAMETYPE_INTER_NOREF = 3, ///< droppable P-frame
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
46 FRAMETYPE_NULL = 4 ///< empty frame with no data
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
47 };
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
48
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
49 #define IVI5_PIC_SIZE_ESC 15
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
50
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
51 #define IVI5_IS_PROTECTED 0x20
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
52
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
53 typedef struct {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
54 GetBitContext gb;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
55 AVFrame frame;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
56 RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
57 IVIPlaneDesc planes[3]; ///< color planes
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
58 const uint8_t *frame_data; ///< input frame data pointer
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
59 int buf_switch; ///< used to switch between three buffers
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
60 int dst_buf;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
61 int ref_buf;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
62 uint32_t frame_size; ///< frame size in bytes
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
63 int frame_type;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
64 int prev_frame_type; ///< frame type of the previous frame
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
65 int frame_num;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
66 uint32_t pic_hdr_size; ///< picture header size in bytes
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
67 uint8_t frame_flags;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
68 uint16_t checksum; ///< frame checksum
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
69
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
70 int16_t mb_huff_sel; ///< MB huffman table selector
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
71 IVIHuffDesc mb_huff_desc; ///< MB table descriptor associated with the selector above
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
72 VLC *mb_vlc; ///< ptr to the vlc table for decoding macroblock data
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
73 VLC mb_vlc_cust; ///< custom macroblock vlc table
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
74
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
75 uint16_t gop_hdr_size;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
76 uint8_t gop_flags;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
77 int is_scalable;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
78 uint32_t lock_word;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
79 IVIPicConfig pic_conf;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
80 } IVI5DecContext;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
81
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
82 //! static vlc tables (initialized at startup)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
83 static VLC mb_vlc_tabs [8];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
84 static VLC blk_vlc_tabs[8];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
85
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
86
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
87 /**
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
88 * Decodes Indeo5 GOP (Group of pictures) header.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
89 * This header is present in key frames only.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
90 * It defines parameters for all frames in a GOP.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
91 *
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
92 * @param ctx [in,out] ptr to the decoder context
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
93 * @param avctx [in] ptr to the AVCodecContext
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
94 * @return result code: 0 = OK, -1 = error
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
95 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
96 static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
97 {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
98 int result, i, p, tile_size, pic_size_indx, mb_size, blk_size, blk_size_changed = 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
99 IVIBandDesc *band, *band1, *band2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
100 IVIPicConfig pic_conf;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
101
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
102 ctx->gop_flags = get_bits(&ctx->gb, 8);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
103
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
104 ctx->gop_hdr_size = (ctx->gop_flags & 1) ? get_bits(&ctx->gb, 16) : 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
105
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
106 if (ctx->gop_flags & IVI5_IS_PROTECTED)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
107 ctx->lock_word = get_bits_long(&ctx->gb, 32);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
108
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
109 tile_size = (ctx->gop_flags & 0x40) ? 64 << get_bits(&ctx->gb, 2) : 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
110 if (tile_size > 256) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
111 av_log(avctx, AV_LOG_ERROR, "Invalid tile size: %d\n", tile_size);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
112 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
113 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
114
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
115 /* decode number of wavelet bands */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
116 /* num_levels * 3 + 1 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
117 pic_conf.luma_bands = get_bits(&ctx->gb, 2) * 3 + 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
118 pic_conf.chroma_bands = get_bits1(&ctx->gb) * 3 + 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
119 ctx->is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
120 if (ctx->is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
121 av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n",
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
122 pic_conf.luma_bands, pic_conf.chroma_bands);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
123 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
124 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
125
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
126 pic_size_indx = get_bits(&ctx->gb, 4);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
127 if (pic_size_indx == IVI5_PIC_SIZE_ESC) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
128 pic_conf.pic_height = get_bits(&ctx->gb, 13);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
129 pic_conf.pic_width = get_bits(&ctx->gb, 13);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
130 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
131 pic_conf.pic_height = ivi5_common_pic_sizes[pic_size_indx * 2 + 1] << 2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
132 pic_conf.pic_width = ivi5_common_pic_sizes[pic_size_indx * 2 ] << 2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
133 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
134
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
135 if (ctx->gop_flags & 2) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
136 av_log(avctx, AV_LOG_ERROR, "YV12 picture format not supported!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
137 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
138 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
139
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
140 pic_conf.chroma_height = (pic_conf.pic_height + 3) >> 2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
141 pic_conf.chroma_width = (pic_conf.pic_width + 3) >> 2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
142
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
143 if (!tile_size) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
144 pic_conf.tile_height = pic_conf.pic_height;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
145 pic_conf.tile_width = pic_conf.pic_width;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
146 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
147 pic_conf.tile_height = pic_conf.tile_width = tile_size;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
148 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
149
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
150 /* check if picture layout was changed and reallocate buffers */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
151 if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
152 result = ff_ivi_init_planes(ctx->planes, &pic_conf);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
153 if (result) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
154 av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
155 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
156 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
157 ctx->pic_conf = pic_conf;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
158 blk_size_changed = 1; /* force reallocation of the internal structures */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
159 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
160
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
161 for (p = 0; p <= 1; p++) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
162 for (i = 0; i < (!p ? pic_conf.luma_bands : pic_conf.chroma_bands); i++) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
163 band = &ctx->planes[p].bands[i];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
164
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
165 band->is_halfpel = get_bits1(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
166
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
167 mb_size = get_bits1(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
168 blk_size = 8 >> get_bits1(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
169 mb_size = blk_size << !mb_size;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
170
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
171 blk_size_changed = mb_size != band->mb_size || blk_size != band->blk_size;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
172 if (blk_size_changed) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
173 band->mb_size = mb_size;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
174 band->blk_size = blk_size;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
175 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
176
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
177 if (get_bits1(&ctx->gb)) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
178 av_log(avctx, AV_LOG_ERROR, "Extended transform info encountered!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
179 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
180 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
181
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
182 /* select transform function and scan pattern according to plane and band number */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
183 switch ((p << 2) + i) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
184 case 0:
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
185 band->inv_transform = ff_ivi_inverse_slant_8x8;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
186 band->dc_transform = ff_ivi_dc_slant_2d;
11213
384b6a615a92 remove ivi5_scans8x8[0], it duplicates ff_zigzag_direct
stefang
parents: 11121
diff changeset
187 band->scan = ff_zigzag_direct;
11107
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
188 break;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
189
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
190 case 1:
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
191 band->inv_transform = ff_ivi_row_slant8;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
192 band->dc_transform = ff_ivi_dc_row_slant;
11213
384b6a615a92 remove ivi5_scans8x8[0], it duplicates ff_zigzag_direct
stefang
parents: 11121
diff changeset
193 band->scan = ivi5_scans8x8[0];
11107
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
194 break;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
195
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
196 case 2:
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
197 band->inv_transform = ff_ivi_col_slant8;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
198 band->dc_transform = ff_ivi_dc_col_slant;
11213
384b6a615a92 remove ivi5_scans8x8[0], it duplicates ff_zigzag_direct
stefang
parents: 11121
diff changeset
199 band->scan = ivi5_scans8x8[1];
11107
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
200 break;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
201
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
202 case 3:
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
203 band->inv_transform = ff_ivi_put_pixels_8x8;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
204 band->dc_transform = ff_ivi_put_dc_pixel_8x8;
11213
384b6a615a92 remove ivi5_scans8x8[0], it duplicates ff_zigzag_direct
stefang
parents: 11121
diff changeset
205 band->scan = ivi5_scans8x8[1];
11107
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
206 break;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
207
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
208 case 4:
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
209 band->inv_transform = ff_ivi_inverse_slant_4x4;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
210 band->dc_transform = ff_ivi_dc_slant_2d;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
211 band->scan = ivi5_scan4x4;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
212 break;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
213 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
214
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
215 band->is_2d_trans = band->inv_transform == ff_ivi_inverse_slant_8x8 ||
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
216 band->inv_transform == ff_ivi_inverse_slant_4x4;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
217
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
218 /* select dequant matrix according to plane and band number */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
219 if (!p) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
220 band->quant_mat = (pic_conf.luma_bands > 1) ? i+1 : 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
221 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
222 band->quant_mat = 5;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
223 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
224
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
225 if (get_bits(&ctx->gb, 2)) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
226 av_log(avctx, AV_LOG_ERROR, "End marker missing!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
227 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
228 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
229 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
230 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
231
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
232 /* copy chroma parameters into the 2nd chroma plane */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
233 for (i = 0; i < pic_conf.chroma_bands; i++) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
234 band1 = &ctx->planes[1].bands[i];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
235 band2 = &ctx->planes[2].bands[i];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
236
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
237 band2->width = band1->width;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
238 band2->height = band1->height;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
239 band2->mb_size = band1->mb_size;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
240 band2->blk_size = band1->blk_size;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
241 band2->is_halfpel = band1->is_halfpel;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
242 band2->quant_mat = band1->quant_mat;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
243 band2->scan = band1->scan;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
244 band2->inv_transform = band1->inv_transform;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
245 band2->dc_transform = band1->dc_transform;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
246 band2->is_2d_trans = band1->is_2d_trans;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
247 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
248
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
249 /* reallocate internal structures if needed */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
250 if (blk_size_changed) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
251 result = ff_ivi_init_tiles(ctx->planes, pic_conf.tile_width,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
252 pic_conf.tile_height);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
253 if (result) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
254 av_log(avctx, AV_LOG_ERROR,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
255 "Couldn't reallocate internal structures!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
256 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
257 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
258 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
259
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
260 if (ctx->gop_flags & 8) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
261 if (get_bits(&ctx->gb, 3)) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
262 av_log(avctx, AV_LOG_ERROR, "Alignment bits are not zero!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
263 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
264 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
265
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
266 if (get_bits1(&ctx->gb))
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
267 skip_bits_long(&ctx->gb, 24); /* skip transparency fill color */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
268 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
269
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
270 align_get_bits(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
271
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
272 skip_bits(&ctx->gb, 23); /* FIXME: unknown meaning */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
273
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
274 /* skip GOP extension if any */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
275 if (get_bits1(&ctx->gb)) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
276 do {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
277 i = get_bits(&ctx->gb, 16);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
278 } while (i & 0x8000);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
279 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
280
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
281 align_get_bits(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
282
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
283 return 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
284 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
285
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
286
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
287 /**
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
288 * Skips a header extension.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
289 *
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
290 * @param gb [in,out] the GetBit context
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
291 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
292 static inline void skip_hdr_extension(GetBitContext *gb)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
293 {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
294 int i, len;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
295
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
296 do {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
297 len = get_bits(gb, 8);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
298 for (i = 0; i < len; i++) skip_bits(gb, 8);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
299 } while(len);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
300 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
301
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
302
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
303 /**
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
304 * Decodes Indeo5 picture header.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
305 *
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
306 * @param ctx [in,out] ptr to the decoder context
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
307 * @param avctx [in] ptr to the AVCodecContext
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
308 * @return result code: 0 = OK, -1 = error
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
309 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
310 static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
311 {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
312 int result;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
313 IVIHuffDesc new_huff;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
314
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
315 if (get_bits(&ctx->gb, 5) != 0x1F) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
316 av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
317 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
318 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
319
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
320 ctx->prev_frame_type = ctx->frame_type;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
321 ctx->frame_type = get_bits(&ctx->gb, 3);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
322 if (ctx->frame_type >= 5) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
323 av_log(avctx, AV_LOG_ERROR, "Invalid frame type: %d \n", ctx->frame_type);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
324 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
325 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
326
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
327 ctx->frame_num = get_bits(&ctx->gb, 8);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
328
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
329 if (ctx->frame_type == FRAMETYPE_INTRA) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
330 if (decode_gop_header(ctx, avctx))
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
331 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
332 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
333
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
334 if (ctx->frame_type != FRAMETYPE_NULL) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
335 ctx->frame_flags = get_bits(&ctx->gb, 8);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
336
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
337 ctx->pic_hdr_size = (ctx->frame_flags & 1) ? get_bits_long(&ctx->gb, 24) : 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
338
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
339 ctx->checksum = (ctx->frame_flags & 0x10) ? get_bits(&ctx->gb, 16) : 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
340
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
341 /* skip unknown extension if any */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
342 if (ctx->frame_flags & 0x20)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
343 skip_hdr_extension(&ctx->gb); /* XXX: untested */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
344
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
345 /* decode macroblock huffman codebook */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
346 if (ctx->frame_flags & 0x40) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
347 ctx->mb_huff_sel = ff_ivi_dec_huff_desc(&ctx->gb, &new_huff);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
348 if (ctx->mb_huff_sel != 7) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
349 ctx->mb_vlc = &mb_vlc_tabs[ctx->mb_huff_sel];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
350 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
351 if (ff_ivi_huff_desc_cmp(&new_huff, &ctx->mb_huff_desc)) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
352 ff_ivi_huff_desc_copy(&ctx->mb_huff_desc, &new_huff);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
353
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
354 if (ctx->mb_vlc_cust.table)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
355 free_vlc(&ctx->mb_vlc_cust);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
356 result = ff_ivi_create_huff_from_desc(&ctx->mb_huff_desc,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
357 &ctx->mb_vlc_cust, 0);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
358 if (result) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
359 av_log(avctx, AV_LOG_ERROR, "Error while initializing custom macroblock vlc table!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
360 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
361 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
362 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
363 ctx->mb_vlc = &ctx->mb_vlc_cust;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
364 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
365 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
366 ctx->mb_vlc = &mb_vlc_tabs[7]; /* select the default macroblock huffman table */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
367 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
368
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
369 skip_bits(&ctx->gb, 3); /* FIXME: unknown meaning! */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
370 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
371
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
372 align_get_bits(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
373
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
374 return 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
375 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
376
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
377
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
378 /**
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
379 * Decodes Indeo5 band header.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
380 *
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
381 * @param ctx [in,out] ptr to the decoder context
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
382 * @param band [in,out] ptr to the band descriptor
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
383 * @param avctx [in] ptr to the AVCodecContext
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
384 * @return result code: 0 = OK, -1 = error
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
385 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
386 static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
387 AVCodecContext *avctx)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
388 {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
389 int i, result;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
390 uint8_t band_flags;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
391 IVIHuffDesc new_huff;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
392
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
393 band_flags = get_bits(&ctx->gb, 8);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
394
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
395 if (band_flags & 1) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
396 band->is_empty = 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
397 return 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
398 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
399
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
400 band->data_size = (ctx->frame_flags & 0x80) ? get_bits_long(&ctx->gb, 24) : 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
401
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
402 band->inherit_mv = band_flags & 2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
403 band->inherit_qdelta = band_flags & 8;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
404 band->qdelta_present = band_flags & 4;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
405 if (!band->qdelta_present) band->inherit_qdelta = 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
406
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
407 /* decode rvmap probability corrections if any */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
408 band->num_corr = 0; /* there are no corrections */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
409 if (band_flags & 0x10) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
410 band->num_corr = get_bits(&ctx->gb, 8); /* get number of correction pairs */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
411 if (band->num_corr > 61) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
412 av_log(avctx, AV_LOG_ERROR, "Too many corrections: %d\n",
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
413 band->num_corr);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
414 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
415 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
416
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
417 /* read correction pairs */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
418 for (i = 0; i < band->num_corr * 2; i++)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
419 band->corr[i] = get_bits(&ctx->gb, 8);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
420 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
421
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
422 /* select appropriate rvmap table for this band */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
423 band->rvmap_sel = (band_flags & 0x40) ? get_bits(&ctx->gb, 3) : 8;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
424
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
425 /* decode block huffman codebook */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
426 if (band_flags & 0x80) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
427 band->huff_sel = ff_ivi_dec_huff_desc(&ctx->gb, &new_huff);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
428 if (band->huff_sel != 7) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
429 band->blk_vlc = &blk_vlc_tabs[band->huff_sel];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
430 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
431 if (ff_ivi_huff_desc_cmp(&new_huff, &band->huff_desc)) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
432 ff_ivi_huff_desc_copy(&band->huff_desc, &new_huff);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
433
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
434 if (band->blk_vlc_cust.table)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
435 free_vlc(&band->blk_vlc_cust);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
436 result = ff_ivi_create_huff_from_desc(&band->huff_desc,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
437 &band->blk_vlc_cust, 0);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
438 if (result) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
439 av_log(avctx, AV_LOG_ERROR, "Error while initializing custom block vlc table!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
440 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
441 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
442 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
443 band->blk_vlc = &band->blk_vlc_cust;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
444 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
445 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
446 band->blk_vlc = &blk_vlc_tabs[7]; /* select the default macroblock huffman table */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
447 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
448
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
449 band->checksum_present = get_bits1(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
450 if (band->checksum_present)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
451 band->checksum = get_bits(&ctx->gb, 16);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
452
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
453 band->glob_quant = get_bits(&ctx->gb, 5);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
454
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
455 /* skip unknown extension if any */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
456 if (band_flags & 0x20) { /* XXX: untested */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
457 align_get_bits(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
458 skip_hdr_extension(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
459 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
460
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
461 align_get_bits(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
462
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
463 return 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
464 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
465
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
466
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
467 /**
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
468 * Decodes info (block type, cbp, quant delta, motion vector)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
469 * for all macroblocks in the current tile.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
470 *
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
471 * @param ctx [in,out] ptr to the decoder context
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
472 * @param band [in,out] ptr to the band descriptor
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
473 * @param tile [in,out] ptr to the tile descriptor
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
474 * @param avctx [in] ptr to the AVCodecContext
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
475 * @return result code: 0 = OK, -1 = error
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
476 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
477 static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
478 IVITile *tile, AVCodecContext *avctx)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
479 {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
480 int x, y, mv_x, mv_y, mv_delta, offs, mb_offset,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
481 mv_scale, blks_per_mb;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
482 IVIMbInfo *mb, *ref_mb;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
483 int row_offset = band->mb_size * band->pitch;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
484
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
485 mb = tile->mbs;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
486 ref_mb = tile->ref_mbs;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
487 offs = tile->ypos * band->pitch + tile->xpos;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
488
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
489 /* scale factor for motion vectors */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
490 mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
491 mv_x = mv_y = 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
492
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
493 for (y = tile->ypos; y < (tile->ypos + tile->height); y += band->mb_size) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
494 mb_offset = offs;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
495
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
496 for (x = tile->xpos; x < (tile->xpos + tile->width); x += band->mb_size) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
497 mb->xpos = x;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
498 mb->ypos = y;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
499 mb->buf_offs = mb_offset;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
500
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
501 if (get_bits1(&ctx->gb)) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
502 if (ctx->frame_type == FRAMETYPE_INTRA) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
503 av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
504 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
505 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
506 mb->type = 1; /* empty macroblocks are always INTER */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
507 mb->cbp = 0; /* all blocks are empty */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
508
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
509 mb->q_delta = 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
510 if (!band->plane && !band->band_num && (ctx->frame_flags & 8)) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
511 mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc->table,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
512 IVI_VLC_BITS, 1);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
513 mb->q_delta = IVI_TOSIGNED(mb->q_delta);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
514 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
515
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
516 mb->mv_x = mb->mv_y = 0; /* no motion vector coded */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
517 if (band->inherit_mv){
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
518 /* motion vector inheritance */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
519 if (mv_scale) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
520 mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
521 mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
522 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
523 mb->mv_x = ref_mb->mv_x;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
524 mb->mv_y = ref_mb->mv_y;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
525 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
526 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
527 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
528 if (band->inherit_mv) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
529 mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
530 } else if (ctx->frame_type == FRAMETYPE_INTRA) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
531 mb->type = 0; /* mb_type is always INTRA for intra-frames */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
532 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
533 mb->type = get_bits1(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
534 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
535
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
536 blks_per_mb = band->mb_size != band->blk_size ? 4 : 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
537 mb->cbp = get_bits(&ctx->gb, blks_per_mb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
538
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
539 mb->q_delta = 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
540 if (band->qdelta_present) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
541 if (band->inherit_qdelta) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
542 if (ref_mb) mb->q_delta = ref_mb->q_delta;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
543 } else if (mb->cbp || (!band->plane && !band->band_num &&
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
544 (ctx->frame_flags & 8))) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
545 mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc->table,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
546 IVI_VLC_BITS, 1);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
547 mb->q_delta = IVI_TOSIGNED(mb->q_delta);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
548 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
549 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
550
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
551 if (!mb->type) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
552 mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
553 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
554 if (band->inherit_mv){
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
555 /* motion vector inheritance */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
556 if (mv_scale) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
557 mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
558 mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
559 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
560 mb->mv_x = ref_mb->mv_x;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
561 mb->mv_y = ref_mb->mv_y;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
562 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
563 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
564 /* decode motion vector deltas */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
565 mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc->table,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
566 IVI_VLC_BITS, 1);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
567 mv_y += IVI_TOSIGNED(mv_delta);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
568 mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc->table,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
569 IVI_VLC_BITS, 1);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
570 mv_x += IVI_TOSIGNED(mv_delta);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
571 mb->mv_x = mv_x;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
572 mb->mv_y = mv_y;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
573 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
574 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
575 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
576
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
577 mb++;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
578 if (ref_mb)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
579 ref_mb++;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
580 mb_offset += band->mb_size;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
581 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
582
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
583 offs += row_offset;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
584 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
585
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
586 align_get_bits(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
587
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
588 return 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
589 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
590
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
591
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
592 /**
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
593 * Decodes an Indeo5 band.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
594 *
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
595 * @param ctx [in,out] ptr to the decoder context
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
596 * @param band [in,out] ptr to the band descriptor
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
597 * @param avctx [in] ptr to the AVCodecContext
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
598 * @return result code: 0 = OK, -1 = error
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
599 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
600 static int decode_band(IVI5DecContext *ctx, int plane_num,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
601 IVIBandDesc *band, AVCodecContext *avctx)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
602 {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
603 int result, i, t, idx1, idx2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
604 IVITile *tile;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
605
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
606 band->buf = band->bufs[ctx->dst_buf];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
607 band->ref_buf = band->bufs[ctx->ref_buf];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
608 band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
609
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
610 result = decode_band_hdr(ctx, band, avctx);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
611 if (result) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
612 av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n",
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
613 result);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
614 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
615 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
616
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
617 if (band->is_empty) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
618 av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
619 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
620 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
621
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
622 band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
623
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
624 /* apply corrections to the selected rvmap table if present */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
625 for (i = 0; i < band->num_corr; i++) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
626 idx1 = band->corr[i*2];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
627 idx2 = band->corr[i*2+1];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
628 FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
629 FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
630 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
631
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
632 for (t = 0; t < band->num_tiles; t++) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
633 tile = &band->tiles[t];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
634
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
635 tile->is_empty = get_bits1(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
636 if (tile->is_empty) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
637 ff_ivi_process_empty_tile(avctx, band, tile,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
638 (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
639 align_get_bits(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
640 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
641 tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
642
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
643 result = decode_mb_info(ctx, band, tile, avctx);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
644 if (result < 0)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
645 break;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
646
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
647 if (band->blk_size == 8) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
648 band->intra_base = &ivi5_base_quant_8x8_intra[band->quant_mat][0];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
649 band->inter_base = &ivi5_base_quant_8x8_inter[band->quant_mat][0];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
650 band->intra_scale = &ivi5_scale_quant_8x8_intra[band->quant_mat][0];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
651 band->inter_scale = &ivi5_scale_quant_8x8_inter[band->quant_mat][0];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
652 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
653 band->intra_base = ivi5_base_quant_4x4_intra;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
654 band->inter_base = ivi5_base_quant_4x4_inter;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
655 band->intra_scale = ivi5_scale_quant_4x4_intra;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
656 band->inter_scale = ivi5_scale_quant_4x4_inter;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
657 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
658
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
659 result = ff_ivi_decode_blocks(&ctx->gb, band, tile);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
660 if (result < 0) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
661 av_log(avctx, AV_LOG_ERROR, "Corrupted blocks data encountered!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
662 break;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
663 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
664 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
665 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
666
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
667 /* restore the selected rvmap table by applying its corrections in reverse order */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
668 for (i = band->num_corr-1; i >= 0; i--) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
669 idx1 = band->corr[i*2];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
670 idx2 = band->corr[i*2+1];
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
671 FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
672 FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
673 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
674
11120
b622564e2d60 Move band checksum verifying into preprocessor condition, so compiler won't
kostya
parents: 11107
diff changeset
675 #if IVI_DEBUG
b622564e2d60 Move band checksum verifying into preprocessor condition, so compiler won't
kostya
parents: 11107
diff changeset
676 if (band->checksum_present) {
11121
1d4aeef800d4 Move 'chksum' declaration to the only block where that variable is used
kostya
parents: 11120
diff changeset
677 uint16_t chksum = ivi_calc_band_checksum(band);
11107
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
678 if (chksum != band->checksum) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
679 av_log(avctx, AV_LOG_ERROR,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
680 "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n",
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
681 band->plane, band->band_num, band->checksum, chksum);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
682 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
683 }
11120
b622564e2d60 Move band checksum verifying into preprocessor condition, so compiler won't
kostya
parents: 11107
diff changeset
684 #endif
11107
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
685
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
686 return result;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
687 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
688
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
689
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
690 /**
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
691 * Switches buffers.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
692 *
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
693 * @param ctx [in,out] ptr to the decoder context
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
694 * @param avctx [in] ptr to the AVCodecContext
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
695 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
696 static void switch_buffers(IVI5DecContext *ctx, AVCodecContext *avctx)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
697 {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
698 switch (ctx->frame_type) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
699 case FRAMETYPE_INTRA:
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
700 ctx->buf_switch = 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
701 ctx->dst_buf = 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
702 ctx->ref_buf = 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
703 break;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
704 case FRAMETYPE_INTER:
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
705 ctx->buf_switch &= 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
706 /* swap buffers only if there were no droppable frames */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
707 if (ctx->prev_frame_type != FRAMETYPE_INTER_NOREF &&
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
708 ctx->prev_frame_type != FRAMETYPE_INTER_SCAL)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
709 ctx->buf_switch ^= 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
710 ctx->dst_buf = ctx->buf_switch;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
711 ctx->ref_buf = ctx->buf_switch ^ 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
712 break;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
713 case FRAMETYPE_INTER_SCAL:
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
714 if (ctx->prev_frame_type == FRAMETYPE_INTER_NOREF)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
715 break;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
716 if (ctx->prev_frame_type != FRAMETYPE_INTER_SCAL) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
717 ctx->buf_switch ^= 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
718 ctx->dst_buf = ctx->buf_switch;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
719 ctx->ref_buf = ctx->buf_switch ^ 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
720 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
721 ctx->buf_switch ^= 2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
722 ctx->dst_buf = 2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
723 ctx->ref_buf = ctx->buf_switch & 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
724 if (!(ctx->buf_switch & 2))
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
725 FFSWAP(int, ctx->dst_buf, ctx->ref_buf);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
726 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
727 break;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
728 case FRAMETYPE_INTER_NOREF:
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
729 if (ctx->prev_frame_type == FRAMETYPE_INTER_SCAL) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
730 ctx->buf_switch ^= 2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
731 ctx->dst_buf = 2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
732 ctx->ref_buf = ctx->buf_switch & 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
733 if (!(ctx->buf_switch & 2))
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
734 FFSWAP(int, ctx->dst_buf, ctx->ref_buf);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
735 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
736 ctx->buf_switch ^= 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
737 ctx->dst_buf = ctx->buf_switch & 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
738 ctx->ref_buf = (ctx->buf_switch & 1) ^ 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
739 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
740 break;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
741 case FRAMETYPE_NULL:
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
742 return;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
743 default:
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
744 av_log(avctx, AV_LOG_ERROR, "unsupported frame type: %d\n", ctx->frame_type);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
745 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
746 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
747
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
748
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
749 /**
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
750 * Initializes Indeo5 decoder.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
751 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
752 static av_cold int decode_init(AVCodecContext *avctx)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
753 {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
754 IVI5DecContext *ctx = avctx->priv_data;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
755 int i, result;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
756
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
757 /* initialize static vlc tables for macroblock/block signals */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
758 for (i = 0; i < 8; i++) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
759 ff_ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i], &mb_vlc_tabs[i], 1);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
760 ff_ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i], &blk_vlc_tabs[i], 1);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
761 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
762
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
763 /* copy rvmap tables in our context so we can apply changes to them */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
764 memcpy(ctx->rvmap_tabs, ff_ivi_rvmap_tabs, sizeof(ff_ivi_rvmap_tabs));
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
765
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
766 /* set the initial picture layout according to the basic profile:
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
767 there is only one band per plane (no scalability), only one tile (no local decoding)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
768 and picture format = YVU9 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
769 ctx->pic_conf.pic_width = avctx->width;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
770 ctx->pic_conf.pic_height = avctx->height;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
771 ctx->pic_conf.chroma_width = (avctx->width + 3) >> 2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
772 ctx->pic_conf.chroma_height = (avctx->height + 3) >> 2;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
773 ctx->pic_conf.tile_width = avctx->width;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
774 ctx->pic_conf.tile_height = avctx->height;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
775 ctx->pic_conf.luma_bands = ctx->pic_conf.chroma_bands = 1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
776
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
777 result = ff_ivi_init_planes(ctx->planes, &ctx->pic_conf);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
778 if (result) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
779 av_log(avctx, AV_LOG_ERROR, "Couldn't allocate color planes!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
780 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
781 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
782
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
783 avctx->pix_fmt = PIX_FMT_YUV410P;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
784
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
785 return 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
786 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
787
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
788
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
789 /**
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
790 * main decoder function
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
791 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
792 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
793 AVPacket *avpkt)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
794 {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
795 IVI5DecContext *ctx = avctx->priv_data;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
796 const uint8_t *buf = avpkt->data;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
797 int buf_size = avpkt->size;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
798 int result, p, b;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
799
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
800 init_get_bits(&ctx->gb, buf, buf_size * 8);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
801 ctx->frame_data = buf;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
802 ctx->frame_size = buf_size;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
803
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
804 result = decode_pic_hdr(ctx, avctx);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
805 if (result) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
806 av_log(avctx, AV_LOG_ERROR,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
807 "Error while decoding picture header: %d\n", result);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
808 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
809 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
810
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
811 if (ctx->gop_flags & IVI5_IS_PROTECTED) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
812 av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
813 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
814 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
815
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
816 switch_buffers(ctx, avctx);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
817
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
818 //START_TIMER;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
819
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
820 if (ctx->frame_type == FRAMETYPE_NULL) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
821 ctx->frame_type = ctx->prev_frame_type;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
822 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
823 for (p = 0; p < 3; p++) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
824 for (b = 0; b < ctx->planes[p].num_bands; b++) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
825 result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
826 if (result) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
827 av_log(avctx, AV_LOG_ERROR,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
828 "Error while decoding band: %d, plane: %d\n", b, p);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
829 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
830 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
831 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
832 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
833 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
834
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
835 //STOP_TIMER("decode_planes");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
836
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
837 if (ctx->frame.data[0])
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
838 avctx->release_buffer(avctx, &ctx->frame);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
839
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
840 ctx->frame.reference = 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
841 if (avctx->get_buffer(avctx, &ctx->frame) < 0) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
842 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
843 return -1;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
844 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
845
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
846 if (ctx->is_scalable) {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
847 ff_ivi_recompose53 (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
848 } else {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
849 ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
850 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
851
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
852 ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
853 ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
854
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
855 *data_size = sizeof(AVFrame);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
856 *(AVFrame*)data = ctx->frame;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
857
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
858 return buf_size;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
859 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
860
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
861
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
862 /**
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
863 * Closes Indeo5 decoder and cleans up its context.
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
864 */
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
865 static av_cold int decode_close(AVCodecContext *avctx)
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
866 {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
867 IVI5DecContext *ctx = avctx->priv_data;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
868
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
869 ff_ivi_free_buffers(&ctx->planes[0]);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
870
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
871 if (ctx->frame.data[0])
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
872 avctx->release_buffer(avctx, &ctx->frame);
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
873
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
874 return 0;
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
875 }
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
876
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
877
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
878 AVCodec indeo5_decoder = {
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
879 .name = "indeo5",
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
880 .type = CODEC_TYPE_VIDEO,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
881 .id = CODEC_ID_INDEO5,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
882 .priv_data_size = sizeof(IVI5DecContext),
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
883 .init = decode_init,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
884 .close = decode_close,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
885 .decode = decode_frame,
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
886 .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"),
5ca4eb4a1a3f Indeo 5 decoder
kostya
parents:
diff changeset
887 };