Mercurial > libavcodec.hg
annotate nuv.c @ 8991:ca768cb2bfb6 libavcodec
Use last decoded SPS as current SPS in order to parse picture timing SEI
correctly. This works around an apparent H.264 standard deficiency.
Patch by Ivan Schreter, schreter gmx net
author | cehoyos |
---|---|
date | Fri, 20 Feb 2009 16:20:01 +0000 |
parents | 967c0a1a60a0 |
children | bf274494b66e |
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; | |
8732
967c0a1a60a0
Add av_ prefix to LZO stuff and thus make it officially part of the public API.
reimar
parents:
7799
diff
changeset
|
119 c->decomp_buf = av_realloc(c->decomp_buf, c->decomp_size + AV_LZO_OUTPUT_PADDING); |
5658 | 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; |
7799
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
135 int keyframe; |
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
136 int result; |
3224
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
137 enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1', |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
138 NUV_RTJPEG_IN_LZO = '2', NUV_LZO = '3', |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
139 NUV_BLACK = 'N', NUV_COPY_LAST = 'L'} comptype; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
140 |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
141 if (buf_size < 12) { |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
142 av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
143 return -1; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
144 } |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
145 |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
146 // codec data (rtjpeg quant tables) |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
147 if (buf[0] == 'D' && buf[1] == 'R') { |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
148 int ret; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
149 // skip rest of the frameheader. |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
150 buf = &buf[12]; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
151 buf_size -= 12; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
152 ret = get_quant(avctx, c, buf, buf_size); |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
153 if (ret < 0) |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
154 return ret; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
155 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
|
156 return orig_size; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
157 } |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
158 |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
159 if (buf[0] != 'V' || buf_size < 12) { |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
160 av_log(avctx, AV_LOG_ERROR, "not a nuv video frame\n"); |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
161 return -1; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
162 } |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
163 comptype = buf[1]; |
7799
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
164 switch (comptype) { |
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
165 case NUV_RTJPEG_IN_LZO: |
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
166 case NUV_RTJPEG: |
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
167 keyframe = !buf[2]; break; |
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
168 case NUV_COPY_LAST: |
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
169 keyframe = 0; break; |
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
170 default: |
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
171 keyframe = 1; break; |
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
172 } |
3224
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
173 // skip rest of the frameheader. |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
174 buf = &buf[12]; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
175 buf_size -= 12; |
5653 | 176 if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) { |
177 int outlen = c->decomp_size, inlen = buf_size; | |
8732
967c0a1a60a0
Add av_ prefix to LZO stuff and thus make it officially part of the public API.
reimar
parents:
7799
diff
changeset
|
178 if (av_lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) |
5653 | 179 av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); |
180 buf = c->decomp_buf; | |
181 buf_size = c->decomp_size; | |
182 } | |
5654
93a54fcfa2f4
First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents:
5653
diff
changeset
|
183 if (c->codec_frameheader) { |
5658 | 184 int w, h, q; |
5655 | 185 if (buf_size < 12) { |
186 av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n"); | |
187 return -1; | |
188 } | |
5658 | 189 w = AV_RL16(&buf[6]); |
190 h = AV_RL16(&buf[8]); | |
191 q = buf[10]; | |
192 if (!codec_reinit(avctx, w, h, q)) | |
193 return -1; | |
5654
93a54fcfa2f4
First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents:
5653
diff
changeset
|
194 buf = &buf[12]; |
93a54fcfa2f4
First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents:
5653
diff
changeset
|
195 buf_size -= 12; |
93a54fcfa2f4
First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents:
5653
diff
changeset
|
196 } |
3224
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
197 |
7799
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
198 if (keyframe && c->pic.data[0]) |
5658 | 199 avctx->release_buffer(avctx, &c->pic); |
200 c->pic.reference = 1; | |
201 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | | |
202 FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; | |
7799
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
203 result = keyframe ? avctx->get_buffer(avctx, &c->pic) : avctx->reget_buffer(avctx, &c->pic); |
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
204 if (result < 0) { |
5658 | 205 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
206 return -1; | |
207 } | |
208 | |
7799
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
209 c->pic.pict_type = keyframe ? FF_I_TYPE : FF_P_TYPE; |
c4f105f7c886
Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents:
7040
diff
changeset
|
210 c->pic.key_frame = keyframe; |
3224
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
211 // decompress/copy/whatever data |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
212 switch (comptype) { |
5653 | 213 case NUV_LZO: |
3224
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
214 case NUV_UNCOMPRESSED: { |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
215 int height = c->height; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
216 if (buf_size < c->width * height * 3 / 2) { |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
217 av_log(avctx, AV_LOG_ERROR, "uncompressed frame too short\n"); |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
218 height = buf_size / c->width / 3 * 2; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
219 } |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
220 copy_frame(&c->pic, buf, c->width, height); |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
221 break; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
222 } |
5653 | 223 case NUV_RTJPEG_IN_LZO: |
3224
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
224 case NUV_RTJPEG: { |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
225 rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size); |
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 case NUV_BLACK: { |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
229 memset(c->pic.data[0], 0, c->width * c->height); |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
230 memset(c->pic.data[1], 128, c->width * c->height / 4); |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
231 memset(c->pic.data[2], 128, c->width * c->height / 4); |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
232 break; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
233 } |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
234 case NUV_COPY_LAST: { |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
235 /* nothing more to do here */ |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
236 break; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
237 } |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
238 default: |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
239 av_log(avctx, AV_LOG_ERROR, "unknown compression\n"); |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
240 return -1; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
241 } |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
242 |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
243 *picture = c->pic; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
244 *data_size = sizeof(AVFrame); |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
245 return orig_size; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
246 } |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
247 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6243
diff
changeset
|
248 static av_cold int decode_init(AVCodecContext *avctx) { |
4827 | 249 NuvContext *c = avctx->priv_data; |
3224
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
250 avctx->pix_fmt = PIX_FMT_YUV420P; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
251 c->pic.data[0] = NULL; |
5658 | 252 c->decomp_buf = NULL; |
253 c->quality = -1; | |
254 c->width = 0; | |
255 c->height = 0; | |
5654
93a54fcfa2f4
First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents:
5653
diff
changeset
|
256 c->codec_frameheader = avctx->codec_tag == MKTAG('R', 'J', 'P', 'G'); |
3224
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
257 if (avctx->extradata_size) |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
258 get_quant(avctx, c, avctx->extradata, avctx->extradata_size); |
5669
d540c7d88344
dsputil must be initialized before calling rtjpeg init.
reimar
parents:
5658
diff
changeset
|
259 dsputil_init(&c->dsp, avctx); |
5658 | 260 if (!codec_reinit(avctx, avctx->width, avctx->height, -1)) |
261 return 1; | |
3224
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
262 return 0; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
263 } |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
264 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6243
diff
changeset
|
265 static av_cold int decode_end(AVCodecContext *avctx) { |
4827 | 266 NuvContext *c = avctx->priv_data; |
3224
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
267 av_freep(&c->decomp_buf); |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
268 if (c->pic.data[0]) |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
269 avctx->release_buffer(avctx, &c->pic); |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
270 return 0; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
271 } |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
272 |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
273 AVCodec nuv_decoder = { |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
274 "nuv", |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
275 CODEC_TYPE_VIDEO, |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
276 CODEC_ID_NUV, |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
277 sizeof(NuvContext), |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
278 decode_init, |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
279 NULL, |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
280 decode_end, |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
281 decode_frame, |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
282 CODEC_CAP_DR1, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6763
diff
changeset
|
283 .long_name = NULL_IF_CONFIG_SMALL("NuppelVideo"), |
3224
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
284 }; |
28aaf0a0135e
NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff
changeset
|
285 |