1
by Reinhard Tartler
Import upstream version 0.6.2 |
1 |
/*
|
2 |
* Dirac decoder support via libdirac library
|
|
3 |
* Copyright (c) 2005 BBC, Andrew Kennedy <dirac at rd dot bbc dot co dot uk>
|
|
4 |
* Copyright (c) 2006-2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
|
|
5 |
*
|
|
1.2.1
by Reinhard Tartler
Import upstream version 0.7~b1 |
6 |
* This file is part of Libav.
|
1
by Reinhard Tartler
Import upstream version 0.6.2 |
7 |
*
|
1.2.1
by Reinhard Tartler
Import upstream version 0.7~b1 |
8 |
* Libav is free software; you can redistribute it and/or
|
1
by Reinhard Tartler
Import upstream version 0.6.2 |
9 |
* modify it under the terms of the GNU Lesser General Public
|
10 |
* License as published by the Free Software Foundation; either
|
|
11 |
* version 2.1 of the License, or (at your option) any later version.
|
|
12 |
*
|
|
1.2.1
by Reinhard Tartler
Import upstream version 0.7~b1 |
13 |
* Libav is distributed in the hope that it will be useful,
|
1
by Reinhard Tartler
Import upstream version 0.6.2 |
14 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
16 |
* Lesser General Public License for more details.
|
|
17 |
*
|
|
18 |
* You should have received a copy of the GNU Lesser General Public
|
|
1.2.1
by Reinhard Tartler
Import upstream version 0.7~b1 |
19 |
* License along with Libav; if not, write to the Free Software
|
1
by Reinhard Tartler
Import upstream version 0.6.2 |
20 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
21 |
*/
|
|
22 |
||
23 |
/**
|
|
24 |
* @file
|
|
25 |
* Dirac decoder support via libdirac library; more details about the Dirac
|
|
26 |
* project can be found at http://dirac.sourceforge.net/.
|
|
27 |
* The libdirac_decoder library implements Dirac specification version 2.2
|
|
28 |
* (http://dirac.sourceforge.net/specification.html).
|
|
29 |
*/
|
|
30 |
||
1.2.1
by Reinhard Tartler
Import upstream version 0.7~b1 |
31 |
#include "libavutil/imgutils.h" |
1
by Reinhard Tartler
Import upstream version 0.6.2 |
32 |
#include "libdirac.h" |
33 |
||
34 |
#undef NDEBUG
|
|
35 |
#include <assert.h> |
|
36 |
||
37 |
#include <libdirac_decoder/dirac_parser.h> |
|
38 |
||
39 |
/** contains a single frame returned from Dirac */
|
|
1.4.1
by Reinhard Tartler
Import upstream version 0.8~beta1 |
40 |
typedef struct DiracDecoderParams { |
1
by Reinhard Tartler
Import upstream version 0.6.2 |
41 |
/** decoder handle */
|
42 |
dirac_decoder_t* p_decoder; |
|
43 |
||
44 |
/** buffer to hold decoded frame */
|
|
45 |
unsigned char* p_out_frame_buf; |
|
1.4.1
by Reinhard Tartler
Import upstream version 0.8~beta1 |
46 |
} DiracDecoderParams; |
1
by Reinhard Tartler
Import upstream version 0.6.2 |
47 |
|
48 |
||
49 |
/**
|
|
1.2.1
by Reinhard Tartler
Import upstream version 0.7~b1 |
50 |
* returns Libav chroma format
|
1
by Reinhard Tartler
Import upstream version 0.6.2 |
51 |
*/
|
1.4.1
by Reinhard Tartler
Import upstream version 0.8~beta1 |
52 |
static enum PixelFormat get_chroma_format(dirac_chroma_t dirac_pix_fmt) |
1
by Reinhard Tartler
Import upstream version 0.6.2 |
53 |
{
|
1.4.1
by Reinhard Tartler
Import upstream version 0.8~beta1 |
54 |
int num_formats = sizeof(dirac_pixel_format_map) / |
55 |
sizeof(dirac_pixel_format_map[0]); |
|
1
by Reinhard Tartler
Import upstream version 0.6.2 |
56 |
int idx; |
57 |
||
58 |
for (idx = 0; idx < num_formats; ++idx) |
|
1.4.1
by Reinhard Tartler
Import upstream version 0.8~beta1 |
59 |
if (dirac_pixel_format_map[idx].dirac_pix_fmt == dirac_pix_fmt) |
60 |
return dirac_pixel_format_map[idx].ff_pix_fmt; |
|
1
by Reinhard Tartler
Import upstream version 0.6.2 |
61 |
return PIX_FMT_NONE; |
62 |
}
|
|
63 |
||
64 |
static av_cold int libdirac_decode_init(AVCodecContext *avccontext) |
|
65 |
{
|
|
66 |
||
1.4.1
by Reinhard Tartler
Import upstream version 0.8~beta1 |
67 |
DiracDecoderParams *p_dirac_params = avccontext->priv_data; |
1
by Reinhard Tartler
Import upstream version 0.6.2 |
68 |
p_dirac_params->p_decoder = dirac_decoder_init(avccontext->debug); |
69 |
||
70 |
if (!p_dirac_params->p_decoder) |
|
71 |
return -1; |
|
72 |
||
73 |
return 0; |
|
74 |
}
|
|
75 |
||
76 |
static int libdirac_decode_frame(AVCodecContext *avccontext, |
|
77 |
void *data, int *data_size, |
|
78 |
AVPacket *avpkt) |
|
79 |
{
|
|
80 |
const uint8_t *buf = avpkt->data; |
|
81 |
int buf_size = avpkt->size; |
|
82 |
||
1.4.1
by Reinhard Tartler
Import upstream version 0.8~beta1 |
83 |
DiracDecoderParams *p_dirac_params = avccontext->priv_data; |
1
by Reinhard Tartler
Import upstream version 0.6.2 |
84 |
AVPicture *picture = data; |
85 |
AVPicture pic; |
|
86 |
int pict_size; |
|
87 |
unsigned char *buffer[3]; |
|
88 |
||
89 |
*data_size = 0; |
|
90 |
||
91 |
if (buf_size > 0) { |
|
92 |
/* set data to decode into buffer */
|
|
93 |
dirac_buffer(p_dirac_params->p_decoder, buf, buf + buf_size); |
|
94 |
if ((buf[4] & 0x08) == 0x08 && (buf[4] & 0x03)) |
|
95 |
avccontext->has_b_frames = 1; |
|
96 |
}
|
|
97 |
while (1) { |
|
98 |
/* parse data and process result */
|
|
99 |
DecoderState state = dirac_parse(p_dirac_params->p_decoder); |
|
100 |
switch (state) { |
|
101 |
case STATE_BUFFER: |
|
102 |
return buf_size; |
|
103 |
||
104 |
case STATE_SEQUENCE: |
|
105 |
{
|
|
1.2.1
by Reinhard Tartler
Import upstream version 0.7~b1 |
106 |
/* tell Libav about sequence details */
|
1
by Reinhard Tartler
Import upstream version 0.6.2 |
107 |
dirac_sourceparams_t *src_params = &p_dirac_params->p_decoder->src_params; |
108 |
||
1.2.1
by Reinhard Tartler
Import upstream version 0.7~b1 |
109 |
if (av_image_check_size(src_params->width, src_params->height, |
110 |
0, avccontext) < 0) { |
|
1
by Reinhard Tartler
Import upstream version 0.6.2 |
111 |
av_log(avccontext, AV_LOG_ERROR, "Invalid dimensions (%dx%d)\n", |
112 |
src_params->width, src_params->height); |
|
113 |
avccontext->height = avccontext->width = 0; |
|
114 |
return -1; |
|
115 |
}
|
|
116 |
||
117 |
avccontext->height = src_params->height; |
|
118 |
avccontext->width = src_params->width; |
|
119 |
||
1.4.1
by Reinhard Tartler
Import upstream version 0.8~beta1 |
120 |
avccontext->pix_fmt = get_chroma_format(src_params->chroma); |
1
by Reinhard Tartler
Import upstream version 0.6.2 |
121 |
if (avccontext->pix_fmt == PIX_FMT_NONE) { |
122 |
av_log(avccontext, AV_LOG_ERROR, |
|
123 |
"Dirac chroma format %d not supported currently\n", |
|
124 |
src_params->chroma); |
|
125 |
return -1; |
|
126 |
}
|
|
127 |
||
128 |
avccontext->time_base.den = src_params->frame_rate.numerator; |
|
129 |
avccontext->time_base.num = src_params->frame_rate.denominator; |
|
130 |
||
131 |
/* calculate output dimensions */
|
|
132 |
avpicture_fill(&pic, NULL, avccontext->pix_fmt, |
|
133 |
avccontext->width, avccontext->height); |
|
134 |
||
135 |
pict_size = avpicture_get_size(avccontext->pix_fmt, |
|
136 |
avccontext->width, |
|
137 |
avccontext->height); |
|
138 |
||
139 |
/* allocate output buffer */
|
|
140 |
if (!p_dirac_params->p_out_frame_buf) |
|
141 |
p_dirac_params->p_out_frame_buf = av_malloc(pict_size); |
|
142 |
buffer[0] = p_dirac_params->p_out_frame_buf; |
|
143 |
buffer[1] = p_dirac_params->p_out_frame_buf + |
|
144 |
pic.linesize[0] * avccontext->height; |
|
145 |
buffer[2] = buffer[1] + |
|
146 |
pic.linesize[1] * src_params->chroma_height; |
|
147 |
||
148 |
/* tell Dirac about output destination */
|
|
149 |
dirac_set_buf(p_dirac_params->p_decoder, buffer, NULL); |
|
150 |
break; |
|
151 |
}
|
|
152 |
case STATE_SEQUENCE_END: |
|
153 |
break; |
|
154 |
||
155 |
case STATE_PICTURE_AVAIL: |
|
156 |
/* fill picture with current buffer data from Dirac */
|
|
157 |
avpicture_fill(picture, p_dirac_params->p_out_frame_buf, |
|
158 |
avccontext->pix_fmt, |
|
159 |
avccontext->width, avccontext->height); |
|
160 |
*data_size = sizeof(AVPicture); |
|
161 |
return buf_size; |
|
162 |
||
163 |
case STATE_INVALID: |
|
164 |
return -1; |
|
165 |
||
166 |
default: |
|
167 |
break; |
|
168 |
}
|
|
169 |
}
|
|
170 |
||
171 |
return buf_size; |
|
172 |
}
|
|
173 |
||
174 |
||
175 |
static av_cold int libdirac_decode_close(AVCodecContext *avccontext) |
|
176 |
{
|
|
1.4.1
by Reinhard Tartler
Import upstream version 0.8~beta1 |
177 |
DiracDecoderParams *p_dirac_params = avccontext->priv_data; |
1
by Reinhard Tartler
Import upstream version 0.6.2 |
178 |
dirac_decoder_close(p_dirac_params->p_decoder); |
179 |
||
180 |
av_freep(&p_dirac_params->p_out_frame_buf); |
|
181 |
||
182 |
return 0; |
|
183 |
}
|
|
184 |
||
185 |
static void libdirac_flush(AVCodecContext *avccontext) |
|
186 |
{
|
|
187 |
/* Got a seek request. We will need free memory held in the private
|
|
188 |
* context and free the current Dirac decoder handle and then open
|
|
189 |
* a new decoder handle. */
|
|
190 |
libdirac_decode_close(avccontext); |
|
191 |
libdirac_decode_init(avccontext); |
|
192 |
return; |
|
193 |
}
|
|
194 |
||
195 |
||
196 |
||
1.2.1
by Reinhard Tartler
Import upstream version 0.7~b1 |
197 |
AVCodec ff_libdirac_decoder = { |
1.4.1
by Reinhard Tartler
Import upstream version 0.8~beta1 |
198 |
.name = "libdirac", |
199 |
.type = AVMEDIA_TYPE_VIDEO, |
|
200 |
.id = CODEC_ID_DIRAC, |
|
201 |
.priv_data_size = sizeof(DiracDecoderParams), |
|
202 |
.init = libdirac_decode_init, |
|
203 |
.close = libdirac_decode_close, |
|
204 |
.decode = libdirac_decode_frame, |
|
205 |
.capabilities = CODEC_CAP_DELAY, |
|
1
by Reinhard Tartler
Import upstream version 0.6.2 |
206 |
.flush = libdirac_flush, |
207 |
.long_name = NULL_IF_CONFIG_SMALL("libdirac Dirac 2.2"), |
|
208 |
};
|