Mercurial > libavcodec.hg
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 |
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 | 24 #include "libavutil/bswap.h" |
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 | 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 | 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 | 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 | 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 | 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 | 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 | 107 static int codec_reinit(AVCodecContext *avctx, int width, int height, int quality) { |
108 NuvContext *c = avctx->priv_data; | |
109 width = (width + 1) & ~1; | |
110 height = (height + 1) & ~1; | |
111 if (quality >= 0) | |
112 get_quant_quality(c, quality); | |
113 if (width != c->width || height != c->height) { | |
114 if (avcodec_check_dimensions(avctx, height, width) < 0) | |
115 return 0; | |
116 avctx->width = c->width = width; | |
117 avctx->height = c->height = height; | |
118 c->decomp_size = c->height * c->width * 3 / 2; | |
119 c->decomp_buf = av_realloc(c->decomp_buf, c->decomp_size + LZO_OUTPUT_PADDING); | |
120 if (!c->decomp_buf) { | |
121 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); | |
122 return 0; | |
123 } | |
124 rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); | |
125 } else if (quality != c->quality) | |
126 rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); | |
127 return 1; | |
128 } | |
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 | 131 const uint8_t *buf, int buf_size) { |
4827 | 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 | 165 if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) { |
166 int outlen = c->decomp_size, inlen = buf_size; | |
167 if (lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) | |
168 av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); | |
169 buf = c->decomp_buf; | |
170 buf_size = c->decomp_size; | |
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 | 173 int w, h, q; |
5655 | 174 if (buf_size < 12) { |
175 av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n"); | |
176 return -1; | |
177 } | |
5658 | 178 w = AV_RL16(&buf[6]); |
179 h = AV_RL16(&buf[8]); | |
180 q = buf[10]; | |
181 if (!codec_reinit(avctx, w, h, q)) | |
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 | 187 if (c->pic.data[0]) |
188 avctx->release_buffer(avctx, &c->pic); | |
189 c->pic.reference = 1; | |
190 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | | |
191 FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; | |
192 if (avctx->get_buffer(avctx, &c->pic) < 0) { | |
193 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
194 return -1; | |
195 } | |
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 | 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 | 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 | 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 | 242 c->decomp_buf = NULL; |
243 c->quality = -1; | |
244 c->width = 0; | |
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 | 250 if (!codec_reinit(avctx, avctx->width, avctx->height, -1)) |
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 | 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 | 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 |