yading@10
|
1 /*
|
yading@10
|
2 * Dirac decoder support via Schroedinger libraries
|
yading@10
|
3 * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
|
yading@10
|
4 *
|
yading@10
|
5 * This file is part of FFmpeg.
|
yading@10
|
6 *
|
yading@10
|
7 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
8 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
9 * License as published by the Free Software Foundation; either
|
yading@10
|
10 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
11 *
|
yading@10
|
12 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
15 * Lesser General Public License for more details.
|
yading@10
|
16 *
|
yading@10
|
17 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
18 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
20 */
|
yading@10
|
21
|
yading@10
|
22 /**
|
yading@10
|
23 * @file
|
yading@10
|
24 * Dirac decoder support via libschroedinger-1.0 libraries. More details about
|
yading@10
|
25 * the Schroedinger project can be found at http://www.diracvideo.org/.
|
yading@10
|
26 * The library implements Dirac Specification Version 2.2.
|
yading@10
|
27 * (http://dirac.sourceforge.net/specification.html).
|
yading@10
|
28 */
|
yading@10
|
29
|
yading@10
|
30 #include <string.h>
|
yading@10
|
31
|
yading@10
|
32 #include "libavutil/imgutils.h"
|
yading@10
|
33 #include "libavutil/internal.h"
|
yading@10
|
34 #include "libavutil/intreadwrite.h"
|
yading@10
|
35 #include "libavutil/mem.h"
|
yading@10
|
36 #include "avcodec.h"
|
yading@10
|
37 #include "internal.h"
|
yading@10
|
38 #include "libschroedinger.h"
|
yading@10
|
39
|
yading@10
|
40 #include <schroedinger/schro.h>
|
yading@10
|
41 #include <schroedinger/schrodebug.h>
|
yading@10
|
42 #include <schroedinger/schrovideoformat.h>
|
yading@10
|
43
|
yading@10
|
44 /** SchroFrame and Pts relation */
|
yading@10
|
45 typedef struct LibSchroFrameContext {
|
yading@10
|
46 SchroFrame *frame;
|
yading@10
|
47 int64_t pts;
|
yading@10
|
48 } LibSchroFrameContext;
|
yading@10
|
49
|
yading@10
|
50 /** libschroedinger decoder private data */
|
yading@10
|
51 typedef struct SchroDecoderParams {
|
yading@10
|
52 /** Schroedinger video format */
|
yading@10
|
53 SchroVideoFormat *format;
|
yading@10
|
54
|
yading@10
|
55 /** Schroedinger frame format */
|
yading@10
|
56 SchroFrameFormat frame_format;
|
yading@10
|
57
|
yading@10
|
58 /** decoder handle */
|
yading@10
|
59 SchroDecoder* decoder;
|
yading@10
|
60
|
yading@10
|
61 /** queue storing decoded frames */
|
yading@10
|
62 FFSchroQueue dec_frame_queue;
|
yading@10
|
63
|
yading@10
|
64 /** end of sequence signalled */
|
yading@10
|
65 int eos_signalled;
|
yading@10
|
66
|
yading@10
|
67 /** end of sequence pulled */
|
yading@10
|
68 int eos_pulled;
|
yading@10
|
69 } SchroDecoderParams;
|
yading@10
|
70
|
yading@10
|
71 typedef struct SchroParseUnitContext {
|
yading@10
|
72 const uint8_t *buf;
|
yading@10
|
73 int buf_size;
|
yading@10
|
74 } SchroParseUnitContext;
|
yading@10
|
75
|
yading@10
|
76
|
yading@10
|
77 static void libschroedinger_decode_buffer_free(SchroBuffer *schro_buf,
|
yading@10
|
78 void *priv)
|
yading@10
|
79 {
|
yading@10
|
80 av_freep(&priv);
|
yading@10
|
81 }
|
yading@10
|
82
|
yading@10
|
83 static void parse_context_init(SchroParseUnitContext *parse_ctx,
|
yading@10
|
84 const uint8_t *buf, int buf_size)
|
yading@10
|
85 {
|
yading@10
|
86 parse_ctx->buf = buf;
|
yading@10
|
87 parse_ctx->buf_size = buf_size;
|
yading@10
|
88 }
|
yading@10
|
89
|
yading@10
|
90 static SchroBuffer *find_next_parse_unit(SchroParseUnitContext *parse_ctx)
|
yading@10
|
91 {
|
yading@10
|
92 SchroBuffer *enc_buf = NULL;
|
yading@10
|
93 int next_pu_offset = 0;
|
yading@10
|
94 unsigned char *in_buf;
|
yading@10
|
95
|
yading@10
|
96 if (parse_ctx->buf_size < 13 ||
|
yading@10
|
97 parse_ctx->buf[0] != 'B' ||
|
yading@10
|
98 parse_ctx->buf[1] != 'B' ||
|
yading@10
|
99 parse_ctx->buf[2] != 'C' ||
|
yading@10
|
100 parse_ctx->buf[3] != 'D')
|
yading@10
|
101 return NULL;
|
yading@10
|
102
|
yading@10
|
103 next_pu_offset = (parse_ctx->buf[5] << 24) +
|
yading@10
|
104 (parse_ctx->buf[6] << 16) +
|
yading@10
|
105 (parse_ctx->buf[7] << 8) +
|
yading@10
|
106 parse_ctx->buf[8];
|
yading@10
|
107
|
yading@10
|
108 if (next_pu_offset == 0 &&
|
yading@10
|
109 SCHRO_PARSE_CODE_IS_END_OF_SEQUENCE(parse_ctx->buf[4]))
|
yading@10
|
110 next_pu_offset = 13;
|
yading@10
|
111
|
yading@10
|
112 if (next_pu_offset <= 0 || parse_ctx->buf_size < next_pu_offset)
|
yading@10
|
113 return NULL;
|
yading@10
|
114
|
yading@10
|
115 in_buf = av_malloc(next_pu_offset);
|
yading@10
|
116 if (!in_buf) {
|
yading@10
|
117 av_log(parse_ctx, AV_LOG_ERROR, "Unable to allocate input buffer\n");
|
yading@10
|
118 return NULL;
|
yading@10
|
119 }
|
yading@10
|
120
|
yading@10
|
121 memcpy(in_buf, parse_ctx->buf, next_pu_offset);
|
yading@10
|
122 enc_buf = schro_buffer_new_with_data(in_buf, next_pu_offset);
|
yading@10
|
123 enc_buf->free = libschroedinger_decode_buffer_free;
|
yading@10
|
124 enc_buf->priv = in_buf;
|
yading@10
|
125
|
yading@10
|
126 parse_ctx->buf += next_pu_offset;
|
yading@10
|
127 parse_ctx->buf_size -= next_pu_offset;
|
yading@10
|
128
|
yading@10
|
129 return enc_buf;
|
yading@10
|
130 }
|
yading@10
|
131
|
yading@10
|
132 /**
|
yading@10
|
133 * Returns FFmpeg chroma format.
|
yading@10
|
134 */
|
yading@10
|
135 static enum AVPixelFormat get_chroma_format(SchroChromaFormat schro_pix_fmt)
|
yading@10
|
136 {
|
yading@10
|
137 int num_formats = sizeof(schro_pixel_format_map) /
|
yading@10
|
138 sizeof(schro_pixel_format_map[0]);
|
yading@10
|
139 int idx;
|
yading@10
|
140
|
yading@10
|
141 for (idx = 0; idx < num_formats; ++idx)
|
yading@10
|
142 if (schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt)
|
yading@10
|
143 return schro_pixel_format_map[idx].ff_pix_fmt;
|
yading@10
|
144 return AV_PIX_FMT_NONE;
|
yading@10
|
145 }
|
yading@10
|
146
|
yading@10
|
147 static av_cold int libschroedinger_decode_init(AVCodecContext *avctx)
|
yading@10
|
148 {
|
yading@10
|
149
|
yading@10
|
150 SchroDecoderParams *p_schro_params = avctx->priv_data;
|
yading@10
|
151 /* First of all, initialize our supporting libraries. */
|
yading@10
|
152 schro_init();
|
yading@10
|
153
|
yading@10
|
154 schro_debug_set_level(avctx->debug);
|
yading@10
|
155 p_schro_params->decoder = schro_decoder_new();
|
yading@10
|
156 schro_decoder_set_skip_ratio(p_schro_params->decoder, 1);
|
yading@10
|
157
|
yading@10
|
158 if (!p_schro_params->decoder)
|
yading@10
|
159 return -1;
|
yading@10
|
160
|
yading@10
|
161 /* Initialize the decoded frame queue. */
|
yading@10
|
162 ff_schro_queue_init(&p_schro_params->dec_frame_queue);
|
yading@10
|
163 return 0;
|
yading@10
|
164 }
|
yading@10
|
165
|
yading@10
|
166 static void libschroedinger_decode_frame_free(void *frame)
|
yading@10
|
167 {
|
yading@10
|
168 schro_frame_unref(frame);
|
yading@10
|
169 }
|
yading@10
|
170
|
yading@10
|
171 static void libschroedinger_handle_first_access_unit(AVCodecContext *avctx)
|
yading@10
|
172 {
|
yading@10
|
173 SchroDecoderParams *p_schro_params = avctx->priv_data;
|
yading@10
|
174 SchroDecoder *decoder = p_schro_params->decoder;
|
yading@10
|
175
|
yading@10
|
176 p_schro_params->format = schro_decoder_get_video_format(decoder);
|
yading@10
|
177
|
yading@10
|
178 /* Tell FFmpeg about sequence details. */
|
yading@10
|
179 if (av_image_check_size(p_schro_params->format->width,
|
yading@10
|
180 p_schro_params->format->height, 0, avctx) < 0) {
|
yading@10
|
181 av_log(avctx, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n",
|
yading@10
|
182 p_schro_params->format->width, p_schro_params->format->height);
|
yading@10
|
183 avctx->height = avctx->width = 0;
|
yading@10
|
184 return;
|
yading@10
|
185 }
|
yading@10
|
186 avctx->height = p_schro_params->format->height;
|
yading@10
|
187 avctx->width = p_schro_params->format->width;
|
yading@10
|
188 avctx->pix_fmt = get_chroma_format(p_schro_params->format->chroma_format);
|
yading@10
|
189
|
yading@10
|
190 if (ff_get_schro_frame_format(p_schro_params->format->chroma_format,
|
yading@10
|
191 &p_schro_params->frame_format) == -1) {
|
yading@10
|
192 av_log(avctx, AV_LOG_ERROR,
|
yading@10
|
193 "This codec currently only supports planar YUV 4:2:0, 4:2:2 "
|
yading@10
|
194 "and 4:4:4 formats.\n");
|
yading@10
|
195 return;
|
yading@10
|
196 }
|
yading@10
|
197
|
yading@10
|
198 avctx->time_base.den = p_schro_params->format->frame_rate_numerator;
|
yading@10
|
199 avctx->time_base.num = p_schro_params->format->frame_rate_denominator;
|
yading@10
|
200 }
|
yading@10
|
201
|
yading@10
|
202 static int libschroedinger_decode_frame(AVCodecContext *avctx,
|
yading@10
|
203 void *data, int *got_frame,
|
yading@10
|
204 AVPacket *avpkt)
|
yading@10
|
205 {
|
yading@10
|
206 const uint8_t *buf = avpkt->data;
|
yading@10
|
207 int buf_size = avpkt->size;
|
yading@10
|
208 int64_t pts = avpkt->pts;
|
yading@10
|
209 SchroTag *tag;
|
yading@10
|
210
|
yading@10
|
211 SchroDecoderParams *p_schro_params = avctx->priv_data;
|
yading@10
|
212 SchroDecoder *decoder = p_schro_params->decoder;
|
yading@10
|
213 SchroBuffer *enc_buf;
|
yading@10
|
214 SchroFrame* frame;
|
yading@10
|
215 AVFrame *avframe = data;
|
yading@10
|
216 int state;
|
yading@10
|
217 int go = 1;
|
yading@10
|
218 int outer = 1;
|
yading@10
|
219 SchroParseUnitContext parse_ctx;
|
yading@10
|
220 LibSchroFrameContext *framewithpts = NULL;
|
yading@10
|
221
|
yading@10
|
222 *got_frame = 0;
|
yading@10
|
223
|
yading@10
|
224 parse_context_init(&parse_ctx, buf, buf_size);
|
yading@10
|
225 if (!buf_size) {
|
yading@10
|
226 if (!p_schro_params->eos_signalled) {
|
yading@10
|
227 state = schro_decoder_push_end_of_stream(decoder);
|
yading@10
|
228 p_schro_params->eos_signalled = 1;
|
yading@10
|
229 }
|
yading@10
|
230 }
|
yading@10
|
231
|
yading@10
|
232 /* Loop through all the individual parse units in the input buffer */
|
yading@10
|
233 do {
|
yading@10
|
234 if ((enc_buf = find_next_parse_unit(&parse_ctx))) {
|
yading@10
|
235 /* Set Schrotag with the pts to be recovered after decoding*/
|
yading@10
|
236 enc_buf->tag = schro_tag_new(av_malloc(sizeof(int64_t)), av_free);
|
yading@10
|
237 if (!enc_buf->tag->value) {
|
yading@10
|
238 av_log(avctx, AV_LOG_ERROR, "Unable to allocate SchroTag\n");
|
yading@10
|
239 return AVERROR(ENOMEM);
|
yading@10
|
240 }
|
yading@10
|
241 AV_WN(64, enc_buf->tag->value, pts);
|
yading@10
|
242 /* Push buffer into decoder. */
|
yading@10
|
243 if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) &&
|
yading@10
|
244 SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0)
|
yading@10
|
245 avctx->has_b_frames = 1;
|
yading@10
|
246 state = schro_decoder_push(decoder, enc_buf);
|
yading@10
|
247 if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT)
|
yading@10
|
248 libschroedinger_handle_first_access_unit(avctx);
|
yading@10
|
249 go = 1;
|
yading@10
|
250 } else
|
yading@10
|
251 outer = 0;
|
yading@10
|
252
|
yading@10
|
253 while (go) {
|
yading@10
|
254 /* Parse data and process result. */
|
yading@10
|
255 state = schro_decoder_wait(decoder);
|
yading@10
|
256 switch (state) {
|
yading@10
|
257 case SCHRO_DECODER_FIRST_ACCESS_UNIT:
|
yading@10
|
258 libschroedinger_handle_first_access_unit(avctx);
|
yading@10
|
259 break;
|
yading@10
|
260
|
yading@10
|
261 case SCHRO_DECODER_NEED_BITS:
|
yading@10
|
262 /* Need more input data - stop iterating over what we have. */
|
yading@10
|
263 go = 0;
|
yading@10
|
264 break;
|
yading@10
|
265
|
yading@10
|
266 case SCHRO_DECODER_NEED_FRAME:
|
yading@10
|
267 /* Decoder needs a frame - create one and push it in. */
|
yading@10
|
268 frame = ff_create_schro_frame(avctx,
|
yading@10
|
269 p_schro_params->frame_format);
|
yading@10
|
270 schro_decoder_add_output_picture(decoder, frame);
|
yading@10
|
271 break;
|
yading@10
|
272
|
yading@10
|
273 case SCHRO_DECODER_OK:
|
yading@10
|
274 /* Pull a frame out of the decoder. */
|
yading@10
|
275 tag = schro_decoder_get_picture_tag(decoder);
|
yading@10
|
276 frame = schro_decoder_pull(decoder);
|
yading@10
|
277
|
yading@10
|
278 if (frame) {
|
yading@10
|
279 /* Add relation between schroframe and pts. */
|
yading@10
|
280 framewithpts = av_malloc(sizeof(LibSchroFrameContext));
|
yading@10
|
281 if (!framewithpts) {
|
yading@10
|
282 av_log(avctx, AV_LOG_ERROR, "Unable to allocate FrameWithPts\n");
|
yading@10
|
283 return AVERROR(ENOMEM);
|
yading@10
|
284 }
|
yading@10
|
285 framewithpts->frame = frame;
|
yading@10
|
286 framewithpts->pts = AV_RN64(tag->value);
|
yading@10
|
287 ff_schro_queue_push_back(&p_schro_params->dec_frame_queue,
|
yading@10
|
288 framewithpts);
|
yading@10
|
289 }
|
yading@10
|
290 break;
|
yading@10
|
291 case SCHRO_DECODER_EOS:
|
yading@10
|
292 go = 0;
|
yading@10
|
293 p_schro_params->eos_pulled = 1;
|
yading@10
|
294 schro_decoder_reset(decoder);
|
yading@10
|
295 outer = 0;
|
yading@10
|
296 break;
|
yading@10
|
297
|
yading@10
|
298 case SCHRO_DECODER_ERROR:
|
yading@10
|
299 return -1;
|
yading@10
|
300 break;
|
yading@10
|
301 }
|
yading@10
|
302 }
|
yading@10
|
303 } while (outer);
|
yading@10
|
304
|
yading@10
|
305 /* Grab next frame to be returned from the top of the queue. */
|
yading@10
|
306 framewithpts = ff_schro_queue_pop(&p_schro_params->dec_frame_queue);
|
yading@10
|
307
|
yading@10
|
308 if (framewithpts && framewithpts->frame) {
|
yading@10
|
309 int ret;
|
yading@10
|
310
|
yading@10
|
311 if ((ret = ff_get_buffer(avctx, avframe, 0)) < 0)
|
yading@10
|
312 return ret;
|
yading@10
|
313
|
yading@10
|
314 memcpy(avframe->data[0],
|
yading@10
|
315 framewithpts->frame->components[0].data,
|
yading@10
|
316 framewithpts->frame->components[0].length);
|
yading@10
|
317
|
yading@10
|
318 memcpy(avframe->data[1],
|
yading@10
|
319 framewithpts->frame->components[1].data,
|
yading@10
|
320 framewithpts->frame->components[1].length);
|
yading@10
|
321
|
yading@10
|
322 memcpy(avframe->data[2],
|
yading@10
|
323 framewithpts->frame->components[2].data,
|
yading@10
|
324 framewithpts->frame->components[2].length);
|
yading@10
|
325
|
yading@10
|
326 /* Fill frame with current buffer data from Schroedinger. */
|
yading@10
|
327 avframe->pkt_pts = framewithpts->pts;
|
yading@10
|
328 avframe->linesize[0] = framewithpts->frame->components[0].stride;
|
yading@10
|
329 avframe->linesize[1] = framewithpts->frame->components[1].stride;
|
yading@10
|
330 avframe->linesize[2] = framewithpts->frame->components[2].stride;
|
yading@10
|
331
|
yading@10
|
332 *got_frame = 1;
|
yading@10
|
333
|
yading@10
|
334 /* Now free the frame resources. */
|
yading@10
|
335 libschroedinger_decode_frame_free(framewithpts->frame);
|
yading@10
|
336 av_free(framewithpts);
|
yading@10
|
337 } else {
|
yading@10
|
338 data = NULL;
|
yading@10
|
339 *got_frame = 0;
|
yading@10
|
340 }
|
yading@10
|
341 return buf_size;
|
yading@10
|
342 }
|
yading@10
|
343
|
yading@10
|
344
|
yading@10
|
345 static av_cold int libschroedinger_decode_close(AVCodecContext *avctx)
|
yading@10
|
346 {
|
yading@10
|
347 SchroDecoderParams *p_schro_params = avctx->priv_data;
|
yading@10
|
348 /* Free the decoder. */
|
yading@10
|
349 schro_decoder_free(p_schro_params->decoder);
|
yading@10
|
350 av_freep(&p_schro_params->format);
|
yading@10
|
351
|
yading@10
|
352 /* Free data in the output frame queue. */
|
yading@10
|
353 ff_schro_queue_free(&p_schro_params->dec_frame_queue,
|
yading@10
|
354 libschroedinger_decode_frame_free);
|
yading@10
|
355
|
yading@10
|
356 return 0;
|
yading@10
|
357 }
|
yading@10
|
358
|
yading@10
|
359 static void libschroedinger_flush(AVCodecContext *avctx)
|
yading@10
|
360 {
|
yading@10
|
361 /* Got a seek request. Free the decoded frames queue and then reset
|
yading@10
|
362 * the decoder */
|
yading@10
|
363 SchroDecoderParams *p_schro_params = avctx->priv_data;
|
yading@10
|
364
|
yading@10
|
365 /* Free data in the output frame queue. */
|
yading@10
|
366 ff_schro_queue_free(&p_schro_params->dec_frame_queue,
|
yading@10
|
367 libschroedinger_decode_frame_free);
|
yading@10
|
368
|
yading@10
|
369 ff_schro_queue_init(&p_schro_params->dec_frame_queue);
|
yading@10
|
370 schro_decoder_reset(p_schro_params->decoder);
|
yading@10
|
371 p_schro_params->eos_pulled = 0;
|
yading@10
|
372 p_schro_params->eos_signalled = 0;
|
yading@10
|
373 }
|
yading@10
|
374
|
yading@10
|
375 AVCodec ff_libschroedinger_decoder = {
|
yading@10
|
376 .name = "libschroedinger",
|
yading@10
|
377 .type = AVMEDIA_TYPE_VIDEO,
|
yading@10
|
378 .id = AV_CODEC_ID_DIRAC,
|
yading@10
|
379 .priv_data_size = sizeof(SchroDecoderParams),
|
yading@10
|
380 .init = libschroedinger_decode_init,
|
yading@10
|
381 .close = libschroedinger_decode_close,
|
yading@10
|
382 .decode = libschroedinger_decode_frame,
|
yading@10
|
383 .capabilities = CODEC_CAP_DELAY,
|
yading@10
|
384 .flush = libschroedinger_flush,
|
yading@10
|
385 .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"),
|
yading@10
|
386 };
|