annotate nuv.c @ 8520:a0164882aa38 libavcodec

Generic metadata API. avi is updated as example. No version bump, the API still might change slightly ... No update to ffmpeg.c as requested by aurel.
author michael
date Sun, 04 Jan 2009 18:48:37 +0000
parents c4f105f7c886
children 967c0a1a60a0
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"
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
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
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
michael
parents: 6218
diff changeset
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
michael
parents: 6218
diff changeset
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
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 3947
diff changeset
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
05e932ddaaa9 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 3947
diff changeset
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
ec46684cc8ad Make sure rtjpeg quality is a valid value
reimar
parents: 5656
diff changeset
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
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
107 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
108 NuvContext *c = avctx->priv_data;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
109 width = (width + 1) & ~1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
110 height = (height + 1) & ~1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
111 if (quality >= 0)
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
112 get_quant_quality(c, quality);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
113 if (width != c->width || height != c->height) {
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
114 if (avcodec_check_dimensions(avctx, height, width) < 0)
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
115 return 0;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
116 avctx->width = c->width = width;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
117 avctx->height = c->height = height;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
118 c->decomp_size = c->height * c->width * 3 / 2;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
119 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
120 if (!c->decomp_buf) {
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
121 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
122 return 0;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
123 }
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
124 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
125 } else if (quality != c->quality)
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
126 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
127 return 1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
128 }
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
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
michael
parents: 5669
diff changeset
131 const uint8_t *buf, int buf_size) {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
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
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
176 if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) {
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
177 int outlen = c->decomp_size, inlen = buf_size;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
178 if (lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen))
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
179 av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
180 buf = c->decomp_buf;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
181 buf_size = c->decomp_size;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
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
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
184 int w, h, q;
5655
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
185 if (buf_size < 12) {
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
186 av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n");
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
187 return -1;
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
188 }
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
189 w = AV_RL16(&buf[6]);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
190 h = AV_RL16(&buf[8]);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
191 q = buf[10];
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
192 if (!codec_reinit(avctx, w, h, q))
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
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
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
199 avctx->release_buffer(avctx, &c->pic);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
200 c->pic.reference = 1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
201 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
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
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
205 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
206 return -1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
207 }
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
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
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
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
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
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
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
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
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
252 c->decomp_buf = NULL;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
253 c->quality = -1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
254 c->width = 0;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
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
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
260 if (!codec_reinit(avctx, avctx->width, avctx->height, -1))
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
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
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
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