Mercurial > libavcodec.hg
comparison nuv.c @ 5654:93a54fcfa2f4 libavcodec
First ugly and slow attempt to fix nuv files with extra frameheader
and per-frame rtjpeg quality
author | reimar |
---|---|
date | Sun, 09 Sep 2007 08:42:49 +0000 |
parents | 1b0c60bfae2a |
children | 711922c1e9e7 |
comparison
equal
deleted
inserted
replaced
5653:1b0c60bfae2a | 5654:93a54fcfa2f4 |
---|---|
28 #include "lzo.h" | 28 #include "lzo.h" |
29 #include "rtjpeg.h" | 29 #include "rtjpeg.h" |
30 | 30 |
31 typedef struct { | 31 typedef struct { |
32 AVFrame pic; | 32 AVFrame pic; |
33 int codec_frameheader; | |
33 int width, height; | 34 int width, height; |
34 unsigned int decomp_size; | 35 unsigned int decomp_size; |
35 unsigned char* decomp_buf; | 36 unsigned char* decomp_buf; |
36 uint32_t lq[64], cq[64]; | 37 uint32_t lq[64], cq[64]; |
37 RTJpegContext rtj; | 38 RTJpegContext rtj; |
38 DSPContext dsp; | 39 DSPContext dsp; |
39 } NuvContext; | 40 } NuvContext; |
40 | 41 |
42 static const uint8_t fallback_lquant[] = { | |
43 16, 11, 10, 16, 24, 40, 51, 61, | |
44 12, 12, 14, 19, 26, 58, 60, 55, | |
45 14, 13, 16, 24, 40, 57, 69, 56, | |
46 14, 17, 22, 29, 51, 87, 80, 62, | |
47 18, 22, 37, 56, 68, 109, 103, 77, | |
48 24, 35, 55, 64, 81, 104, 113, 92, | |
49 49, 64, 78, 87, 103, 121, 120, 101, | |
50 72, 92, 95, 98, 112, 100, 103, 99 | |
51 }; | |
52 | |
53 static const uint8_t fallback_cquant[] = { | |
54 17, 18, 24, 47, 99, 99, 99, 99, | |
55 18, 21, 26, 66, 99, 99, 99, 99, | |
56 24, 26, 56, 99, 99, 99, 99, 99, | |
57 47, 66, 99, 99, 99, 99, 99, 99, | |
58 99, 99, 99, 99, 99, 99, 99, 99, | |
59 99, 99, 99, 99, 99, 99, 99, 99, | |
60 99, 99, 99, 99, 99, 99, 99, 99, | |
61 99, 99, 99, 99, 99, 99, 99, 99 | |
62 }; | |
63 | |
41 /** | 64 /** |
42 * \brief copy frame data from buffer to AVFrame, handling stride. | 65 * \brief copy frame data from buffer to AVFrame, handling stride. |
43 * \param f destination AVFrame | 66 * \param f destination AVFrame |
44 * \param src source buffer, does not use any line-stride | 67 * \param src source buffer, does not use any line-stride |
45 * \param width width of the video frame | 68 * \param width width of the video frame |
65 for (i = 0; i < 64; i++, buf += 4) | 88 for (i = 0; i < 64; i++, buf += 4) |
66 c->lq[i] = AV_RL32(buf); | 89 c->lq[i] = AV_RL32(buf); |
67 for (i = 0; i < 64; i++, buf += 4) | 90 for (i = 0; i < 64; i++, buf += 4) |
68 c->cq[i] = AV_RL32(buf); | 91 c->cq[i] = AV_RL32(buf); |
69 return 0; | 92 return 0; |
93 } | |
94 | |
95 /** | |
96 * \brief set quantization tables from a quality value | |
97 */ | |
98 static void get_quant_quality(NuvContext *c, int quality) { | |
99 int i; | |
100 for (i = 0; i < 64; i++) { | |
101 c->lq[i] = (fallback_lquant[i] << 7) / quality; | |
102 c->cq[i] = (fallback_cquant[i] << 7) / quality; | |
103 } | |
70 } | 104 } |
71 | 105 |
72 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, | 106 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, |
73 uint8_t *buf, int buf_size) { | 107 uint8_t *buf, int buf_size) { |
74 NuvContext *c = avctx->priv_data; | 108 NuvContext *c = avctx->priv_data; |
118 int outlen = c->decomp_size, inlen = buf_size; | 152 int outlen = c->decomp_size, inlen = buf_size; |
119 if (lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) | 153 if (lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) |
120 av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); | 154 av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); |
121 buf = c->decomp_buf; | 155 buf = c->decomp_buf; |
122 buf_size = c->decomp_size; | 156 buf_size = c->decomp_size; |
157 } | |
158 if (c->codec_frameheader) { | |
159 get_quant_quality(c, buf[10]); | |
160 rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); | |
161 buf = &buf[12]; | |
162 buf_size -= 12; | |
123 } | 163 } |
124 | 164 |
125 c->pic.pict_type = FF_I_TYPE; | 165 c->pic.pict_type = FF_I_TYPE; |
126 c->pic.key_frame = 1; | 166 c->pic.key_frame = 1; |
127 // decompress/copy/whatever data | 167 // decompress/copy/whatever data |
170 if (avcodec_check_dimensions(avctx, avctx->height, avctx->width) < 0) { | 210 if (avcodec_check_dimensions(avctx, avctx->height, avctx->width) < 0) { |
171 return 1; | 211 return 1; |
172 } | 212 } |
173 avctx->pix_fmt = PIX_FMT_YUV420P; | 213 avctx->pix_fmt = PIX_FMT_YUV420P; |
174 c->pic.data[0] = NULL; | 214 c->pic.data[0] = NULL; |
215 c->codec_frameheader = avctx->codec_tag == MKTAG('R', 'J', 'P', 'G'); | |
175 c->width = avctx->width; | 216 c->width = avctx->width; |
176 c->height = avctx->height; | 217 c->height = avctx->height; |
177 c->decomp_size = c->height * c->width * 3 / 2; | 218 c->decomp_size = c->height * c->width * 3 / 2; |
178 c->decomp_buf = av_malloc(c->decomp_size + LZO_OUTPUT_PADDING); | 219 c->decomp_buf = av_malloc(c->decomp_size + LZO_OUTPUT_PADDING); |
179 if (!c->decomp_buf) { | 220 if (!c->decomp_buf) { |