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 Libav. 6 * 7 * Libav 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 * Libav 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 Libav; 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 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 "libavutil/imgutils.h" 31#include "avcodec.h" 32#include "libdirac_libschro.h" 33#include "libschroedinger.h" 34 35#undef NDEBUG 36#include <assert.h> 37 38 39#include <schroedinger/schro.h> 40#include <schroedinger/schrodebug.h> 41#include <schroedinger/schrovideoformat.h> 42 43/** libschroedinger decoder private data */ 44typedef struct SchroDecoderParams { 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 DiracSchroQueue 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} SchroDecoderParams; 66 67typedef struct SchroParseUnitContext { 68 const uint8_t *buf; 69 int buf_size; 70} SchroParseUnitContext; 71 72 73static void libschroedinger_decode_buffer_free(SchroBuffer *schro_buf, 74 void *priv); 75 76static void SchroParseContextInit(SchroParseUnitContext *parse_ctx, 77 const uint8_t *buf, int buf_size) 78{ 79 parse_ctx->buf = buf; 80 parse_ctx->buf_size = buf_size; 81} 82 83static SchroBuffer *FindNextSchroParseUnit(SchroParseUnitContext *parse_ctx) 84{ 85 SchroBuffer *enc_buf = NULL; 86 int next_pu_offset = 0; 87 unsigned char *in_buf; 88 89 if (parse_ctx->buf_size < 13 || 90 parse_ctx->buf[0] != 'B' || 91 parse_ctx->buf[1] != 'B' || 92 parse_ctx->buf[2] != 'C' || 93 parse_ctx->buf[3] != 'D') 94 return NULL; 95 96 next_pu_offset = (parse_ctx->buf[5] << 24) + 97 (parse_ctx->buf[6] << 16) + 98 (parse_ctx->buf[7] << 8) + 99 parse_ctx->buf[8]; 100 101 if (next_pu_offset == 0 && 102 SCHRO_PARSE_CODE_IS_END_OF_SEQUENCE(parse_ctx->buf[4])) 103 next_pu_offset = 13; 104 105 if (next_pu_offset <= 0 || parse_ctx->buf_size < next_pu_offset) 106 return NULL; 107 108 in_buf = av_malloc(next_pu_offset); 109 memcpy(in_buf, parse_ctx->buf, next_pu_offset); 110 enc_buf = schro_buffer_new_with_data(in_buf, next_pu_offset); 111 enc_buf->free = libschroedinger_decode_buffer_free; 112 enc_buf->priv = in_buf; 113 114 parse_ctx->buf += next_pu_offset; 115 parse_ctx->buf_size -= next_pu_offset; 116 117 return enc_buf; 118} 119 120/** 121* Returns Libav chroma format. 122*/ 123static enum PixelFormat get_chroma_format(SchroChromaFormat schro_pix_fmt) 124{ 125 int num_formats = sizeof(schro_pixel_format_map) / 126 sizeof(schro_pixel_format_map[0]); 127 int idx; 128 129 for (idx = 0; idx < num_formats; ++idx) 130 if (schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt) 131 return schro_pixel_format_map[idx].ff_pix_fmt; 132 return PIX_FMT_NONE; 133} 134 135static av_cold int libschroedinger_decode_init(AVCodecContext *avccontext) 136{ 137 138 SchroDecoderParams *p_schro_params = avccontext->priv_data; 139 /* First of all, initialize our supporting libraries. */ 140 schro_init(); 141 142 schro_debug_set_level(avccontext->debug); 143 p_schro_params->decoder = schro_decoder_new(); 144 schro_decoder_set_skip_ratio(p_schro_params->decoder, 1); 145 146 if (!p_schro_params->decoder) 147 return -1; 148 149 /* Initialize the decoded frame queue. */ 150 ff_dirac_schro_queue_init(&p_schro_params->dec_frame_queue); 151 return 0; 152} 153 154static void libschroedinger_decode_buffer_free(SchroBuffer *schro_buf, 155 void *priv) 156{ 157 av_freep(&priv); 158} 159 160static void libschroedinger_decode_frame_free(void *frame) 161{ 162 schro_frame_unref(frame); 163} 164 165static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext) 166{ 167 SchroDecoderParams *p_schro_params = avccontext->priv_data; 168 SchroDecoder *decoder = p_schro_params->decoder; 169 170 p_schro_params->format = schro_decoder_get_video_format(decoder); 171 172 /* Tell Libav about sequence details. */ 173 if (av_image_check_size(p_schro_params->format->width, p_schro_params->format->height, 174 0, avccontext) < 0) { 175 av_log(avccontext, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n", 176 p_schro_params->format->width, p_schro_params->format->height); 177 avccontext->height = avccontext->width = 0; 178 return; 179 } 180 avccontext->height = p_schro_params->format->height; 181 avccontext->width = p_schro_params->format->width; 182 avccontext->pix_fmt = get_chroma_format(p_schro_params->format->chroma_format); 183 184 if (ff_get_schro_frame_format(p_schro_params->format->chroma_format, 185 &p_schro_params->frame_format) == -1) { 186 av_log(avccontext, AV_LOG_ERROR, 187 "This codec currently only supports planar YUV 4:2:0, 4:2:2 " 188 "and 4:4:4 formats.\n"); 189 return; 190 } 191 192 avccontext->time_base.den = p_schro_params->format->frame_rate_numerator; 193 avccontext->time_base.num = p_schro_params->format->frame_rate_denominator; 194 195 if (!p_schro_params->dec_pic.data[0]) 196 avpicture_alloc(&p_schro_params->dec_pic, 197 avccontext->pix_fmt, 198 avccontext->width, 199 avccontext->height); 200} 201 202static int libschroedinger_decode_frame(AVCodecContext *avccontext, 203 void *data, int *data_size, 204 AVPacket *avpkt) 205{ 206 const uint8_t *buf = avpkt->data; 207 int buf_size = avpkt->size; 208 209 SchroDecoderParams *p_schro_params = avccontext->priv_data; 210 SchroDecoder *decoder = p_schro_params->decoder; 211 AVPicture *picture = data; 212 SchroBuffer *enc_buf; 213 SchroFrame* frame; 214 int state; 215 int go = 1; 216 int outer = 1; 217 SchroParseUnitContext parse_ctx; 218 219 *data_size = 0; 220 221 SchroParseContextInit(&parse_ctx, buf, buf_size); 222 if (!buf_size) { 223 if (!p_schro_params->eos_signalled) { 224 state = schro_decoder_push_end_of_stream(decoder); 225 p_schro_params->eos_signalled = 1; 226 } 227 } 228 229 /* Loop through all the individual parse units in the input buffer */ 230 do { 231 if ((enc_buf = FindNextSchroParseUnit(&parse_ctx))) { 232 /* Push buffer into decoder. */ 233 if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) && 234 SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0) 235 avccontext->has_b_frames = 1; 236 state = schro_decoder_push(decoder, enc_buf); 237 if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT) 238 libschroedinger_handle_first_access_unit(avccontext); 239 go = 1; 240 } else 241 outer = 0; 242 243 while (go) { 244 /* Parse data and process result. */ 245 state = schro_decoder_wait(decoder); 246 switch (state) { 247 case SCHRO_DECODER_FIRST_ACCESS_UNIT: 248 libschroedinger_handle_first_access_unit(avccontext); 249 break; 250 251 case SCHRO_DECODER_NEED_BITS: 252 /* Need more input data - stop iterating over what we have. */ 253 go = 0; 254 break; 255 256 case SCHRO_DECODER_NEED_FRAME: 257 /* Decoder needs a frame - create one and push it in. */ 258 frame = ff_create_schro_frame(avccontext, 259 p_schro_params->frame_format); 260 schro_decoder_add_output_picture(decoder, frame); 261 break; 262 263 case SCHRO_DECODER_OK: 264 /* Pull a frame out of the decoder. */ 265 frame = schro_decoder_pull(decoder); 266 267 if (frame) 268 ff_dirac_schro_queue_push_back(&p_schro_params->dec_frame_queue, 269 frame); 270 break; 271 case SCHRO_DECODER_EOS: 272 go = 0; 273 p_schro_params->eos_pulled = 1; 274 schro_decoder_reset(decoder); 275 outer = 0; 276 break; 277 278 case SCHRO_DECODER_ERROR: 279 return -1; 280 break; 281 } 282 } 283 } while (outer); 284 285 /* Grab next frame to be returned from the top of the queue. */ 286 frame = ff_dirac_schro_queue_pop(&p_schro_params->dec_frame_queue); 287 288 if (frame) { 289 memcpy(p_schro_params->dec_pic.data[0], 290 frame->components[0].data, 291 frame->components[0].length); 292 293 memcpy(p_schro_params->dec_pic.data[1], 294 frame->components[1].data, 295 frame->components[1].length); 296 297 memcpy(p_schro_params->dec_pic.data[2], 298 frame->components[2].data, 299 frame->components[2].length); 300 301 /* Fill picture with current buffer data from Schroedinger. */ 302 avpicture_fill(picture, p_schro_params->dec_pic.data[0], 303 avccontext->pix_fmt, 304 avccontext->width, avccontext->height); 305 306 *data_size = sizeof(AVPicture); 307 308 /* Now free the frame resources. */ 309 libschroedinger_decode_frame_free(frame); 310 } 311 return buf_size; 312} 313 314 315static av_cold int libschroedinger_decode_close(AVCodecContext *avccontext) 316{ 317 SchroDecoderParams *p_schro_params = avccontext->priv_data; 318 /* Free the decoder. */ 319 schro_decoder_free(p_schro_params->decoder); 320 av_freep(&p_schro_params->format); 321 322 avpicture_free(&p_schro_params->dec_pic); 323 324 /* Free data in the output frame queue. */ 325 ff_dirac_schro_queue_free(&p_schro_params->dec_frame_queue, 326 libschroedinger_decode_frame_free); 327 328 return 0; 329} 330 331static void libschroedinger_flush(AVCodecContext *avccontext) 332{ 333 /* Got a seek request. Free the decoded frames queue and then reset 334 * the decoder */ 335 SchroDecoderParams *p_schro_params = avccontext->priv_data; 336 337 /* Free data in the output frame queue. */ 338 ff_dirac_schro_queue_free(&p_schro_params->dec_frame_queue, 339 libschroedinger_decode_frame_free); 340 341 ff_dirac_schro_queue_init(&p_schro_params->dec_frame_queue); 342 schro_decoder_reset(p_schro_params->decoder); 343 p_schro_params->eos_pulled = 0; 344 p_schro_params->eos_signalled = 0; 345} 346 347AVCodec ff_libschroedinger_decoder = { 348 .name = "libschroedinger", 349 .type = AVMEDIA_TYPE_VIDEO, 350 .id = CODEC_ID_DIRAC, 351 .priv_data_size = sizeof(SchroDecoderParams), 352 .init = libschroedinger_decode_init, 353 .close = libschroedinger_decode_close, 354 .decode = libschroedinger_decode_frame, 355 .capabilities = CODEC_CAP_DELAY, 356 .flush = libschroedinger_flush, 357 .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"), 358}; 359