annotate nuv.c @ 11034:fd5921186064 libavcodec

Make the fast loop filter path work with unavailable left MBs. This prevents the issue with having to switch between slow and fast code paths in each row. 0.5% faster loopfilter for cathedral
author michael
date Thu, 28 Jan 2010 02:15:25 +0000
parents 8f578f86c51a
children 8a4984c5cacc
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;
8732
967c0a1a60a0 Add av_ prefix to LZO stuff and thus make it officially part of the public API.
reimar
parents: 7799
diff changeset
119 c->decomp_buf = av_realloc(c->decomp_buf, c->decomp_size + AV_LZO_OUTPUT_PADDING);
5658
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,
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9126
diff changeset
131 AVPacket *avpkt) {
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9126
diff changeset
132 const uint8_t *buf = avpkt->data;
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9126
diff changeset
133 int buf_size = avpkt->size;
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
134 NuvContext *c = avctx->priv_data;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
135 AVFrame *picture = data;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
136 int orig_size = buf_size;
7799
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
137 int keyframe;
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
138 int result;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
139 enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1',
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
140 NUV_RTJPEG_IN_LZO = '2', NUV_LZO = '3',
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
141 NUV_BLACK = 'N', NUV_COPY_LAST = 'L'} comptype;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
142
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
143 if (buf_size < 12) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
144 av_log(avctx, AV_LOG_ERROR, "coded frame too small\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
145 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
146 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
147
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
148 // codec data (rtjpeg quant tables)
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
149 if (buf[0] == 'D' && buf[1] == 'R') {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
150 int ret;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
151 // skip rest of the frameheader.
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
152 buf = &buf[12];
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
153 buf_size -= 12;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
154 ret = get_quant(avctx, c, buf, buf_size);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
155 if (ret < 0)
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
156 return ret;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
157 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
158 return orig_size;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
159 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
160
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
161 if (buf[0] != 'V' || buf_size < 12) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
162 av_log(avctx, AV_LOG_ERROR, "not a nuv video frame\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
163 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
164 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
165 comptype = buf[1];
7799
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
166 switch (comptype) {
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
167 case NUV_RTJPEG_IN_LZO:
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
168 case NUV_RTJPEG:
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
169 keyframe = !buf[2]; break;
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
170 case NUV_COPY_LAST:
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
171 keyframe = 0; break;
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
172 default:
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
173 keyframe = 1; break;
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
174 }
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
175 // skip rest of the frameheader.
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
176 buf = &buf[12];
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
177 buf_size -= 12;
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
178 if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) {
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
179 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
180 if (av_lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen))
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
181 av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
182 buf = c->decomp_buf;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
183 buf_size = c->decomp_size;
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
184 }
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
185 if (c->codec_frameheader) {
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
186 int w, h, q;
5655
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
187 if (buf_size < 12) {
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
188 av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n");
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
189 return -1;
711922c1e9e7 10l, add check forgotten in last commit
reimar
parents: 5654
diff changeset
190 }
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
191 w = AV_RL16(&buf[6]);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
192 h = AV_RL16(&buf[8]);
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
193 q = buf[10];
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
194 if (!codec_reinit(avctx, w, h, q))
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
195 return -1;
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
196 buf = &buf[12];
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
197 buf_size -= 12;
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
198 }
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
199
7799
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
200 if (keyframe && c->pic.data[0])
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
201 avctx->release_buffer(avctx, &c->pic);
9126
851ff1a23191 Set AVFrame.reference correctly for nuv decoder.
reimar
parents: 9083
diff changeset
202 c->pic.reference = 3;
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
203 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
204 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
205 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
206 if (result < 0) {
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
207 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
208 return -1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
209 }
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
210
7799
c4f105f7c886 Fix nuv decoder to use reget_buffer for non-keyframes and correctly
reimar
parents: 7040
diff changeset
211 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
212 c->pic.key_frame = keyframe;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
213 // decompress/copy/whatever data
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
214 switch (comptype) {
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
215 case NUV_LZO:
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
216 case NUV_UNCOMPRESSED: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
217 int height = c->height;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
218 if (buf_size < c->width * height * 3 / 2) {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
219 av_log(avctx, AV_LOG_ERROR, "uncompressed frame too short\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
220 height = buf_size / c->width / 3 * 2;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
221 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
222 copy_frame(&c->pic, buf, c->width, height);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
223 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
224 }
5653
1b0c60bfae2a Simplify nuv: factor out LZO decompression
reimar
parents: 4962
diff changeset
225 case NUV_RTJPEG_IN_LZO:
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
226 case NUV_RTJPEG: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
227 rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
228 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
229 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
230 case NUV_BLACK: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
231 memset(c->pic.data[0], 0, c->width * c->height);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
232 memset(c->pic.data[1], 128, c->width * c->height / 4);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
233 memset(c->pic.data[2], 128, c->width * c->height / 4);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
234 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
235 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
236 case NUV_COPY_LAST: {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
237 /* nothing more to do here */
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
238 break;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
239 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
240 default:
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
241 av_log(avctx, AV_LOG_ERROR, "unknown compression\n");
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
242 return -1;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
243 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
244
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
245 *picture = c->pic;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
246 *data_size = sizeof(AVFrame);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
247 return orig_size;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
248 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
249
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6243
diff changeset
250 static av_cold int decode_init(AVCodecContext *avctx) {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
251 NuvContext *c = avctx->priv_data;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
252 avctx->pix_fmt = PIX_FMT_YUV420P;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
253 c->pic.data[0] = NULL;
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
254 c->decomp_buf = NULL;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
255 c->quality = -1;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
256 c->width = 0;
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
257 c->height = 0;
5654
93a54fcfa2f4 First ugly and slow attempt to fix nuv files with extra frameheader
reimar
parents: 5653
diff changeset
258 c->codec_frameheader = avctx->codec_tag == MKTAG('R', 'J', 'P', 'G');
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
259 if (avctx->extradata_size)
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
260 get_quant(avctx, c, avctx->extradata, avctx->extradata_size);
5669
d540c7d88344 dsputil must be initialized before calling rtjpeg init.
reimar
parents: 5658
diff changeset
261 dsputil_init(&c->dsp, avctx);
5658
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
262 if (!codec_reinit(avctx, avctx->width, avctx->height, -1))
0dc21d071895 Properly handle nuv file with changing resolution
reimar
parents: 5657
diff changeset
263 return 1;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
264 return 0;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
265 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
266
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6243
diff changeset
267 static av_cold int decode_end(AVCodecContext *avctx) {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
268 NuvContext *c = avctx->priv_data;
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
269 av_freep(&c->decomp_buf);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
270 if (c->pic.data[0])
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
271 avctx->release_buffer(avctx, &c->pic);
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
272 return 0;
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
273 }
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
274
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
275 AVCodec nuv_decoder = {
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
276 "nuv",
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
277 CODEC_TYPE_VIDEO,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
278 CODEC_ID_NUV,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
279 sizeof(NuvContext),
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
280 decode_init,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
281 NULL,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
282 decode_end,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
283 decode_frame,
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
284 CODEC_CAP_DR1,
9083
bf274494b66e Change a bunch of codec long_names to be more consistent and descriptive.
diego
parents: 8732
diff changeset
285 .long_name = NULL_IF_CONFIG_SMALL("NuppelVideo/RTJPEG"),
3224
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
286 };
28aaf0a0135e NuppelVideo/MythTVVideo support, including rtjpeg decoder
reimar
parents:
diff changeset
287