annotate yop.c @ 11816:7c2369ec6faa libavcodec

ARM: check struct offsets only when they are used The offsets differ depending on configuration, so only check them when they will actually be used. Presently, this is when NEON is enabled.
author mru
date Wed, 02 Jun 2010 22:05:25 +0000
parents 7dd2a45249a9
children fdafbcef52f5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11553
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
1 /**
11644
7dd2a45249a9 Remove explicit filename from Doxygen @file commands.
diego
parents: 11560
diff changeset
2 * @file
11553
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
3 * Psygnosis YOP decoder
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
4 *
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
5 * Copyright (C) 2010 Mohamed Naufal Basheer <naufal11@gmail.com>
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
6 * derived from the code by
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
7 * Copyright (C) 2009 Thomas P. Higdon <thomas.p.higdon@gmail.com>
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
8 *
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
9 * This file is part of FFmpeg.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
10 *
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
11 * FFmpeg is free software; you can redistribute it and/or
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
12 * modify it under the terms of the GNU Lesser General Public
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
13 * License as published by the Free Software Foundation; either
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
14 * version 2.1 of the License, or (at your option) any later version.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
15 *
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
16 * FFmpeg is distributed in the hope that it will be useful,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
19 * Lesser General Public License for more details.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
20 *
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
21 * You should have received a copy of the GNU Lesser General Public
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
22 * License along with FFmpeg; if not, write to the Free Software
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
24 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
25
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
26 #include "libavutil/intreadwrite.h"
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
27
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
28 #include "avcodec.h"
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
29 #include "get_bits.h"
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
30
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
31 typedef struct YopDecContext {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
32 AVFrame frame;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
33 AVCodecContext *avctx;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
34
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
35 int num_pal_colors;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
36 int first_color[2];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
37 int frame_data_length;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
38 int row_pos;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
39
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
40 uint8_t *low_nibble;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
41 uint8_t *srcptr;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
42 uint8_t *dstptr;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
43 uint8_t *dstbuf;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
44 } YopDecContext;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
45
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
46 // These tables are taken directly from:
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
47 // http://wiki.multimedia.cx/index.php?title=Psygnosis_YOP
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
48
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
49 /**
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
50 * Lookup table for painting macroblocks. Bytes 0-2 of each entry contain
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
51 * the macroblock positions to be painted (taken as (0, B0, B1, B2)).
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
52 * Byte 3 contains the number of bytes consumed on the input,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
53 * equal to max(bytes 0-2) + 1.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
54 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
55 static const uint8_t paint_lut[15][4] =
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
56 {{1, 2, 3, 4}, {1, 2, 0, 3},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
57 {1, 2, 1, 3}, {1, 2, 2, 3},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
58 {1, 0, 2, 3}, {1, 0, 0, 2},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
59 {1, 0, 1, 2}, {1, 1, 2, 3},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
60 {0, 1, 2, 3}, {0, 1, 0, 2},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
61 {1, 1, 0, 2}, {0, 1, 1, 2},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
62 {0, 0, 1, 2}, {0, 0, 0, 1},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
63 {1, 1, 1, 2},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
64 };
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
65
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
66 /**
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
67 * Lookup table for copying macroblocks. Each entry contains the respective
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
68 * x and y pixel offset for the copy source.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
69 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
70 static const int8_t motion_vector[16][2] =
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
71 {{-4, -4}, {-2, -4},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
72 { 0, -4}, { 2, -4},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
73 {-4, -2}, {-4, 0},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
74 {-3, -3}, {-1, -3},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
75 { 1, -3}, { 3, -3},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
76 {-3, -1}, {-2, -2},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
77 { 0, -2}, { 2, -2},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
78 { 4, -2}, {-2, 0},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
79 };
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
80
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
81 static av_cold int yop_decode_init(AVCodecContext *avctx)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
82 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
83 YopDecContext *s = avctx->priv_data;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
84 s->avctx = avctx;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
85
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
86 if (avctx->width & 1 || avctx->height & 1 ||
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
87 avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
88 av_log(avctx, AV_LOG_ERROR, "YOP has invalid dimensions\n");
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
89 return -1;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
90 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
91
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
92 avctx->pix_fmt = PIX_FMT_PAL8;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
93
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
94 s->num_pal_colors = avctx->extradata[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
95 s->first_color[0] = avctx->extradata[1];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
96 s->first_color[1] = avctx->extradata[2];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
97
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
98 if (s->num_pal_colors + s->first_color[0] > 256 ||
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
99 s->num_pal_colors + s->first_color[1] > 256) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
100 av_log(avctx, AV_LOG_ERROR,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
101 "YOP: palette parameters invalid, header probably corrupt\n");
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
102 return AVERROR_INVALIDDATA;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
103 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
104
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
105 return 0;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
106 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
107
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
108 static av_cold int yop_decode_close(AVCodecContext *avctx)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
109 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
110 YopDecContext *s = avctx->priv_data;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
111 if (s->frame.data[0])
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
112 avctx->release_buffer(avctx, &s->frame);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
113 return 0;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
114 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
115
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
116 /**
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
117 * Paints a macroblock using the pattern in paint_lut.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
118 * @param s codec context
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
119 * @param tag the tag that was in the nibble
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
120 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
121 static void yop_paint_block(YopDecContext *s, int tag)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
122 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
123 s->dstptr[0] = s->srcptr[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
124 s->dstptr[1] = s->srcptr[paint_lut[tag][0]];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
125 s->dstptr[s->frame.linesize[0]] = s->srcptr[paint_lut[tag][1]];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
126 s->dstptr[s->frame.linesize[0] + 1] = s->srcptr[paint_lut[tag][2]];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
127
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
128 // The number of src bytes consumed is in the last part of the lut entry.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
129 s->srcptr += paint_lut[tag][3];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
130 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
131
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
132 /**
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
133 * Copies a previously painted macroblock to the current_block.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
134 * @param copy_tag the tag that was in the nibble
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
135 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
136 static int yop_copy_previous_block(YopDecContext *s, int copy_tag)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
137 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
138 uint8_t *bufptr;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
139
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
140 // Calculate position for the copy source
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
141 bufptr = s->dstptr + motion_vector[copy_tag][0] +
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
142 s->frame.linesize[0] * motion_vector[copy_tag][1];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
143 if (bufptr < s->dstbuf) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
144 av_log(s->avctx, AV_LOG_ERROR,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
145 "YOP: cannot decode, file probably corrupt\n");
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
146 return AVERROR_INVALIDDATA;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
147 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
148
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
149 s->dstptr[0] = bufptr[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
150 s->dstptr[1] = bufptr[1];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
151 s->dstptr[s->frame.linesize[0]] = bufptr[s->frame.linesize[0]];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
152 s->dstptr[s->frame.linesize[0] + 1] = bufptr[s->frame.linesize[0] + 1];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
153
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
154 return 0;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
155 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
156
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
157 /**
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
158 * Returns the next nibble in sequence, consuming a new byte on the input
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
159 * only if necessary.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
160 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
161 static uint8_t yop_get_next_nibble(YopDecContext *s)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
162 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
163 int ret;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
164
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
165 if (s->low_nibble) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
166 ret = *s->low_nibble & 0xf;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
167 s->low_nibble = NULL;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
168 }else {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
169 s->low_nibble = s->srcptr++;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
170 ret = *s->low_nibble >> 4;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
171 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
172 return ret;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
173 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
174
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
175 /**
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
176 * Takes s->dstptr to the next macroblock in sequence.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
177 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
178 static void yop_next_macroblock(YopDecContext *s)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
179 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
180 // If we are advancing to the next row of macroblocks
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
181 if (s->row_pos == s->frame.linesize[0] - 2) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
182 s->dstptr += s->frame.linesize[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
183 s->row_pos = 0;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
184 }else {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
185 s->row_pos += 2;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
186 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
187 s->dstptr += 2;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
188 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
189
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
190 static int yop_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
191 AVPacket *avpkt)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
192 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
193 YopDecContext *s = avctx->priv_data;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
194 int tag, firstcolor, is_odd_frame;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
195 int ret, i;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
196 uint32_t *palette;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
197
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
198 if (s->frame.data[0])
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
199 avctx->release_buffer(avctx, &s->frame);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
200
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
201 ret = avctx->get_buffer(avctx, &s->frame);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
202 if (ret < 0) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
203 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
204 return ret;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
205 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
206
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
207 s->frame.linesize[0] = avctx->width;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
208
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
209 s->dstbuf = s->frame.data[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
210 s->dstptr = s->frame.data[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
211 s->srcptr = avpkt->data + 4;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
212 s->row_pos = 0;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
213 s->low_nibble = NULL;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
214
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
215 is_odd_frame = avpkt->data[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
216 firstcolor = s->first_color[is_odd_frame];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
217 palette = (uint32_t *)s->frame.data[1];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
218
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
219 for (i = 0; i < s->num_pal_colors; i++, s->srcptr += 3)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
220 palette[i + firstcolor] = (s->srcptr[0] << 18) |
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
221 (s->srcptr[1] << 10) |
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
222 (s->srcptr[2] << 2);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
223
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
224 s->frame.palette_has_changed = 1;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
225
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
226 while (s->dstptr - s->dstbuf <
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
227 avctx->width * avctx->height &&
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
228 s->srcptr - avpkt->data < avpkt->size) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
229
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
230 tag = yop_get_next_nibble(s);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
231
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
232 if (tag != 0xf) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
233 yop_paint_block(s, tag);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
234 }else {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
235 tag = yop_get_next_nibble(s);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
236 ret = yop_copy_previous_block(s, tag);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
237 if (ret < 0) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
238 avctx->release_buffer(avctx, &s->frame);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
239 return ret;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
240 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
241 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
242 yop_next_macroblock(s);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
243 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
244
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
245 *data_size = sizeof(AVFrame);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
246 *(AVFrame *) data = s->frame;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
247 return avpkt->size;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
248 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
249
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
250 AVCodec yop_decoder = {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
251 "yop",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 11553
diff changeset
252 AVMEDIA_TYPE_VIDEO,
11553
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
253 CODEC_ID_YOP,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
254 sizeof(YopDecContext),
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
255 yop_decode_init,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
256 NULL,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
257 yop_decode_close,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
258 yop_decode_frame,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
259 .long_name = NULL_IF_CONFIG_SMALL("Psygnosis YOP Video"),
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
260 };