annotate yop.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents ffb3668ff7af
children
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"
12372
914f484bb476 Remove use of the deprecated function avcodec_check_dimensions(), use
stefano
parents: 12024
diff changeset
27 #include "libavcore/imgutils.h"
11553
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
28
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
29 #include "avcodec.h"
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
30 #include "get_bits.h"
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
31
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
32 typedef struct YopDecContext {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
33 AVFrame frame;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
34 AVCodecContext *avctx;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
35
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
36 int num_pal_colors;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
37 int first_color[2];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
38 int frame_data_length;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
39 int row_pos;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
40
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
41 uint8_t *low_nibble;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
42 uint8_t *srcptr;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
43 uint8_t *dstptr;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
44 uint8_t *dstbuf;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
45 } YopDecContext;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
46
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
47 // These tables are taken directly from:
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
48 // http://wiki.multimedia.cx/index.php?title=Psygnosis_YOP
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
49
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
50 /**
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
51 * Lookup table for painting macroblocks. Bytes 0-2 of each entry contain
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
52 * the macroblock positions to be painted (taken as (0, B0, B1, B2)).
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
53 * Byte 3 contains the number of bytes consumed on the input,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
54 * equal to max(bytes 0-2) + 1.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
55 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
56 static const uint8_t paint_lut[15][4] =
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
57 {{1, 2, 3, 4}, {1, 2, 0, 3},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
58 {1, 2, 1, 3}, {1, 2, 2, 3},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
59 {1, 0, 2, 3}, {1, 0, 0, 2},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
60 {1, 0, 1, 2}, {1, 1, 2, 3},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
61 {0, 1, 2, 3}, {0, 1, 0, 2},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
62 {1, 1, 0, 2}, {0, 1, 1, 2},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
63 {0, 0, 1, 2}, {0, 0, 0, 1},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
64 {1, 1, 1, 2},
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 /**
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
68 * Lookup table for copying macroblocks. Each entry contains the respective
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
69 * x and y pixel offset for the copy source.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
70 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
71 static const int8_t motion_vector[16][2] =
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
72 {{-4, -4}, {-2, -4},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
73 { 0, -4}, { 2, -4},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
74 {-4, -2}, {-4, 0},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
75 {-3, -3}, {-1, -3},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
76 { 1, -3}, { 3, -3},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
77 {-3, -1}, {-2, -2},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
78 { 0, -2}, { 2, -2},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
79 { 4, -2}, {-2, 0},
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
80 };
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
81
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
82 static av_cold int yop_decode_init(AVCodecContext *avctx)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
83 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
84 YopDecContext *s = avctx->priv_data;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
85 s->avctx = avctx;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
86
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
87 if (avctx->width & 1 || avctx->height & 1 ||
12462
ffb3668ff7af Use new imgutils.h API names, fix deprecation warnings.
stefano
parents: 12372
diff changeset
88 av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) {
11553
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
89 av_log(avctx, AV_LOG_ERROR, "YOP has invalid dimensions\n");
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
90 return -1;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
91 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
92
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
93 avctx->pix_fmt = PIX_FMT_PAL8;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
94
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
95 s->num_pal_colors = avctx->extradata[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
96 s->first_color[0] = avctx->extradata[1];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
97 s->first_color[1] = avctx->extradata[2];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
98
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
99 if (s->num_pal_colors + s->first_color[0] > 256 ||
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
100 s->num_pal_colors + s->first_color[1] > 256) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
101 av_log(avctx, AV_LOG_ERROR,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
102 "YOP: palette parameters invalid, header probably corrupt\n");
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
103 return AVERROR_INVALIDDATA;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
104 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
105
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
106 return 0;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
107 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
108
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
109 static av_cold int yop_decode_close(AVCodecContext *avctx)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
110 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
111 YopDecContext *s = avctx->priv_data;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
112 if (s->frame.data[0])
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
113 avctx->release_buffer(avctx, &s->frame);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
114 return 0;
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 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11644
diff changeset
118 * Paint a macroblock using the pattern in paint_lut.
11553
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
119 * @param s codec context
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
120 * @param tag the tag that was in the nibble
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
121 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
122 static void yop_paint_block(YopDecContext *s, int tag)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
123 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
124 s->dstptr[0] = s->srcptr[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
125 s->dstptr[1] = s->srcptr[paint_lut[tag][0]];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
126 s->dstptr[s->frame.linesize[0]] = s->srcptr[paint_lut[tag][1]];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
127 s->dstptr[s->frame.linesize[0] + 1] = s->srcptr[paint_lut[tag][2]];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
128
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
129 // 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
130 s->srcptr += paint_lut[tag][3];
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 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11644
diff changeset
134 * Copy a previously painted macroblock to the current_block.
11553
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
135 * @param copy_tag the tag that was in the nibble
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
136 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
137 static int yop_copy_previous_block(YopDecContext *s, int copy_tag)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
138 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
139 uint8_t *bufptr;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
140
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
141 // Calculate position for the copy source
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
142 bufptr = s->dstptr + motion_vector[copy_tag][0] +
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
143 s->frame.linesize[0] * motion_vector[copy_tag][1];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
144 if (bufptr < s->dstbuf) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
145 av_log(s->avctx, AV_LOG_ERROR,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
146 "YOP: cannot decode, file probably corrupt\n");
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
147 return AVERROR_INVALIDDATA;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
148 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
149
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
150 s->dstptr[0] = bufptr[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
151 s->dstptr[1] = bufptr[1];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
152 s->dstptr[s->frame.linesize[0]] = bufptr[s->frame.linesize[0]];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
153 s->dstptr[s->frame.linesize[0] + 1] = bufptr[s->frame.linesize[0] + 1];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
154
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
155 return 0;
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 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11644
diff changeset
159 * Return the next nibble in sequence, consuming a new byte on the input
11553
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
160 * only if necessary.
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
161 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
162 static uint8_t yop_get_next_nibble(YopDecContext *s)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
163 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
164 int ret;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
165
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
166 if (s->low_nibble) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
167 ret = *s->low_nibble & 0xf;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
168 s->low_nibble = NULL;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
169 }else {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
170 s->low_nibble = s->srcptr++;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
171 ret = *s->low_nibble >> 4;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
172 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
173 return ret;
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 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11644
diff changeset
177 * Take s->dstptr to the next macroblock in sequence.
11553
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
178 */
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
179 static void yop_next_macroblock(YopDecContext *s)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
180 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
181 // If we are advancing to the next row of macroblocks
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
182 if (s->row_pos == s->frame.linesize[0] - 2) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
183 s->dstptr += s->frame.linesize[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
184 s->row_pos = 0;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
185 }else {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
186 s->row_pos += 2;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
187 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
188 s->dstptr += 2;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
189 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
190
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
191 static int yop_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
192 AVPacket *avpkt)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
193 {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
194 YopDecContext *s = avctx->priv_data;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
195 int tag, firstcolor, is_odd_frame;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
196 int ret, i;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
197 uint32_t *palette;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
198
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
199 if (s->frame.data[0])
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
200 avctx->release_buffer(avctx, &s->frame);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
201
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
202 ret = avctx->get_buffer(avctx, &s->frame);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
203 if (ret < 0) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
204 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
205 return ret;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
206 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
207
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
208 s->frame.linesize[0] = avctx->width;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
209
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
210 s->dstbuf = s->frame.data[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
211 s->dstptr = s->frame.data[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
212 s->srcptr = avpkt->data + 4;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
213 s->row_pos = 0;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
214 s->low_nibble = NULL;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
215
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
216 is_odd_frame = avpkt->data[0];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
217 firstcolor = s->first_color[is_odd_frame];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
218 palette = (uint32_t *)s->frame.data[1];
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
219
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
220 for (i = 0; i < s->num_pal_colors; i++, s->srcptr += 3)
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
221 palette[i + firstcolor] = (s->srcptr[0] << 18) |
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
222 (s->srcptr[1] << 10) |
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
223 (s->srcptr[2] << 2);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
224
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
225 s->frame.palette_has_changed = 1;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
226
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
227 while (s->dstptr - s->dstbuf <
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
228 avctx->width * avctx->height &&
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
229 s->srcptr - avpkt->data < avpkt->size) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
230
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
231 tag = yop_get_next_nibble(s);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
232
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
233 if (tag != 0xf) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
234 yop_paint_block(s, tag);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
235 }else {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
236 tag = yop_get_next_nibble(s);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
237 ret = yop_copy_previous_block(s, tag);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
238 if (ret < 0) {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
239 avctx->release_buffer(avctx, &s->frame);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
240 return ret;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
241 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
242 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
243 yop_next_macroblock(s);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
244 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
245
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
246 *data_size = sizeof(AVFrame);
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
247 *(AVFrame *) data = s->frame;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
248 return avpkt->size;
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
249 }
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
250
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
251 AVCodec yop_decoder = {
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
252 "yop",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 11553
diff changeset
253 AVMEDIA_TYPE_VIDEO,
11553
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
254 CODEC_ID_YOP,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
255 sizeof(YopDecContext),
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
256 yop_decode_init,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
257 NULL,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
258 yop_decode_close,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
259 yop_decode_frame,
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
260 .long_name = NULL_IF_CONFIG_SMALL("Psygnosis YOP Video"),
d35c3095f96b Implement YOP demuxer and video decoder.
stefano
parents:
diff changeset
261 };