• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavcodec/libdiracdec.c

Go to the documentation of this file.
00001 /*
00002  * Dirac decoder support via libdirac library
00003  * Copyright (c) 2005 BBC, Andrew Kennedy <dirac at rd dot bbc dot co dot uk>
00004  * Copyright (c) 2006-2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
00005  *
00006  * This file is part of Libav.
00007  *
00008  * Libav is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * Libav is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with Libav; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00031 #include "libavutil/imgutils.h"
00032 #include "libdirac.h"
00033 
00034 #undef NDEBUG
00035 #include <assert.h>
00036 
00037 #include <libdirac_decoder/dirac_parser.h>
00038 
00040 typedef struct DiracDecoderParams {
00042     dirac_decoder_t* p_decoder;
00043 
00045     unsigned char* p_out_frame_buf;
00046 } DiracDecoderParams;
00047 
00048 
00052 static enum PixelFormat get_chroma_format(dirac_chroma_t dirac_pix_fmt)
00053 {
00054     int num_formats = sizeof(dirac_pixel_format_map) /
00055                       sizeof(dirac_pixel_format_map[0]);
00056     int idx;
00057 
00058     for (idx = 0; idx < num_formats; ++idx)
00059         if (dirac_pixel_format_map[idx].dirac_pix_fmt == dirac_pix_fmt)
00060             return dirac_pixel_format_map[idx].ff_pix_fmt;
00061     return PIX_FMT_NONE;
00062 }
00063 
00064 static av_cold int libdirac_decode_init(AVCodecContext *avccontext)
00065 {
00066 
00067     DiracDecoderParams *p_dirac_params = avccontext->priv_data;
00068     p_dirac_params->p_decoder =  dirac_decoder_init(avccontext->debug);
00069 
00070     if (!p_dirac_params->p_decoder)
00071         return -1;
00072 
00073     return 0;
00074 }
00075 
00076 static int libdirac_decode_frame(AVCodecContext *avccontext,
00077                                  void *data, int *data_size,
00078                                  AVPacket *avpkt)
00079 {
00080     const uint8_t *buf = avpkt->data;
00081     int buf_size = avpkt->size;
00082 
00083     DiracDecoderParams *p_dirac_params = avccontext->priv_data;
00084     AVPicture *picture = data;
00085     AVPicture pic;
00086     int pict_size;
00087     unsigned char *buffer[3];
00088 
00089     *data_size = 0;
00090 
00091     if (buf_size > 0) {
00092         /* set data to decode into buffer */
00093         dirac_buffer(p_dirac_params->p_decoder, buf, buf + buf_size);
00094         if ((buf[4] & 0x08) == 0x08 && (buf[4] & 0x03))
00095             avccontext->has_b_frames = 1;
00096     }
00097     while (1) {
00098          /* parse data and process result */
00099         DecoderState state = dirac_parse(p_dirac_params->p_decoder);
00100         switch (state) {
00101         case STATE_BUFFER:
00102             return buf_size;
00103 
00104         case STATE_SEQUENCE:
00105         {
00106             /* tell Libav about sequence details */
00107             dirac_sourceparams_t *src_params = &p_dirac_params->p_decoder->src_params;
00108 
00109             if (av_image_check_size(src_params->width, src_params->height,
00110                                     0, avccontext) < 0) {
00111                 av_log(avccontext, AV_LOG_ERROR, "Invalid dimensions (%dx%d)\n",
00112                        src_params->width, src_params->height);
00113                 avccontext->height = avccontext->width = 0;
00114                 return -1;
00115             }
00116 
00117             avccontext->height = src_params->height;
00118             avccontext->width  = src_params->width;
00119 
00120             avccontext->pix_fmt = get_chroma_format(src_params->chroma);
00121             if (avccontext->pix_fmt == PIX_FMT_NONE) {
00122                 av_log(avccontext, AV_LOG_ERROR,
00123                        "Dirac chroma format %d not supported currently\n",
00124                        src_params->chroma);
00125                 return -1;
00126             }
00127 
00128             avccontext->time_base.den = src_params->frame_rate.numerator;
00129             avccontext->time_base.num = src_params->frame_rate.denominator;
00130 
00131             /* calculate output dimensions */
00132             avpicture_fill(&pic, NULL, avccontext->pix_fmt,
00133                            avccontext->width, avccontext->height);
00134 
00135             pict_size = avpicture_get_size(avccontext->pix_fmt,
00136                                            avccontext->width,
00137                                            avccontext->height);
00138 
00139             /* allocate output buffer */
00140             if (!p_dirac_params->p_out_frame_buf)
00141                 p_dirac_params->p_out_frame_buf = av_malloc(pict_size);
00142             buffer[0] = p_dirac_params->p_out_frame_buf;
00143             buffer[1] = p_dirac_params->p_out_frame_buf +
00144                         pic.linesize[0] * avccontext->height;
00145             buffer[2] = buffer[1] +
00146                         pic.linesize[1] * src_params->chroma_height;
00147 
00148             /* tell Dirac about output destination */
00149             dirac_set_buf(p_dirac_params->p_decoder, buffer, NULL);
00150             break;
00151         }
00152         case STATE_SEQUENCE_END:
00153             break;
00154 
00155         case STATE_PICTURE_AVAIL:
00156             /* fill picture with current buffer data from Dirac */
00157             avpicture_fill(picture, p_dirac_params->p_out_frame_buf,
00158                            avccontext->pix_fmt,
00159                            avccontext->width, avccontext->height);
00160             *data_size = sizeof(AVPicture);
00161             return buf_size;
00162 
00163         case STATE_INVALID:
00164             return -1;
00165 
00166         default:
00167             break;
00168         }
00169     }
00170 
00171     return buf_size;
00172 }
00173 
00174 
00175 static av_cold int libdirac_decode_close(AVCodecContext *avccontext)
00176 {
00177     DiracDecoderParams *p_dirac_params = avccontext->priv_data;
00178     dirac_decoder_close(p_dirac_params->p_decoder);
00179 
00180     av_freep(&p_dirac_params->p_out_frame_buf);
00181 
00182     return 0;
00183 }
00184 
00185 static void libdirac_flush(AVCodecContext *avccontext)
00186 {
00187     /* Got a seek request. We will need free memory held in the private
00188      * context and free the current Dirac decoder handle and then open
00189      * a new decoder handle. */
00190     libdirac_decode_close(avccontext);
00191     libdirac_decode_init(avccontext);
00192     return;
00193 }
00194 
00195 
00196 
00197 AVCodec ff_libdirac_decoder = {
00198     .name           = "libdirac",
00199     .type           = AVMEDIA_TYPE_VIDEO,
00200     .id             = CODEC_ID_DIRAC,
00201     .priv_data_size = sizeof(DiracDecoderParams),
00202     .init           = libdirac_decode_init,
00203     .close          = libdirac_decode_close,
00204     .decode         = libdirac_decode_frame,
00205     .capabilities   = CODEC_CAP_DELAY,
00206     .flush = libdirac_flush,
00207     .long_name = NULL_IF_CONFIG_SMALL("libdirac Dirac 2.2"),
00208 };
Generated on Thu Jan 24 2013 17:08:52 for Libav by doxygen 1.7.1