annotate nuv.c @ 6920:d02af7474bff libavcodec

Prevent 128*1<<trellis from becoming 0 and creating 0 sized arrays. fixes CID84 RUN2 CID85 RUN2 CID86 RUN2 CID87 RUN2 CID88 RUN2 CID89 RUN2 CID90 RUN2 CID91 RUN2 CID92 RUN2 CID93 RUN2 CID94 RUN2 CID95 RUN2 CID96 RUN2 CID97 RUN2 CID98 RUN2 CID99 RUN2 CID100 RUN2 CID101 RUN2 CID102 RUN2 CID103 RUN2 CID104 RUN2 CID105 RUN2 CID106 RUN2
author michael
date Wed, 28 May 2008 11:59:41 +0000
parents f7cbb7733146
children e943e1409077
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
1 /*
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
2 * NuppelVideo decoder
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
3 * Copyright (c) 2006 Reimar Doeffinger
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
4 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3224
diff changeset
5 * This file is part of FFmpeg.
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3224
diff changeset
6 *
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3224
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3224
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
11 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3224
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
15 * Lesser General Public License for more details.
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
16 *
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3224
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
20 */
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
21 #include <stdio.h>
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
22 #include <stdlib.h>
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
23
6763
f7cbb7733146 Use full path for #includes from another directory.
diego
parents: 6710
diff changeset
24 #include "libavutil/bswap.h"
f7cbb7733146 Use full path for #includes from another directory.
diego
parents: 6710
diff changeset
25 #include "libavutil/lzo.h"
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
26 #include "avcodec.h"
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
27 #include "dsputil.h"
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
28 #include "rtjpeg.h"
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
29
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
30 typedef struct {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
31 AVFrame pic;
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
32 int codec_frameheader;
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
33 int quality;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
34 int width, height;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
35 unsigned int decomp_size;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
36 unsigned char* decomp_buf;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
37 uint32_t lq[64], cq[64];
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
38 RTJpegContext rtj;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
39 DSPContext dsp;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
40 } NuvContext;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
41
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
42 static const uint8_t fallback_lquant[] = {
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
43 16, 11, 10, 16, 24, 40, 51, 61,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
44 12, 12, 14, 19, 26, 58, 60, 55,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
45 14, 13, 16, 24, 40, 57, 69, 56,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
46 14, 17, 22, 29, 51, 87, 80, 62,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
47 18, 22, 37, 56, 68, 109, 103, 77,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
48 24, 35, 55, 64, 81, 104, 113, 92,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
49 49, 64, 78, 87, 103, 121, 120, 101,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
50 72, 92, 95, 98, 112, 100, 103, 99
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
51 };
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
52
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
53 static const uint8_t fallback_cquant[] = {
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
54 17, 18, 24, 47, 99, 99, 99, 99,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
55 18, 21, 26, 66, 99, 99, 99, 99,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
56 24, 26, 56, 99, 99, 99, 99, 99,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
57 47, 66, 99, 99, 99, 99, 99, 99,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
58 99, 99, 99, 99, 99, 99, 99, 99,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
59 99, 99, 99, 99, 99, 99, 99, 99,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
60 99, 99, 99, 99, 99, 99, 99, 99,
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
61 99, 99, 99, 99, 99, 99, 99, 99
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
62 };
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
63
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
64 /**
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
65 * \brief copy frame data from buffer to AVFrame, handling stride.
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
66 * \param f destination AVFrame
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
67 * \param src source buffer, does not use any line-stride
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
68 * \param width width of the video frame
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
69 * \param height height of the video frame
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
70 */
6243
michael
parents: 6218
diff changeset
71 static void copy_frame(AVFrame *f, const uint8_t *src,
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
72 int width, int height) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
73 AVPicture pic;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
74 avpicture_fill(&pic, src, PIX_FMT_YUV420P, width, height);
4624
6a900f539e2c Add the prefix "av_" to img_crop(), img_copy() and img_pad(), and rename "img"
takis
parents: 4364
diff changeset
75 av_picture_copy((AVPicture *)f, &pic, PIX_FMT_YUV420P, width, height);
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
76 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
77
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
78 /**
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
79 * \brief extract quantization tables from codec data into our context
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
80 */
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
81 static int get_quant(AVCodecContext *avctx, NuvContext *c,
6243
michael
parents: 6218
diff changeset
82 const uint8_t *buf, int size) {
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
83 int i;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
84 if (size < 2 * 64 * 4) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
85 av_log(avctx, AV_LOG_ERROR, "insufficient rtjpeg quant data\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
86 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
87 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
88 for (i = 0; i < 64; i++, buf += 4)
4364
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 3947
diff changeset
89 c->lq[i] = AV_RL32(buf);
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
90 for (i = 0; i < 64; i++, buf += 4)
4364
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 3947
diff changeset
91 c->cq[i] = AV_RL32(buf);
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
92 return 0;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
93 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
94
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
95 /**
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
96 * \brief set quantization tables from a quality value
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
97 */
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
98 static void get_quant_quality(NuvContext *c, int quality) {
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
99 int i;
5657
ec46684cc8ad Make sure rtjpeg quality is a valid value
reimar
parents: 5656
diff changeset
100 quality = FFMAX(quality, 1);
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
101 for (i = 0; i < 64; i++) {
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
102 c->lq[i] = (fallback_lquant[i] << 7) / quality;
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
103 c->cq[i] = (fallback_cquant[i] << 7) / quality;
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
104 }
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
105 }
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
106
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
107 static int codec_reinit(AVCodecContext *avctx, int width, int height, int quality) {
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
108 NuvContext *c = avctx->priv_data;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
109 width = (width + 1) & ~1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
110 height = (height + 1) & ~1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
111 if (quality >= 0)
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
112 get_quant_quality(c, quality);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
113 if (width != c->width || height != c->height) {
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
114 if (avcodec_check_dimensions(avctx, height, width) < 0)
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
115 return 0;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
116 avctx->width = c->width = width;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
117 avctx->height = c->height = height;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
118 c->decomp_size = c->height * c->width * 3 / 2;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
119 c->decomp_buf = av_realloc(c->decomp_buf, c->decomp_size + LZO_OUTPUT_PADDING);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
120 if (!c->decomp_buf) {
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
121 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
122 return 0;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
123 }
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
124 rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
125 } else if (quality != c->quality)
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
126 rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
127 return 1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
128 }
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
129
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
130 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
6218
michael
parents: 5669
diff changeset
131 const uint8_t *buf, int buf_size) {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
132 NuvContext *c = avctx->priv_data;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
133 AVFrame *picture = data;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
134 int orig_size = buf_size;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
135 enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1',
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
136 NUV_RTJPEG_IN_LZO = '2', NUV_LZO = '3',
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
137 NUV_BLACK = 'N', NUV_COPY_LAST = 'L'} comptype;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
138
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
139 if (buf_size < 12) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
140 av_log(avctx, AV_LOG_ERROR, "coded frame too small\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
141 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
142 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
143
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
144 // codec data (rtjpeg quant tables)
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
145 if (buf[0] == 'D' && buf[1] == 'R') {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
146 int ret;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
147 // skip rest of the frameheader.
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
148 buf = &buf[12];
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
149 buf_size -= 12;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
150 ret = get_quant(avctx, c, buf, buf_size);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
151 if (ret < 0)
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
152 return ret;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
153 rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
154 return orig_size;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
155 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
156
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
157 if (buf[0] != 'V' || buf_size < 12) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
158 av_log(avctx, AV_LOG_ERROR, "not a nuv video frame\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
159 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
160 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
161 comptype = buf[1];
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
162 // skip rest of the frameheader.
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
163 buf = &buf[12];
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
164 buf_size -= 12;
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
165 if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) {
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
166 int outlen = c->decomp_size, inlen = buf_size;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
167 if (lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen))
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
168 av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
169 buf = c->decomp_buf;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
170 buf_size = c->decomp_size;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
171 }
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
172 if (c->codec_frameheader) {
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
173 int w, h, q;
5655
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
174 if (buf_size < 12) {
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
175 av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n");
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
176 return -1;
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
177 }
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
178 w = AV_RL16(&buf[6]);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
179 h = AV_RL16(&buf[8]);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
180 q = buf[10];
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
181 if (!codec_reinit(avctx, w, h, q))
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
182 return -1;
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
183 buf = &buf[12];
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
184 buf_size -= 12;
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
185 }
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
186
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
187 if (c->pic.data[0])
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
188 avctx->release_buffer(avctx, &c->pic);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
189 c->pic.reference = 1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
190 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE |
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
191 FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
192 if (avctx->get_buffer(avctx, &c->pic) < 0) {
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
193 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
194 return -1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
195 }
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
196
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
197 c->pic.pict_type = FF_I_TYPE;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
198 c->pic.key_frame = 1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
199 // decompress/copy/whatever data
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
200 switch (comptype) {
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
201 case NUV_LZO:
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
202 case NUV_UNCOMPRESSED: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
203 int height = c->height;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
204 if (buf_size < c->width * height * 3 / 2) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
205 av_log(avctx, AV_LOG_ERROR, "uncompressed frame too short\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
206 height = buf_size / c->width / 3 * 2;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
207 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
208 copy_frame(&c->pic, buf, c->width, height);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
209 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
210 }
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
211 case NUV_RTJPEG_IN_LZO:
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
212 case NUV_RTJPEG: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
213 rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
214 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
215 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
216 case NUV_BLACK: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
217 memset(c->pic.data[0], 0, c->width * c->height);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
218 memset(c->pic.data[1], 128, c->width * c->height / 4);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
219 memset(c->pic.data[2], 128, c->width * c->height / 4);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
220 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
221 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
222 case NUV_COPY_LAST: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
223 c->pic.pict_type = FF_P_TYPE;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
224 c->pic.key_frame = 0;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
225 /* nothing more to do here */
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
226 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
227 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
228 default:
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
229 av_log(avctx, AV_LOG_ERROR, "unknown compression\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
230 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
231 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
232
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
233 *picture = c->pic;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
234 *data_size = sizeof(AVFrame);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
235 return orig_size;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
236 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
237
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6243
diff changeset
238 static av_cold int decode_init(AVCodecContext *avctx) {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
239 NuvContext *c = avctx->priv_data;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
240 avctx->pix_fmt = PIX_FMT_YUV420P;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
241 c->pic.data[0] = NULL;
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
242 c->decomp_buf = NULL;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
243 c->quality = -1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
244 c->width = 0;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
245 c->height = 0;
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
246 c->codec_frameheader = avctx->codec_tag == MKTAG('R', 'J', 'P', 'G');
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
247 if (avctx->extradata_size)
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
248 get_quant(avctx, c, avctx->extradata, avctx->extradata_size);
5669
d540c7d88344 dsputil must be initialized before calling rtjpeg init.
reimar
parents: 5658
diff changeset
249 dsputil_init(&c->dsp, avctx);
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
250 if (!codec_reinit(avctx, avctx->width, avctx->height, -1))
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
251 return 1;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
252 return 0;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
253 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
254
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6243
diff changeset
255 static av_cold int decode_end(AVCodecContext *avctx) {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
256 NuvContext *c = avctx->priv_data;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
257 av_freep(&c->decomp_buf);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
258 if (c->pic.data[0])
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
259 avctx->release_buffer(avctx, &c->pic);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
260 return 0;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
261 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
262
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
263 AVCodec nuv_decoder = {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
264 "nuv",
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
265 CODEC_TYPE_VIDEO,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
266 CODEC_ID_NUV,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
267 sizeof(NuvContext),
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
268 decode_init,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
269 NULL,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
270 decode_end,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
271 decode_frame,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
272 CODEC_CAP_DR1,
6710
a4104482ceef Add long names to many AVCodec declarations.
diego
parents: 6517
diff changeset
273 .long_name = "NuppelVideo",
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
274 };
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
275