annotate vb.c @ 5883:c64d94561b19 libavcodec

Fix deblocking filter for field pictures by properly looking for first row in bottom fields and preventing the use of "fast" deblocking for such.
author heydowns
date Wed, 07 Nov 2007 23:35:48 +0000
parents 82ac47c0c6dd
children dfdff1ca78a7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5847
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
1 /*
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
2 * Beam Software VB decoder
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
3 * Copyright (c) 2007 Konstantin Shishkov
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
4 *
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
5 * This file is part of FFmpeg.
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
6 *
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
11 *
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
15 * Lesser General Public License for more details.
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
16 *
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
20 */
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
21
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
22 /**
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
23 * @file vb.c
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
24 * VB Video decoder
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
25 */
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
26
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
27 #include <stdio.h>
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
28 #include <stdlib.h>
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
29
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
30 #include "avcodec.h"
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
31 #include "bytestream.h"
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
32
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
33 enum VBFlags{
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
34 VB_HAS_GMC = 0x01,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
35 VB_HAS_AUDIO = 0x04,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
36 VB_HAS_VIDEO = 0x08,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
37 VB_HAS_PALETTE = 0x10,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
38 VB_HAS_LENGTH = 0x20
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
39 };
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
40
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
41 typedef struct VBDecContext {
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
42 AVCodecContext *avctx;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
43 AVFrame pic;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
44
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
45 uint8_t *frame, *prev_frame;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
46 uint32_t pal[256];
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
47 uint8_t *stream;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
48 } VBDecContext;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
49
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
50 static const uint16_t vb_patterns[64] = {
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
51 0x0660, 0xFF00, 0xCCCC, 0xF000, 0x8888, 0x000F, 0x1111, 0xFEC8,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
52 0x8CEF, 0x137F, 0xF731, 0xC800, 0x008C, 0x0013, 0x3100, 0xCC00,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
53 0x00CC, 0x0033, 0x3300, 0x0FF0, 0x6666, 0x00F0, 0x0F00, 0x2222,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
54 0x4444, 0xF600, 0x8CC8, 0x006F, 0x1331, 0x318C, 0xC813, 0x33CC,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
55 0x6600, 0x0CC0, 0x0066, 0x0330, 0xF900, 0xC88C, 0x009F, 0x3113,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
56 0x6000, 0x0880, 0x0006, 0x0110, 0xCC88, 0xFC00, 0x00CF, 0x88CC,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
57 0x003F, 0x1133, 0x3311, 0xF300, 0x6FF6, 0x0603, 0x08C6, 0x8C63,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
58 0xC631, 0x6310, 0xC060, 0x0136, 0x136C, 0x36C8, 0x6C80, 0x324C
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
59 };
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
60
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
61 static void vb_decode_palette(VBDecContext *c)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
62 {
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
63 int start, size, i;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
64
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
65 start = bytestream_get_byte(&c->stream);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
66 size = (bytestream_get_byte(&c->stream) - 1) & 0xFF;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
67 if(start + size > 255){
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
68 av_log(c->avctx, AV_LOG_ERROR, "Palette change runs beyond entry 256\n");
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
69 return;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
70 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
71 for(i = start; i <= start + size; i++)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
72 c->pal[i] = bytestream_get_be24(&c->stream);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
73 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
74
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
75 static inline int check_pixel(uint8_t *buf, uint8_t *start, uint8_t *end)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
76 {
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
77 return buf >= start && buf < end;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
78 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
79
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
80 static inline int check_line(uint8_t *buf, uint8_t *start, uint8_t *end)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
81 {
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
82 return buf >= start && (buf + 4) <= end;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
83 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
84
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
85 static int vb_decode_framedata(VBDecContext *c, uint8_t *buf, int offset)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
86 {
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
87 uint8_t *prev, *cur;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
88 int blk, blocks, t, blk2;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
89 int blocktypes = 0;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
90 int x, y, a, b;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
91 int pattype, pattern;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
92 const int width = c->avctx->width;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
93 uint8_t *pstart = c->prev_frame;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
94 uint8_t *pend = c->prev_frame + width*c->avctx->height;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
95
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
96 prev = c->prev_frame + offset;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
97 cur = c->frame;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
98
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
99 blocks = (c->avctx->width >> 2) * (c->avctx->height >> 2);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
100 blk2 = 0;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
101 for(blk = 0; blk < blocks; blk++){
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
102 if(!(blk & 3))
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
103 blocktypes = bytestream_get_byte(&buf);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
104 switch(blocktypes & 0xC0){
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
105 case 0x00: //skip
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
106 for(y = 0; y < 4; y++)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
107 if(check_line(prev + y*width, pstart, pend))
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
108 memcpy(cur + y*width, prev + y*width, 4);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
109 else
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
110 memset(cur + y*width, 0, 4);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
111 break;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
112 case 0x40:
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
113 t = bytestream_get_byte(&buf);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
114 if(!t){ //raw block
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
115 for(y = 0; y < 4; y++)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
116 memcpy(cur + y*width, buf + y*4, 4);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
117 buf += 16;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
118 }else{ // motion compensation
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
119 x = ((t & 0xF)^8) - 8;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
120 y = ((t >> 4) ^8) - 8;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
121 t = x + y*width;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
122 for(y = 0; y < 4; y++)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
123 if(check_line(prev + t + y*width, pstart, pend))
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
124 memcpy(cur + y*width, prev + t + y*width, 4);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
125 else
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
126 memset(cur + y*width, 0, 4);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
127 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
128 break;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
129 case 0x80: // fill
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
130 t = bytestream_get_byte(&buf);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
131 for(y = 0; y < 4; y++)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
132 memset(cur + y*width, t, 4);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
133 break;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
134 case 0xC0: // pattern fill
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
135 t = bytestream_get_byte(&buf);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
136 pattype = t >> 6;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
137 pattern = vb_patterns[t & 0x3F];
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
138 switch(pattype){
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
139 case 0:
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
140 a = bytestream_get_byte(&buf);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
141 b = bytestream_get_byte(&buf);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
142 for(y = 0; y < 4; y++)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
143 for(x = 0; x < 4; x++, pattern >>= 1)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
144 cur[x + y*width] = (pattern & 1) ? b : a;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
145 break;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
146 case 1:
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
147 pattern = ~pattern;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
148 case 2:
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
149 a = bytestream_get_byte(&buf);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
150 for(y = 0; y < 4; y++)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
151 for(x = 0; x < 4; x++, pattern >>= 1)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
152 if(pattern & 1 && check_pixel(prev + x + y*width, pstart, pend))
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
153 cur[x + y*width] = prev[x + y*width];
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
154 else
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
155 cur[x + y*width] = a;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
156 break;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
157 case 3:
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
158 av_log(c->avctx, AV_LOG_ERROR, "Invalid opcode seen @%d\n",blk);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
159 return -1;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
160 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
161 break;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
162 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
163 blocktypes <<= 2;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
164 cur += 4;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
165 prev += 4;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
166 blk2++;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
167 if(blk2 == (width >> 2)){
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
168 blk2 = 0;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
169 cur += width * 3;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
170 prev += width * 3;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
171 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
172 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
173 return 0;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
174 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
175
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
176 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
177 {
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
178 VBDecContext * const c = avctx->priv_data;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
179 uint8_t *outptr, *srcptr;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
180 int i, j;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
181 int flags;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
182 uint32_t size;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
183 int rest = buf_size;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
184 int offset = 0;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
185
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
186 c->stream = buf;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
187 flags = bytestream_get_le16(&c->stream);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
188 rest -= 2;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
189
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
190 if(flags & VB_HAS_GMC){
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
191 i = (int16_t)bytestream_get_le16(&c->stream);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
192 j = (int16_t)bytestream_get_le16(&c->stream);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
193 offset = i + j * avctx->width;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
194 rest -= 4;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
195 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
196 if(flags & VB_HAS_VIDEO){
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
197 size = bytestream_get_le32(&c->stream);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
198 if(size > rest){
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
199 av_log(avctx, AV_LOG_ERROR, "Frame size is too big\n");
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
200 return -1;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
201 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
202 vb_decode_framedata(c, c->stream, offset);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
203 c->stream += size - 4;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
204 rest -= size;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
205 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
206 if(flags & VB_HAS_PALETTE){
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
207 size = bytestream_get_le32(&c->stream);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
208 if(size > rest){
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
209 av_log(avctx, AV_LOG_ERROR, "Palette size is too big\n");
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
210 return -1;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
211 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
212 vb_decode_palette(c);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
213 rest -= size;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
214 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
215
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
216 memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
217 c->pic.palette_has_changed = flags & VB_HAS_PALETTE;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
218
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
219 outptr = c->pic.data[0];
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
220 srcptr = c->frame;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
221
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
222 for(i = 0; i < avctx->height; i++){
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
223 memcpy(outptr, srcptr, avctx->width);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
224 srcptr += avctx->width;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
225 outptr += c->pic.linesize[0];
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
226 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
227
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
228 FFSWAP(uint8_t*, c->frame, c->prev_frame);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
229
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
230 *data_size = sizeof(AVFrame);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
231 *(AVFrame*)data = c->pic;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
232
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
233 /* always report that the buffer was completely consumed */
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
234 return buf_size;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
235 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
236
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
237 static int decode_init(AVCodecContext *avctx)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
238 {
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
239 VBDecContext * const c = avctx->priv_data;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
240
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
241 c->avctx = avctx;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
242 avctx->pix_fmt = PIX_FMT_PAL8;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
243
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
244 if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
245 return -1;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
246 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
247
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
248 c->pic.reference = 1;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
249 if(avctx->get_buffer(avctx, &c->pic) < 0){
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
250 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
251 return -1;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
252 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
253
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
254 c->frame = av_malloc( avctx->width * avctx->height);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
255 c->prev_frame = av_malloc( avctx->width * avctx->height);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
256
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
257 return 0;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
258 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
259
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
260 static int decode_end(AVCodecContext *avctx)
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
261 {
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
262 VBDecContext *c = avctx->priv_data;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
263
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
264 av_freep(&c->frame);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
265 av_freep(&c->prev_frame);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
266 if(c->pic.data[0])
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
267 avctx->release_buffer(avctx, &c->pic);
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
268
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
269 return 0;
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
270 }
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
271
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
272 AVCodec vb_decoder = {
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
273 "vb",
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
274 CODEC_TYPE_VIDEO,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
275 CODEC_ID_VB,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
276 sizeof(VBDecContext),
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
277 decode_init,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
278 NULL,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
279 decode_end,
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
280 decode_frame
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
281 };
82ac47c0c6dd Beam Software SIFF demuxer and video decoder
kostya
parents:
diff changeset
282