annotate kgv1dec.c @ 12454:f4355cd85faa libavcodec

Port latest x264 deblock asm (before they moved to using NV12 as internal format), LGPL'ed with permission from Jason and Loren. This includes mmx2 code, so remove inline asm from h264dsp_mmx.c accordingly.
author rbultje
date Fri, 03 Sep 2010 16:52:46 +0000
parents 914f484bb476
children ffb3668ff7af
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11425
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
1 /*
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
2 * Kega Game Video (KGV1) decoder
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
3 * Copyright (c) 2010 Daniel Verkamp
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
4 *
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
5 * This file is part of FFmpeg.
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
6 *
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
11 *
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
15 * Lesser General Public License for more details.
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
16 *
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
20 */
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
21
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
22 /**
11644
7dd2a45249a9 Remove explicit filename from Doxygen @file commands.
diego
parents: 11560
diff changeset
23 * @file
11425
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
24 * Kega Game Video decoder
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
25 */
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
26
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
27 #include "libavutil/intreadwrite.h"
12372
914f484bb476 Remove use of the deprecated function avcodec_check_dimensions(), use
stefano
parents: 12108
diff changeset
28 #include "libavcore/imgutils.h"
11425
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
29 #include "avcodec.h"
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
30
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
31 typedef struct {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
32 AVCodecContext *avctx;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
33 AVFrame pic;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
34 uint16_t *prev, *cur;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
35 } KgvContext;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
36
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
37 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
38 {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
39 const uint8_t *buf = avpkt->data;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
40 const uint8_t *buf_end = buf + avpkt->size;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
41 KgvContext * const c = avctx->priv_data;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
42 int offsets[7];
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
43 uint16_t *out, *prev;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
44 int outcnt = 0, maxcnt;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
45 int w, h, i;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
46
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
47 if (avpkt->size < 2)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
48 return -1;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
49
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
50 w = (buf[0] + 1) * 8;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
51 h = (buf[1] + 1) * 8;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
52 buf += 2;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
53
12372
914f484bb476 Remove use of the deprecated function avcodec_check_dimensions(), use
stefano
parents: 12108
diff changeset
54 if (av_check_image_size(w, h, 0, avctx))
11425
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
55 return -1;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
56
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
57 if (w != avctx->width || h != avctx->height)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
58 avcodec_set_dimensions(avctx, w, h);
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
59
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
60 maxcnt = w * h;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
61
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
62 out = av_realloc(c->cur, w * h * 2);
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
63 if (!out)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
64 return -1;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
65 c->cur = out;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
66
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
67 prev = av_realloc(c->prev, w * h * 2);
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
68 if (!prev)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
69 return -1;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
70 c->prev = prev;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
71
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
72 for (i = 0; i < 7; i++)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
73 offsets[i] = -1;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
74
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
75 while (outcnt < maxcnt && buf_end - 2 > buf) {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
76 int code = AV_RL16(buf);
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
77 buf += 2;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
78
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
79 if (!(code & 0x8000)) {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
80 out[outcnt++] = code; // rgb555 pixel coded directly
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
81 } else {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
82 int count;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
83 uint16_t *inp;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
84
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
85 if ((code & 0x6000) == 0x6000) {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
86 // copy from previous frame
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
87 int oidx = (code >> 10) & 7;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
88 int start;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
89
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
90 count = (code & 0x3FF) + 3;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
91
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
92 if (offsets[oidx] < 0) {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
93 if (buf_end - 3 < buf)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
94 break;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
95 offsets[oidx] = AV_RL24(buf);
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
96 buf += 3;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
97 }
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
98
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
99 start = (outcnt + offsets[oidx]) % maxcnt;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
100
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
101 if (maxcnt - start < count)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
102 break;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
103
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
104 inp = prev + start;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
105 } else {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
106 // copy from earlier in this frame
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
107 int offset = (code & 0x1FFF) + 1;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
108
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
109 if (!(code & 0x6000)) {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
110 count = 2;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
111 } else if ((code & 0x6000) == 0x2000) {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
112 count = 3;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
113 } else {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
114 if (buf_end - 1 < buf)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
115 break;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
116 count = 4 + *buf++;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
117 }
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
118
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
119 if (outcnt < offset)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
120 break;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
121
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
122 inp = out + outcnt - offset;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
123 }
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
124
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
125 if (maxcnt - outcnt < count)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
126 break;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
127
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
128 for (i = 0; i < count; i++)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
129 out[outcnt++] = inp[i];
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
130 }
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
131 }
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
132
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
133 if (outcnt - maxcnt)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
134 av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt);
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
135
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
136 c->pic.data[0] = (uint8_t *)c->cur;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
137 c->pic.linesize[0] = w * 2;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
138
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
139 *data_size = sizeof(AVFrame);
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
140 *(AVFrame*)data = c->pic;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
141
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
142 FFSWAP(uint16_t *, c->cur, c->prev);
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
143
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
144 return avpkt->size;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
145 }
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
146
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
147 static av_cold int decode_init(AVCodecContext *avctx)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
148 {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
149 KgvContext * const c = avctx->priv_data;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
150
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
151 c->avctx = avctx;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
152 avctx->pix_fmt = PIX_FMT_RGB555;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
153
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
154 return 0;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
155 }
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
156
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
157 static av_cold int decode_end(AVCodecContext *avctx)
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
158 {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
159 KgvContext * const c = avctx->priv_data;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
160
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
161 av_freep(&c->cur);
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
162 av_freep(&c->prev);
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
163
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
164 return 0;
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
165 }
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
166
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
167 AVCodec kgv1_decoder = {
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
168 "kgv1",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 11425
diff changeset
169 AVMEDIA_TYPE_VIDEO,
11425
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
170 CODEC_ID_KGV1,
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
171 sizeof(KgvContext),
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
172 decode_init,
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
173 NULL,
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
174 decode_end,
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
175 decode_frame,
12108
c35d7bc64882 Add new decoder property max_lowres and do not init decoder if requested value is higher.
cehoyos
parents: 11644
diff changeset
176 .max_lowres = 1,
11425
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
177 .long_name = NULL_IF_CONFIG_SMALL("Kega Game Video"),
599e717b0549 Kega Game Video (KGV1) decoder
daniel
parents:
diff changeset
178 };