~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/nuv.c

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc, Andrew Starr-Bochicchio, Lionel Le Folgoc
  • Date: 2008-12-26 00:10:06 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20081226001006-2040ls9680bd1blt
Tags: 1.1.7-0.2ubuntu1
[ Andrew Starr-Bochicchio ]
* Merge from debian-multimedia (LP: #298547), Ubuntu Changes:
 - For ffmpeg-related build-deps, fix versionized dependencies
   as the ubuntu versioning is different than debian-multimedia's.

[ Lionel Le Folgoc ]
* LP: #311412 is fixed since the 1.1.7~rc1-0.1 revision.
* debian/patches/03_ffmpeg.diff: updated to fix FTBFS due to libswscale API
  change (cherry-pick from Gentoo #234383).

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include <stdio.h>
22
22
#include <stdlib.h>
23
23
 
24
 
#include "common.h"
25
24
#include "avcodec.h"
26
25
 
27
26
#include "bswap.h"
31
30
 
32
31
typedef struct {
33
32
    AVFrame pic;
 
33
    int codec_frameheader;
 
34
    int quality;
34
35
    int width, height;
35
36
    unsigned int decomp_size;
36
37
    unsigned char* decomp_buf;
39
40
    DSPContext dsp;
40
41
} NuvContext;
41
42
 
 
43
static const uint8_t fallback_lquant[] = {
 
44
    16,  11,  10,  16,  24,  40,  51,  61,
 
45
    12,  12,  14,  19,  26,  58,  60,  55,
 
46
    14,  13,  16,  24,  40,  57,  69,  56,
 
47
    14,  17,  22,  29,  51,  87,  80,  62,
 
48
    18,  22,  37,  56,  68, 109, 103,  77,
 
49
    24,  35,  55,  64,  81, 104, 113,  92,
 
50
    49,  64,  78,  87, 103, 121, 120, 101,
 
51
    72,  92,  95,  98, 112, 100, 103,  99
 
52
};
 
53
 
 
54
static const uint8_t fallback_cquant[] = {
 
55
    17, 18, 24, 47, 99, 99, 99, 99,
 
56
    18, 21, 26, 66, 99, 99, 99, 99,
 
57
    24, 26, 56, 99, 99, 99, 99, 99,
 
58
    47, 66, 99, 99, 99, 99, 99, 99,
 
59
    99, 99, 99, 99, 99, 99, 99, 99,
 
60
    99, 99, 99, 99, 99, 99, 99, 99,
 
61
    99, 99, 99, 99, 99, 99, 99, 99,
 
62
    99, 99, 99, 99, 99, 99, 99, 99
 
63
};
 
64
 
42
65
/**
43
66
 * \brief copy frame data from buffer to AVFrame, handling stride.
44
67
 * \param f destination AVFrame
46
69
 * \param width width of the video frame
47
70
 * \param height height of the video frame
48
71
 */
49
 
static void copy_frame(AVFrame *f, uint8_t *src,
 
72
static void copy_frame(AVFrame *f, const uint8_t *src,
50
73
                       int width, int height) {
51
74
    AVPicture pic;
52
75
    avpicture_fill(&pic, src, PIX_FMT_YUV420P, width, height);
53
 
    img_copy((AVPicture *)f, &pic, PIX_FMT_YUV420P, width, height);
 
76
    av_picture_copy((AVPicture *)f, &pic, PIX_FMT_YUV420P, width, height);
54
77
}
55
78
 
56
79
/**
57
80
 * \brief extract quantization tables from codec data into our context
58
81
 */
59
82
static int get_quant(AVCodecContext *avctx, NuvContext *c,
60
 
                     uint8_t *buf, int size) {
 
83
                     const uint8_t *buf, int size) {
61
84
    int i;
62
85
    if (size < 2 * 64 * 4) {
63
86
        av_log(avctx, AV_LOG_ERROR, "insufficient rtjpeg quant data\n");
70
93
    return 0;
71
94
}
72
95
 
 
96
/**
 
97
 * \brief set quantization tables from a quality value
 
98
 */
 
99
static void get_quant_quality(NuvContext *c, int quality) {
 
100
    int i;
 
101
    quality = FFMAX(quality, 1);
 
102
    for (i = 0; i < 64; i++) {
 
103
        c->lq[i] = (fallback_lquant[i] << 7) / quality;
 
104
        c->cq[i] = (fallback_cquant[i] << 7) / quality;
 
105
    }
 
106
}
 
107
 
 
108
static int codec_reinit(AVCodecContext *avctx, int width, int height, int quality) {
 
109
    NuvContext *c = avctx->priv_data;
 
110
    width = (width + 1) & ~1;
 
111
    height = (height + 1) & ~1;
 
112
    if (quality >= 0)
 
113
        get_quant_quality(c, quality);
 
114
    if (width != c->width || height != c->height) {
 
115
        if (avcodec_check_dimensions(avctx, height, width) < 0)
 
116
            return 0;
 
117
        avctx->width = c->width = width;
 
118
        avctx->height = c->height = height;
 
119
        c->decomp_size = c->height * c->width * 3 / 2;
 
120
        c->decomp_buf = av_realloc(c->decomp_buf, c->decomp_size + LZO_OUTPUT_PADDING);
 
121
        if (!c->decomp_buf) {
 
122
            av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
 
123
            return 0;
 
124
        }
 
125
        rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq);
 
126
    } else if (quality != c->quality)
 
127
        rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq);
 
128
    return 1;
 
129
}
 
130
 
73
131
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
74
 
                        uint8_t *buf, int buf_size) {
75
 
    NuvContext *c = (NuvContext *)avctx->priv_data;
 
132
                        const uint8_t *buf, int buf_size) {
 
133
    NuvContext *c = avctx->priv_data;
76
134
    AVFrame *picture = data;
77
135
    int orig_size = buf_size;
78
136
    enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1',
84
142
        return -1;
85
143
    }
86
144
 
87
 
    if (c->pic.data[0])
88
 
        avctx->release_buffer(avctx, &c->pic);
89
 
    c->pic.reference = 1;
90
 
    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE |
91
 
                          FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
92
 
    if (avctx->get_buffer(avctx, &c->pic) < 0) {
93
 
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
94
 
        return -1;
95
 
    }
96
 
 
97
145
    // codec data (rtjpeg quant tables)
98
146
    if (buf[0] == 'D' && buf[1] == 'R') {
99
147
        int ret;
115
163
    // skip rest of the frameheader.
116
164
    buf = &buf[12];
117
165
    buf_size -= 12;
 
166
    if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) {
 
167
        int outlen = c->decomp_size, inlen = buf_size;
 
168
        if (lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen))
 
169
            av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
 
170
        buf = c->decomp_buf;
 
171
        buf_size = c->decomp_size;
 
172
    }
 
173
    if (c->codec_frameheader) {
 
174
        int w, h, q;
 
175
        if (buf_size < 12) {
 
176
            av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n");
 
177
            return -1;
 
178
        }
 
179
        w = AV_RL16(&buf[6]);
 
180
        h = AV_RL16(&buf[8]);
 
181
        q = buf[10];
 
182
        if (!codec_reinit(avctx, w, h, q))
 
183
            return -1;
 
184
        buf = &buf[12];
 
185
        buf_size -= 12;
 
186
    }
 
187
 
 
188
    if (c->pic.data[0])
 
189
        avctx->release_buffer(avctx, &c->pic);
 
190
    c->pic.reference = 1;
 
191
    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE |
 
192
                          FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
 
193
    if (avctx->get_buffer(avctx, &c->pic) < 0) {
 
194
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 
195
        return -1;
 
196
    }
118
197
 
119
198
    c->pic.pict_type = FF_I_TYPE;
120
199
    c->pic.key_frame = 1;
121
200
    // decompress/copy/whatever data
122
201
    switch (comptype) {
 
202
        case NUV_LZO:
123
203
        case NUV_UNCOMPRESSED: {
124
204
            int height = c->height;
125
205
            if (buf_size < c->width * height * 3 / 2) {
129
209
            copy_frame(&c->pic, buf, c->width, height);
130
210
            break;
131
211
        }
 
212
        case NUV_RTJPEG_IN_LZO:
132
213
        case NUV_RTJPEG: {
133
214
            rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size);
134
215
            break;
135
216
        }
136
 
        case NUV_RTJPEG_IN_LZO: {
137
 
            int outlen = c->decomp_size, inlen = buf_size;
138
 
            if (lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen))
139
 
                av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
140
 
            rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, c->decomp_buf, c->decomp_size);
141
 
            break;
142
 
        }
143
 
        case NUV_LZO: {
144
 
            int outlen = c->decomp_size, inlen = buf_size;
145
 
            if (lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen))
146
 
                av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
147
 
            copy_frame(&c->pic, c->decomp_buf, c->width, c->height);
148
 
            break;
149
 
        }
150
217
        case NUV_BLACK: {
151
218
            memset(c->pic.data[0], 0, c->width * c->height);
152
219
            memset(c->pic.data[1], 128, c->width * c->height / 4);
169
236
    return orig_size;
170
237
}
171
238
 
172
 
static int decode_init(AVCodecContext *avctx) {
173
 
    NuvContext *c = (NuvContext *)avctx->priv_data;
174
 
    avctx->width = (avctx->width + 1) & ~1;
175
 
    avctx->height = (avctx->height + 1) & ~1;
176
 
    if (avcodec_check_dimensions(avctx, avctx->height, avctx->width) < 0) {
177
 
        return 1;
178
 
    }
179
 
    avctx->has_b_frames = 0;
 
239
static av_cold int decode_init(AVCodecContext *avctx) {
 
240
    NuvContext *c = avctx->priv_data;
180
241
    avctx->pix_fmt = PIX_FMT_YUV420P;
181
242
    c->pic.data[0] = NULL;
182
 
    c->width = avctx->width;
183
 
    c->height = avctx->height;
184
 
    c->decomp_size = c->height * c->width * 3 / 2;
185
 
    c->decomp_buf = av_malloc(c->decomp_size + LZO_OUTPUT_PADDING);
186
 
    if (!c->decomp_buf) {
187
 
        av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
188
 
        return 1;
189
 
    }
190
 
    dsputil_init(&c->dsp, avctx);
 
243
    c->decomp_buf = NULL;
 
244
    c->quality = -1;
 
245
    c->width = 0;
 
246
    c->height = 0;
 
247
    c->codec_frameheader = avctx->codec_tag == MKTAG('R', 'J', 'P', 'G');
191
248
    if (avctx->extradata_size)
192
249
        get_quant(avctx, c, avctx->extradata, avctx->extradata_size);
193
 
    rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq);
 
250
    dsputil_init(&c->dsp, avctx);
 
251
    if (!codec_reinit(avctx, avctx->width, avctx->height, -1))
 
252
        return 1;
194
253
    return 0;
195
254
}
196
255
 
197
 
static int decode_end(AVCodecContext *avctx) {
198
 
    NuvContext *c = (NuvContext *)avctx->priv_data;
 
256
static av_cold int decode_end(AVCodecContext *avctx) {
 
257
    NuvContext *c = avctx->priv_data;
199
258
    av_freep(&c->decomp_buf);
200
259
    if (c->pic.data[0])
201
260
        avctx->release_buffer(avctx, &c->pic);
212
271
    decode_end,
213
272
    decode_frame,
214
273
    CODEC_CAP_DR1,
 
274
    .long_name = "NuppelVideo",
215
275
};
216
276