annotate qpeg.c @ 2497:69adfbbdcdeb libavcodec

- samples from mplayer ftp in the "adv" profile seem to have profile=2, which isn't the advanced one; and indeed, using adv. profile parser fails. Using normal parser works, and that's what is done - attempt at taking care of stride for NORM2 bitplane decoding - duplication of much code from msmpeg4.c; this code isn't yet used, but goes down as far as the block layer (mainly Transform Type stuff, the remains are wild editing without checking). Unusable yet, and lacks the AC decoding (but a step further in bitstream parsing) patch by anonymous
author michael
date Fri, 04 Feb 2005 02:20:38 +0000
parents f67b63ed036d
children 00d9abc5f76f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2355
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
1 /*
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
2 * QPEG codec
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
3 * Copyright (c) 2004 Konstantin Shishkov
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
4 *
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
9 *
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
13 * Lesser General Public License for more details.
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
14 *
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
18 *
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
19 */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
20
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
21 /**
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
22 * @file qpeg.c
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
23 * QPEG codec.
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
24 */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
25
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
26 #include "avcodec.h"
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
27 #include "mpegvideo.h"
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
28
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
29 typedef struct QpegContext{
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
30 AVCodecContext *avctx;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
31 AVFrame pic;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
32 uint8_t *refdata;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
33 } QpegContext;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
34
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
35 static void qpeg_decode_intra(uint8_t *src, uint8_t *dst, int size,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
36 int stride, int width, int height)
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
37 {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
38 int i;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
39 int code;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
40 int c0, c1;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
41 int run, copy;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
42 int filled = 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
43
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
44 height--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
45 dst = dst + height * stride;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
46
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
47 while(size > 0) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
48 code = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
49 size--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
50 run = copy = 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
51 if(code == 0xFC) /* end-of-picture code */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
52 break;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
53 if(code >= 0xF8) { /* very long run */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
54 c0 = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
55 c1 = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
56 size -= 2;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
57 run = ((code & 0x7) << 16) + (c0 << 8) + c1 + 2;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
58 } else if (code >= 0xF0) { /* long run */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
59 c0 = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
60 size--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
61 run = ((code & 0xF) << 8) + c0 + 2;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
62 } else if (code >= 0xE0) { /* short run */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
63 run = (code & 0x1F) + 2;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
64 } else if (code >= 0xC0) { /* very long copy */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
65 c0 = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
66 c1 = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
67 size -= 2;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
68 copy = ((code & 0x3F) << 16) + (c0 << 8) + c1 + 1;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
69 } else if (code >= 0x80) { /* long copy */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
70 c0 = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
71 size--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
72 copy = ((code & 0x7F) << 8) + c0 + 1;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
73 } else { /* short copy */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
74 copy = code + 1;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
75 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
76
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
77 /* perform actual run or copy */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
78 if(run) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
79 int p;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
80
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
81 p = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
82 size--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
83 for(i = 0; i < run; i++) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
84 dst[filled++] = p;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
85 if (filled >= width) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
86 filled = 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
87 dst -= stride;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
88 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
89 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
90 } else {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
91 for(i = 0; i < copy; i++) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
92 dst[filled++] = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
93 if (filled >= width) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
94 filled = 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
95 dst -= stride;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
96 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
97 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
98 size -= copy;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
99 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
100 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
101 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
102
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
103 static int qpeg_table_h[16] =
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
104 { 0x00, 0x20, 0x20, 0x20, 0x18, 0x10, 0x10, 0x20, 0x10, 0x08, 0x18, 0x08, 0x08, 0x18, 0x10, 0x04};
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
105 static int qpeg_table_w[16] =
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
106 { 0x00, 0x20, 0x18, 0x08, 0x18, 0x10, 0x20, 0x10, 0x08, 0x10, 0x20, 0x20, 0x08, 0x10, 0x18, 0x04};
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
107
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
108 /* Decodes delta frames */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
109 static void qpeg_decode_inter(uint8_t *src, uint8_t *dst, int size,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
110 int stride, int width, int height,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
111 int delta, uint8_t *ctable, uint8_t *refdata)
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
112 {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
113 int i, j;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
114 int code;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
115 int filled = 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
116 uint8_t *blkdata;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
117
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
118 /* copy prev frame */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
119 for(i = 0; i < height; i++)
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
120 memcpy(refdata + (i * width), dst + (i * stride), width);
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
121
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
122 blkdata = src - 0x86;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
123 height--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
124 dst = dst + height * stride;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
125
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
126 while(size > 0) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
127 code = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
128 size--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
129
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
130 if(delta) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
131 /* motion compensation */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
132 while((code & 0xF0) == 0xF0) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
133 if(delta == 1) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
134 int me_idx;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
135 int me_w, me_h, me_x, me_y;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
136 uint8_t *me_plane;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
137 int corr, val;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
138
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
139 /* get block size by index */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
140 me_idx = code & 0xF;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
141 me_w = qpeg_table_w[me_idx];
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
142 me_h = qpeg_table_h[me_idx];
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
143
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
144 /* extract motion vector */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
145 corr = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
146 size--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
147
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
148 val = corr >> 4;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
149 if(val > 7)
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
150 val -= 16;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
151 me_x = val;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
152
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
153 val = corr & 0xF;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
154 if(val > 7)
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
155 val -= 16;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
156 me_y = val;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
157
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
158 /* do motion compensation */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
159 me_plane = refdata + (filled + me_x) + (height - me_y) * width;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
160 for(j = 0; j < me_h; j++) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
161 for(i = 0; i < me_w; i++)
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
162 dst[filled + i - (j * stride)] = me_plane[i - (j * width)];
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
163 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
164 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
165 code = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
166 size--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
167 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
168 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
169
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
170 if(code == 0xE0) /* end-of-picture code */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
171 break;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
172 if(code > 0xE0) { /* run code: 0xE1..0xFF */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
173 int p;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
174
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
175 code &= 0x1F;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
176 p = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
177 size--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
178 for(i = 0; i <= code; i++) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
179 dst[filled++] = p;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
180 if(filled >= width) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
181 filled = 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
182 dst -= stride;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
183 height--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
184 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
185 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
186 } else if(code >= 0xC0) { /* copy code: 0xC0..0xDF */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
187 code &= 0x1F;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
188
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
189 for(i = 0; i <= code; i++) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
190 dst[filled++] = *src++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
191 if(filled >= width) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
192 filled = 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
193 dst -= stride;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
194 height--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
195 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
196 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
197 size -= code + 1;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
198 } else if(code >= 0x80) { /* skip code: 0x80..0xBF */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
199 int skip;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
200
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
201 code &= 0x3F;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
202 /* codes 0x80 and 0x81 are actually escape codes,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
203 skip value minus constant is in the next byte */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
204 if(!code)
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
205 skip = (*src++) + 64;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
206 else if(code == 1)
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
207 skip = (*src++) + 320;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
208 else
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
209 skip = code;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
210 filled += skip;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
211 while( filled >= width) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
212 filled -= width;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
213 dst -= stride;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
214 height--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
215 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
216 } else {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
217 /* zero code treated as one-pixel skip */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
218 if(code)
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
219 dst[filled++] = ctable[code & 0x7F];
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
220 else
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
221 filled++;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
222 if(filled >= width) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
223 filled = 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
224 dst -= stride;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
225 height--;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
226 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
227 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
228 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
229 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
230
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
231 static int decode_frame(AVCodecContext *avctx,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
232 void *data, int *data_size,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
233 uint8_t *buf, int buf_size)
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
234 {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
235 QpegContext * const a = avctx->priv_data;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
236 AVFrame * const p= (AVFrame*)&a->pic;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
237 uint8_t* outdata;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
238 int delta;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
239
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
240 if(p->data[0])
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
241 avctx->release_buffer(avctx, p);
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
242
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
243 p->reference= 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
244 if(avctx->get_buffer(avctx, p) < 0){
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
245 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
246 return -1;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
247 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
248 outdata = a->pic.data[0];
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
249 if(buf[0x85] == 0x10) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
250 qpeg_decode_intra(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height);
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
251 } else {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
252 delta = buf[0x85];
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
253 qpeg_decode_inter(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height, delta, buf + 4, a->refdata);
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
254 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
255
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
256 /* make the palette available on the way out */
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
257 memcpy(a->pic.data[1], a->avctx->palctrl->palette, AVPALETTE_SIZE);
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
258 if (a->avctx->palctrl->palette_changed) {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
259 a->pic.palette_has_changed = 1;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
260 a->avctx->palctrl->palette_changed = 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
261 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
262
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
263 *data_size = sizeof(AVFrame);
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
264 *(AVFrame*)data = a->pic;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
265
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
266 return buf_size;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
267 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
268
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
269 static int decode_init(AVCodecContext *avctx){
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
270 QpegContext * const a = avctx->priv_data;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
271
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
272 a->avctx = avctx;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
273 avctx->pix_fmt= PIX_FMT_PAL8;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
274 avctx->has_b_frames = 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
275 a->pic.data[0] = NULL;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
276 a->refdata = av_malloc(avctx->width * avctx->height);
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
277
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
278 return 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
279 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
280
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
281 static int decode_end(AVCodecContext *avctx){
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
282 QpegContext * const a = avctx->priv_data;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
283
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
284 av_free(a->refdata);
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
285 return 0;
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
286 }
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
287
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
288 AVCodec qpeg_decoder = {
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
289 "qpeg",
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
290 CODEC_TYPE_VIDEO,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
291 CODEC_ID_QPEG,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
292 sizeof(QpegContext),
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
293 decode_init,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
294 NULL,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
295 decode_end,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
296 decode_frame,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
297 CODEC_CAP_DR1,
69fcdad5f7d5 native QPEG video decoder, courtesy of Konstantin Shishkov
melanson
parents:
diff changeset
298 };