annotate nuv.c @ 5757:ace63c809071 libavcodec

Remove uses of SIGILL for CPU extension detection, that method is not acceptable in a library. Should not change anything for PPC, the autodetection is currently pointless due to other code being compiled with -maltivec as well (and detection for OSX and AmigaOS remains in place). SPARC binaries built with VIS support can now only run on systems with VIS.
author reimar
date Tue, 02 Oct 2007 18:18:35 +0000
parents d540c7d88344
children dfdff1ca78a7
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
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
24 #include "avcodec.h"
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
25
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
26 #include "bswap.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 "lzo.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 */
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
72 static void copy_frame(AVFrame *f, uint8_t *src,
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,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
83 uint8_t *buf, int size) {
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) {
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
115 if (avcodec_check_dimensions(avctx, height, width) < 0)
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;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
120 c->decomp_buf = av_realloc(c->decomp_buf, c->decomp_size + LZO_OUTPUT_PADDING);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
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,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
132 uint8_t *buf, int buf_size) {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
133 NuvContext *c = avctx->priv_data;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
134 AVFrame *picture = data;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
135 int orig_size = buf_size;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
136 enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1',
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
137 NUV_RTJPEG_IN_LZO = '2', NUV_LZO = '3',
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
138 NUV_BLACK = 'N', NUV_COPY_LAST = 'L'} comptype;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
139
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
140 if (buf_size < 12) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
141 av_log(avctx, AV_LOG_ERROR, "coded frame too small\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
142 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
143 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
144
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
145 // codec data (rtjpeg quant tables)
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
146 if (buf[0] == 'D' && buf[1] == 'R') {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
147 int ret;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
148 // skip rest of the frameheader.
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
149 buf = &buf[12];
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
150 buf_size -= 12;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
151 ret = get_quant(avctx, c, buf, buf_size);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
152 if (ret < 0)
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
153 return ret;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
154 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
155 return orig_size;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
156 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
157
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
158 if (buf[0] != 'V' || buf_size < 12) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
159 av_log(avctx, AV_LOG_ERROR, "not a nuv video frame\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
160 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
161 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
162 comptype = buf[1];
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
163 // skip rest of the frameheader.
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
164 buf = &buf[12];
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
165 buf_size -= 12;
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
166 if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) {
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
167 int outlen = c->decomp_size, inlen = buf_size;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
168 if (lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen))
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
169 av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
170 buf = c->decomp_buf;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
171 buf_size = c->decomp_size;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
172 }
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
173 if (c->codec_frameheader) {
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
174 int w, h, q;
5655
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
175 if (buf_size < 12) {
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
176 av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n");
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
177 return -1;
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
178 }
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
179 w = AV_RL16(&buf[6]);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
180 h = AV_RL16(&buf[8]);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
181 q = buf[10];
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
182 if (!codec_reinit(avctx, w, h, q))
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
183 return -1;
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
184 buf = &buf[12];
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
185 buf_size -= 12;
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
186 }
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
187
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
188 if (c->pic.data[0])
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
189 avctx->release_buffer(avctx, &c->pic);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
190 c->pic.reference = 1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
191 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
192 FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
193 if (avctx->get_buffer(avctx, &c->pic) < 0) {
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
194 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
195 return -1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
196 }
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
197
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
198 c->pic.pict_type = FF_I_TYPE;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
199 c->pic.key_frame = 1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
200 // decompress/copy/whatever data
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
201 switch (comptype) {
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
202 case NUV_LZO:
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
203 case NUV_UNCOMPRESSED: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
204 int height = c->height;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
205 if (buf_size < c->width * height * 3 / 2) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
206 av_log(avctx, AV_LOG_ERROR, "uncompressed frame too short\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
207 height = buf_size / c->width / 3 * 2;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
208 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
209 copy_frame(&c->pic, buf, c->width, height);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
210 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
211 }
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
212 case NUV_RTJPEG_IN_LZO:
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
213 case NUV_RTJPEG: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
214 rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
215 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
216 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
217 case NUV_BLACK: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
218 memset(c->pic.data[0], 0, c->width * c->height);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
219 memset(c->pic.data[1], 128, c->width * c->height / 4);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
220 memset(c->pic.data[2], 128, c->width * c->height / 4);
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 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
223 case NUV_COPY_LAST: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
224 c->pic.pict_type = FF_P_TYPE;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
225 c->pic.key_frame = 0;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
226 /* nothing more to do here */
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
227 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
228 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
229 default:
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
230 av_log(avctx, AV_LOG_ERROR, "unknown compression\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
231 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
232 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
233
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
234 *picture = c->pic;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
235 *data_size = sizeof(AVFrame);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
236 return orig_size;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
237 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
238
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
239 static int decode_init(AVCodecContext *avctx) {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
240 NuvContext *c = avctx->priv_data;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
241 avctx->pix_fmt = PIX_FMT_YUV420P;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
242 c->pic.data[0] = NULL;
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
243 c->decomp_buf = NULL;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
244 c->quality = -1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
245 c->width = 0;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
246 c->height = 0;
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
247 c->codec_frameheader = avctx->codec_tag == MKTAG('R', 'J', 'P', 'G');
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
248 if (avctx->extradata_size)
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
249 get_quant(avctx, c, avctx->extradata, avctx->extradata_size);
5669
d540c7d88344 dsputil must be initialized before calling rtjpeg init.
reimar
parents: 5658
diff changeset
250 dsputil_init(&c->dsp, avctx);
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
251 if (!codec_reinit(avctx, avctx->width, avctx->height, -1))
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
252 return 1;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
253 return 0;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
254 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
255
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
256 static int decode_end(AVCodecContext *avctx) {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
257 NuvContext *c = avctx->priv_data;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
258 av_freep(&c->decomp_buf);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
259 if (c->pic.data[0])
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
260 avctx->release_buffer(avctx, &c->pic);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
261 return 0;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
262 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
263
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
264 AVCodec nuv_decoder = {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
265 "nuv",
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
266 CODEC_TYPE_VIDEO,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
267 CODEC_ID_NUV,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
268 sizeof(NuvContext),
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
269 decode_init,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
270 NULL,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
271 decode_end,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
272 decode_frame,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
273 CODEC_CAP_DR1,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
274 };
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
275