annotate nuv.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents ffb3668ff7af
children
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"
12372
914f484bb476 Remove use of the deprecated function avcodec_check_dimensions(), use
stefano
parents: 11560
diff changeset
26 #include "libavcore/imgutils.h"
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
27 #include "avcodec.h"
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
28 #include "dsputil.h"
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
29 #include "rtjpeg.h"
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
30
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
31 typedef struct {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
32 AVFrame pic;
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
33 int codec_frameheader;
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
34 int quality;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
35 int width, height;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
36 unsigned int decomp_size;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
37 unsigned char* decomp_buf;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
38 uint32_t lq[64], cq[64];
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
39 RTJpegContext rtj;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
40 DSPContext dsp;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
41 } NuvContext;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
42
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
43 static const uint8_t fallback_lquant[] = {
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
44 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
45 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
46 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
47 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
48 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
49 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
50 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
51 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
52 };
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
53
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
54 static const uint8_t fallback_cquant[] = {
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
55 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
56 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
57 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
58 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
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 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
63 };
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
64
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
65 /**
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
66 * \brief copy frame data from buffer to AVFrame, handling stride.
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
67 * \param f destination AVFrame
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
68 * \param src source buffer, does not use any line-stride
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
69 * \param width width of the video frame
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
70 * \param height height of the video frame
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
71 */
6243
michael
parents: 6218
diff changeset
72 static void copy_frame(AVFrame *f, const uint8_t *src,
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
73 int width, int height) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
74 AVPicture pic;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
75 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
76 av_picture_copy((AVPicture *)f, &pic, PIX_FMT_YUV420P, width, height);
3224
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 /**
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
80 * \brief extract quantization tables from codec data into our context
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
81 */
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
82 static int get_quant(AVCodecContext *avctx, NuvContext *c,
6243
michael
parents: 6218
diff changeset
83 const uint8_t *buf, int size) {
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
84 int i;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
85 if (size < 2 * 64 * 4) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
86 av_log(avctx, AV_LOG_ERROR, "insufficient rtjpeg quant data\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
87 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
88 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
89 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
90 c->lq[i] = AV_RL32(buf);
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
91 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
92 c->cq[i] = AV_RL32(buf);
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
93 return 0;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
94 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
95
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
96 /**
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
97 * \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
98 */
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
99 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
100 int i;
5657
ec46684cc8ad Make sure rtjpeg quality is a valid value
reimar
parents: 5656
diff changeset
101 quality = FFMAX(quality, 1);
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
102 for (i = 0; i < 64; i++) {
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
103 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
104 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
105 }
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
106 }
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
107
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
108 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
109 NuvContext *c = avctx->priv_data;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
110 width = (width + 1) & ~1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
111 height = (height + 1) & ~1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
112 if (quality >= 0)
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
113 get_quant_quality(c, quality);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
114 if (width != c->width || height != c->height) {
12462
ffb3668ff7af Use new imgutils.h API names, fix deprecation warnings.
stefano
parents: 12372
diff changeset
115 if (av_image_check_size(height, width, 0, avctx) < 0)
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
116 return 0;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
117 avctx->width = c->width = width;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
118 avctx->height = c->height = height;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
119 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
120 c->decomp_buf = av_realloc(c->decomp_buf, c->decomp_size + AV_LZO_OUTPUT_PADDING);
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
121 if (!c->decomp_buf) {
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
122 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
123 return 0;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
124 }
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
125 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
126 } else if (quality != c->quality)
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
127 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
128 return 1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
129 }
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
130
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
131 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9126
diff changeset
132 AVPacket *avpkt) {
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9126
diff changeset
133 const uint8_t *buf = avpkt->data;
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9126
diff changeset
134 int buf_size = avpkt->size;
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
135 NuvContext *c = avctx->priv_data;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
136 AVFrame *picture = data;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
137 int orig_size = buf_size;
7799
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
138 int keyframe;
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
139 int result;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
140 enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1',
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
141 NUV_RTJPEG_IN_LZO = '2', NUV_LZO = '3',
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
142 NUV_BLACK = 'N', NUV_COPY_LAST = 'L'} comptype;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
143
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
144 if (buf_size < 12) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
145 av_log(avctx, AV_LOG_ERROR, "coded frame too small\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
146 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
147 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
148
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
149 // codec data (rtjpeg quant tables)
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
150 if (buf[0] == 'D' && buf[1] == 'R') {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
151 int ret;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
152 // skip rest of the frameheader.
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
153 buf = &buf[12];
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
154 buf_size -= 12;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
155 ret = get_quant(avctx, c, buf, buf_size);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
156 if (ret < 0)
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
157 return ret;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
158 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
159 return orig_size;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
160 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
161
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
162 if (buf[0] != 'V' || buf_size < 12) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
163 av_log(avctx, AV_LOG_ERROR, "not a nuv video frame\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
164 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
165 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
166 comptype = buf[1];
7799
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
167 switch (comptype) {
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
168 case NUV_RTJPEG_IN_LZO:
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
169 case NUV_RTJPEG:
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
170 keyframe = !buf[2]; break;
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
171 case NUV_COPY_LAST:
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
172 keyframe = 0; break;
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
173 default:
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
174 keyframe = 1; break;
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
175 }
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
176 // skip rest of the frameheader.
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
177 buf = &buf[12];
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
178 buf_size -= 12;
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
179 if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) {
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
180 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
181 if (av_lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen))
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
182 av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
183 buf = c->decomp_buf;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
184 buf_size = c->decomp_size;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
185 }
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
186 if (c->codec_frameheader) {
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
187 int w, h, q;
5655
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
188 if (buf_size < 12) {
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
189 av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n");
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
190 return -1;
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
191 }
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
192 w = AV_RL16(&buf[6]);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
193 h = AV_RL16(&buf[8]);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
194 q = buf[10];
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
195 if (!codec_reinit(avctx, w, h, q))
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
196 return -1;
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
197 buf = &buf[12];
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
198 buf_size -= 12;
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
199 }
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
200
7799
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
201 if (keyframe && c->pic.data[0])
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
202 avctx->release_buffer(avctx, &c->pic);
9126
851ff1a23191 Set AVFrame.reference correctly for nuv decoder.
reimar
parents: 9083
diff changeset
203 c->pic.reference = 3;
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
204 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
205 FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
10154
8f578f86c51a Simplify: reget_buffer behaves exactly like get_buffer if the buffer was
reimar
parents: 9355
diff changeset
206 result = avctx->reget_buffer(avctx, &c->pic);
7799
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
207 if (result < 0) {
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
208 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
209 return -1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
210 }
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
211
7799
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
212 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
213 c->pic.key_frame = keyframe;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
214 // decompress/copy/whatever data
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
215 switch (comptype) {
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
216 case NUV_LZO:
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
217 case NUV_UNCOMPRESSED: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
218 int height = c->height;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
219 if (buf_size < c->width * height * 3 / 2) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
220 av_log(avctx, AV_LOG_ERROR, "uncompressed frame too short\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
221 height = buf_size / c->width / 3 * 2;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
222 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
223 copy_frame(&c->pic, buf, c->width, height);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
224 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
225 }
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
226 case NUV_RTJPEG_IN_LZO:
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
227 case NUV_RTJPEG: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
228 rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
229 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
230 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
231 case NUV_BLACK: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
232 memset(c->pic.data[0], 0, c->width * c->height);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
233 memset(c->pic.data[1], 128, c->width * c->height / 4);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
234 memset(c->pic.data[2], 128, c->width * c->height / 4);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
235 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
236 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
237 case NUV_COPY_LAST: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
238 /* nothing more to do here */
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
239 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
240 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
241 default:
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
242 av_log(avctx, AV_LOG_ERROR, "unknown compression\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
243 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
244 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
245
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
246 *picture = c->pic;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
247 *data_size = sizeof(AVFrame);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
248 return orig_size;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
249 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
250
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6243
diff changeset
251 static av_cold int decode_init(AVCodecContext *avctx) {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
252 NuvContext *c = avctx->priv_data;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
253 avctx->pix_fmt = PIX_FMT_YUV420P;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
254 c->pic.data[0] = NULL;
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
255 c->decomp_buf = NULL;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
256 c->quality = -1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
257 c->width = 0;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
258 c->height = 0;
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
259 c->codec_frameheader = avctx->codec_tag == MKTAG('R', 'J', 'P', 'G');
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
260 if (avctx->extradata_size)
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
261 get_quant(avctx, c, avctx->extradata, avctx->extradata_size);
5669
d540c7d88344 dsputil must be initialized before calling rtjpeg init.
reimar
parents: 5658
diff changeset
262 dsputil_init(&c->dsp, avctx);
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
263 if (!codec_reinit(avctx, avctx->width, avctx->height, -1))
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
264 return 1;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
265 return 0;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
266 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
267
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6243
diff changeset
268 static av_cold int decode_end(AVCodecContext *avctx) {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
269 NuvContext *c = avctx->priv_data;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
270 av_freep(&c->decomp_buf);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
271 if (c->pic.data[0])
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
272 avctx->release_buffer(avctx, &c->pic);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
273 return 0;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
274 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
275
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
276 AVCodec nuv_decoder = {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
277 "nuv",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 10154
diff changeset
278 AVMEDIA_TYPE_VIDEO,
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
279 CODEC_ID_NUV,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
280 sizeof(NuvContext),
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
281 decode_init,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
282 NULL,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
283 decode_end,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
284 decode_frame,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
285 CODEC_CAP_DR1,
9083
bf274494b66e Change a bunch of codec long_names to be more consistent and descriptive.
diego
parents: 8732
diff changeset
286 .long_name = NULL_IF_CONFIG_SMALL("NuppelVideo/RTJPEG"),
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
287 };
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
288