1 /*
2 * NuppelVideo decoder
3 * Copyright (c) 2006 Reimar Doeffinger
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <stddef.h>
24
34
45
46 /**
47 * @brief copy frame data from buffer to AVFrame, handling stride.
48 * @param f destination AVFrame
49 * @param src source buffer, does not use any line-stride
50 * @param width width of the video frame
51 * @param height height of the video frame
52 */
54 {
55 uint8_t *src_data[4];
56 int src_linesize[4];
59 av_image_copy(
f->data,
f->linesize, (
const uint8_t **)src_data, src_linesize,
61 }
62
63 /**
64 * @brief extract quantization tables from codec data into our context
65 */
68 {
70 if (
size < 2 * 64 * 4) {
73 }
74 for (
i = 0;
i < 64;
i++, buf += 4)
76 for (
i = 0;
i < 64;
i++, buf += 4)
78 return 0;
79 }
80
81 /**
82 * @brief set quantization tables from a quality value
83 */
85 {
88 for (
i = 0;
i < 64;
i++) {
91 }
92 }
93
96 {
99
105 // also reserve space for a possible additional header
109 if (buf_size > INT_MAX/8)
110 return -1;
116 buf_size);
117 if (!
c->decomp_buf) {
119 "Can't allocate decompression buffer.\n");
121 }
124 return 1;
127
128 return 0;
129 }
130
133 {
134 const uint8_t *buf = avpkt->
data;
135 int buf_size = avpkt->
size;
137 int orig_size = buf_size;
139 int size_change = 0;
140 int minsize = 0;
143 enum {
144 NUV_UNCOMPRESSED = '0',
145 NUV_RTJPEG = '1',
146 NUV_RTJPEG_IN_LZO = '2',
147 NUV_LZO = '3',
148 NUV_BLACK = 'N',
149 NUV_COPY_LAST = 'L'
150 } comptype;
151
152 if (buf_size < 12) {
155 }
156
157 // codec data (rtjpeg quant tables)
158 if (buf[0] == 'D' && buf[1] == 'R') {
160 // Skip the rest of the frame header.
161 buf = &buf[12];
162 buf_size -= 12;
167 return orig_size;
168 }
169
170 if (buf_size < 12 || buf[0] != 'V') {
173 }
174 comptype = buf[1];
175 switch (comptype) {
176 case NUV_RTJPEG_IN_LZO:
177 case NUV_RTJPEG:
178 keyframe = !buf[2];
179 if (
c->width < 16 ||
c->height < 16) {
181 }
182 break;
183 case NUV_COPY_LAST:
185 keyframe = 0;
186 break;
187 default:
188 keyframe = 1;
189 break;
190 }
191 switch (comptype) {
192 case NUV_UNCOMPRESSED:
193 minsize =
c->width *
c->height * 3 / 2;
194 break;
195 case NUV_RTJPEG:
196 minsize =
c->width/16 * (
c->height/16) * 6;
197 break;
198 case NUV_BLACK:
199 case NUV_COPY_LAST:
200 case NUV_LZO:
201 case NUV_RTJPEG_IN_LZO:
202 break;
203 default:
206 }
207 if (buf_size < minsize / 4)
209 retry:
210 // Skip the rest of the frame header.
211 buf = &buf[12];
212 buf_size -= 12;
213 if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) {
215 int inlen = buf_size;
219 }
223 }
224 if (
c->codec_frameheader) {
229 }
230 // There seem to exist two variants of this header: one starts with 'V'
231 // and 5 bytes unknown, the other matches current MythTV and is 4 bytes size,
232 // 1 byte header size (== 12), 1 byte version (== 0)
233 if (buf[0] !=
'V' &&
AV_RL16(&buf[4]) != 0x000c) {
236 }
239 q = buf[10];
244 buf_size = avpkt->
size;
245 size_change = 1;
246 goto retry;
247 }
250 }
251
252 if (size_change || keyframe) {
255 }
256
260 memset(
c->pic->data[0], 0, avctx->
height *
c->pic->linesize[0]);
261 memset(
c->pic->data[1], 0x80, avctx->
height *
c->pic->linesize[1] / 2);
262 memset(
c->pic->data[2], 0x80, avctx->
height *
c->pic->linesize[2] / 2);
263 }
264
266 c->pic->key_frame = keyframe;
267 // decompress/copy/whatever data
268 switch (comptype) {
269 case NUV_LZO:
270 case NUV_UNCOMPRESSED: {
274 height = buf_size /
c->width / 3 * 2;
275 }
278 break;
279 }
280 case NUV_RTJPEG_IN_LZO:
281 case NUV_RTJPEG:
285 break;
286 case NUV_BLACK:
287 memset(
c->pic->data[0], 0,
c->width *
c->height);
288 memset(
c->pic->data[1], 128,
c->width *
c->height / 4);
289 memset(
c->pic->data[2], 128,
c->width *
c->height / 4);
290 break;
291 case NUV_COPY_LAST:
292 /* nothing more to do here */
293 break;
294 }
295
298
299 *got_frame = 1;
300 return orig_size;
301 }
302
304 {
307
311
313 c->decomp_buf =
NULL;
317
319
322
324
327
328 return 0;
329 }
330
332 {
334
337
338 return 0;
339 }
340
352 };