Statistics
| Branch: | Revision:

ffmpeg / libavcodec / libschroedingerdec.c @ 735a3804

History | View | Annotate | Download (11.8 KB)

1
/*
2
 * Dirac decoder support via Schroedinger libraries
3
 * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

    
22
/**
23
* @file libavcodec/libschroedingerdec.c
24
* Dirac decoder support via libschroedinger-1.0 libraries. More details about
25
* the Schroedinger project can be found at http://www.diracvideo.org/.
26
* The library implements Dirac Specification Version 2.2.
27
* (http://dirac.sourceforge.net/specification.html).
28
*/
29

    
30
#include "avcodec.h"
31
#include "libdirac_libschro.h"
32
#include "libschroedinger.h"
33

    
34
#undef NDEBUG
35
#include <assert.h>
36

    
37

    
38
#include <schroedinger/schro.h>
39
#include <schroedinger/schrodebug.h>
40
#include <schroedinger/schrovideoformat.h>
41

    
42
/** libschroedinger decoder private data */
43
typedef struct FfmpegSchroDecoderParams
44
{
45
    /** Schroedinger video format */
46
    SchroVideoFormat *format;
47

    
48
    /** Schroedinger frame format */
49
    SchroFrameFormat frame_format;
50

    
51
    /** decoder handle */
52
    SchroDecoder* decoder;
53

    
54
    /** queue storing decoded frames */
55
    FfmpegDiracSchroQueue dec_frame_queue;
56

    
57
    /** end of sequence signalled */
58
    int eos_signalled;
59

    
60
    /** end of sequence pulled */
61
    int eos_pulled;
62

    
63
    /** decoded picture */
64
    AVPicture dec_pic;
65
} FfmpegSchroDecoderParams;
66

    
67
typedef struct FfmpegSchroParseUnitContext
68
{
69
    const uint8_t *buf;
70
    int           buf_size;
71
} FfmpegSchroParseUnitContext;
72

    
73

    
74
static void libschroedinger_decode_buffer_free (SchroBuffer *schro_buf,
75
                                                void *priv);
76

    
77
static void FfmpegSchroParseContextInit (FfmpegSchroParseUnitContext *parse_ctx,
78
                                         const uint8_t *buf, int buf_size)
79
{
80
    parse_ctx->buf           = buf;
81
    parse_ctx->buf_size      = buf_size;
82
}
83

    
84
static SchroBuffer* FfmpegFindNextSchroParseUnit (FfmpegSchroParseUnitContext *parse_ctx)
85
{
86
    SchroBuffer *enc_buf = NULL;
87
    int next_pu_offset = 0;
88
    unsigned char *in_buf;
89

    
90
    if (parse_ctx->buf_size < 13 ||
91
        parse_ctx->buf[0] != 'B' ||
92
        parse_ctx->buf[1] != 'B' ||
93
        parse_ctx->buf[2] != 'C' ||
94
        parse_ctx->buf[3] != 'D')
95
        return NULL;
96

    
97
    next_pu_offset = (parse_ctx->buf[5] << 24) +
98
                     (parse_ctx->buf[6] << 16) +
99
                     (parse_ctx->buf[7] <<  8) +
100
                      parse_ctx->buf[8];
101

    
102
    if (next_pu_offset == 0 &&
103
        SCHRO_PARSE_CODE_IS_END_OF_SEQUENCE(parse_ctx->buf[4]))
104
        next_pu_offset = 13;
105

    
106
    if (next_pu_offset <= 0 || parse_ctx->buf_size < next_pu_offset)
107
        return NULL;
108

    
109
    in_buf = av_malloc(next_pu_offset);
110
    memcpy (in_buf, parse_ctx->buf, next_pu_offset);
111
    enc_buf = schro_buffer_new_with_data (in_buf, next_pu_offset);
112
    enc_buf->free = libschroedinger_decode_buffer_free;
113
    enc_buf->priv = in_buf;
114

    
115
    parse_ctx->buf += next_pu_offset;
116
    parse_ctx->buf_size -= next_pu_offset;
117

    
118
    return enc_buf;
119
}
120

    
121
/**
122
* Returns FFmpeg chroma format.
123
*/
124
static enum PixelFormat GetFfmpegChromaFormat(SchroChromaFormat schro_pix_fmt)
125
{
126
    int num_formats = sizeof(ffmpeg_schro_pixel_format_map) /
127
                      sizeof(ffmpeg_schro_pixel_format_map[0]);
128
    int idx;
129

    
130
    for (idx = 0; idx < num_formats; ++idx)
131
        if (ffmpeg_schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt)
132
            return ffmpeg_schro_pixel_format_map[idx].ff_pix_fmt;
133
    return PIX_FMT_NONE;
134
}
135

    
136
static av_cold int libschroedinger_decode_init(AVCodecContext *avccontext)
137
{
138

    
139
    FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data ;
140
    /* First of all, initialize our supporting libraries. */
141
    schro_init();
142

    
143
    schro_debug_set_level(avccontext->debug);
144
    p_schro_params->decoder =  schro_decoder_new();
145
    schro_decoder_set_skip_ratio(p_schro_params->decoder, 1);
146

    
147
    if (!p_schro_params->decoder)
148
        return -1;
149

    
150
    /* Initialize the decoded frame queue. */
151
    ff_dirac_schro_queue_init (&p_schro_params->dec_frame_queue);
152
    return 0 ;
153
}
154

    
155
static void libschroedinger_decode_buffer_free (SchroBuffer *schro_buf,
156
                                                void *priv)
157
{
158
    av_freep(&priv);
159
}
160

    
161
static void libschroedinger_decode_frame_free (void *frame)
162
{
163
    schro_frame_unref(frame);
164
}
165

    
166
static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext)
167
{
168
    FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
169
    SchroDecoder *decoder = p_schro_params->decoder;
170

    
171
    p_schro_params->format = schro_decoder_get_video_format (decoder);
172

    
173
    /* Tell FFmpeg about sequence details. */
174
    if(avcodec_check_dimensions(avccontext, p_schro_params->format->width,
175
                                p_schro_params->format->height) < 0) {
176
        av_log(avccontext, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n",
177
               p_schro_params->format->width, p_schro_params->format->height);
178
        avccontext->height = avccontext->width = 0;
179
        return;
180
    }
181
    avccontext->height  = p_schro_params->format->height;
182
    avccontext->width   = p_schro_params->format->width;
183
    avccontext->pix_fmt =
184
                   GetFfmpegChromaFormat(p_schro_params->format->chroma_format);
185

    
186
    if (ff_get_schro_frame_format( p_schro_params->format->chroma_format,
187
                                   &p_schro_params->frame_format) == -1) {
188
        av_log (avccontext, AV_LOG_ERROR,
189
                "This codec currently only supports planar YUV 4:2:0, 4:2:2 "
190
                "and 4:4:4 formats.\n");
191
        return;
192
    }
193

    
194
    avccontext->time_base.den = p_schro_params->format->frame_rate_numerator;
195
    avccontext->time_base.num = p_schro_params->format->frame_rate_denominator;
196

    
197
    if (!p_schro_params->dec_pic.data[0])
198
        avpicture_alloc(&p_schro_params->dec_pic,
199
                        avccontext->pix_fmt,
200
                        avccontext->width,
201
                        avccontext->height);
202
}
203

    
204
static int libschroedinger_decode_frame(AVCodecContext *avccontext,
205
                                        void *data, int *data_size,
206
                                        AVPacket *avpkt)
207
{
208
    const uint8_t *buf = avpkt->data;
209
    int buf_size = avpkt->size;
210

    
211
    FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
212
    SchroDecoder *decoder = p_schro_params->decoder;
213
    SchroVideoFormat *format;
214
    AVPicture *picture = data;
215
    SchroBuffer *enc_buf;
216
    SchroFrame* frame;
217
    int state;
218
    int go = 1;
219
    int outer = 1;
220
    FfmpegSchroParseUnitContext parse_ctx;
221

    
222
    *data_size = 0;
223

    
224
    FfmpegSchroParseContextInit (&parse_ctx, buf, buf_size);
225
    if (!buf_size) {
226
        if (!p_schro_params->eos_signalled) {
227
            state = schro_decoder_push_end_of_stream(decoder);
228
            p_schro_params->eos_signalled = 1;
229
        }
230
    }
231

    
232
    /* Loop through all the individual parse units in the input buffer */
233
    do {
234
        if ((enc_buf = FfmpegFindNextSchroParseUnit(&parse_ctx))) {
235
            /* Push buffer into decoder. */
236
            if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) &&
237
                SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0)
238
                avccontext->has_b_frames = 1;
239
            state = schro_decoder_push (decoder, enc_buf);
240
            if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT)
241
                  libschroedinger_handle_first_access_unit(avccontext);
242
            go = 1;
243
        }
244
        else
245
            outer = 0;
246
    format = p_schro_params->format;
247

    
248
    while (go) {
249
        /* Parse data and process result. */
250
        state = schro_decoder_wait (decoder);
251
        switch (state)
252
        {
253
        case SCHRO_DECODER_FIRST_ACCESS_UNIT:
254
            libschroedinger_handle_first_access_unit (avccontext);
255
            break;
256

    
257
        case SCHRO_DECODER_NEED_BITS:
258
            /* Need more input data - stop iterating over what we have. */
259
            go = 0;
260
            break;
261

    
262
        case SCHRO_DECODER_NEED_FRAME:
263
            /* Decoder needs a frame - create one and push it in. */
264

    
265
            frame = schro_frame_new_and_alloc(NULL,
266
                                              p_schro_params->frame_format,
267
                                              format->width,
268
                                              format->height);
269
            schro_decoder_add_output_picture (decoder, frame);
270
            break;
271

    
272
        case SCHRO_DECODER_OK:
273
            /* Pull a frame out of the decoder. */
274
            frame = schro_decoder_pull (decoder);
275

    
276
            if (frame)
277
                ff_dirac_schro_queue_push_back(
278
                                             &p_schro_params->dec_frame_queue,
279
                                             frame);
280
            break;
281
        case SCHRO_DECODER_EOS:
282
            go = 0;
283
            p_schro_params->eos_pulled = 1;
284
            schro_decoder_reset (decoder);
285
            outer = 0;
286
            break;
287

    
288
        case SCHRO_DECODER_ERROR:
289
            return -1;
290
            break;
291
        }
292
    }
293
    } while(outer);
294

    
295
    /* Grab next frame to be returned from the top of the queue. */
296
    frame = ff_dirac_schro_queue_pop(&p_schro_params->dec_frame_queue);
297

    
298
    if (frame) {
299
        memcpy (p_schro_params->dec_pic.data[0],
300
                frame->components[0].data,
301
                frame->components[0].length);
302

    
303
        memcpy (p_schro_params->dec_pic.data[1],
304
                frame->components[1].data,
305
                frame->components[1].length);
306

    
307
        memcpy (p_schro_params->dec_pic.data[2],
308
                frame->components[2].data,
309
                frame->components[2].length);
310

    
311
        /* Fill picture with current buffer data from Schroedinger. */
312
        avpicture_fill(picture, p_schro_params->dec_pic.data[0],
313
                       avccontext->pix_fmt,
314
                       avccontext->width, avccontext->height);
315

    
316
        *data_size = sizeof(AVPicture);
317

    
318
        /* Now free the frame resources. */
319
        libschroedinger_decode_frame_free (frame);
320
    }
321
    return buf_size;
322
}
323

    
324

    
325
static av_cold int libschroedinger_decode_close(AVCodecContext *avccontext)
326
{
327
    FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
328
    /* Free the decoder. */
329
    schro_decoder_free (p_schro_params->decoder);
330
    av_freep(&p_schro_params->format);
331

    
332
    avpicture_free (&p_schro_params->dec_pic);
333

    
334
    /* Free data in the output frame queue. */
335
    ff_dirac_schro_queue_free (&p_schro_params->dec_frame_queue,
336
                               libschroedinger_decode_frame_free);
337

    
338
    return 0 ;
339
}
340

    
341
static void libschroedinger_flush (AVCodecContext *avccontext)
342
{
343
    /* Got a seek request. Free the decoded frames queue and then reset
344
     * the decoder */
345
    FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
346

    
347
    /* Free data in the output frame queue. */
348
    ff_dirac_schro_queue_free (&p_schro_params->dec_frame_queue,
349
                               libschroedinger_decode_frame_free);
350

    
351
    ff_dirac_schro_queue_init (&p_schro_params->dec_frame_queue);
352
    schro_decoder_reset(p_schro_params->decoder);
353
    p_schro_params->eos_pulled = 0;
354
    p_schro_params->eos_signalled = 0;
355
}
356

    
357
AVCodec libschroedinger_decoder = {
358
     "libschroedinger",
359
    CODEC_TYPE_VIDEO,
360
    CODEC_ID_DIRAC,
361
    sizeof(FfmpegSchroDecoderParams),
362
    libschroedinger_decode_init,
363
    NULL,
364
    libschroedinger_decode_close,
365
    libschroedinger_decode_frame,
366
    CODEC_CAP_DELAY,
367
    .flush = libschroedinger_flush,
368
    .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"),
369
};