Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

tarkin.c

00001 /*****************************************************************************
00002  * tarkin.c: tarkin decoder module making use of libtarkin.
00003  *****************************************************************************
00004  * Copyright (C) 2001-2003 the VideoLAN team
00005  * $Id: tarkin.c 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Gildas Bazin <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <vlc/vlc.h>
00028 #include <vlc/decoder.h>
00029 
00030 #include <ogg/ogg.h>
00031 
00032 /* FIXME */
00033 // use 16 bit signed integers as wavelet coefficients
00034 #define TYPE int16_t
00035 // we'll actually use TYPE_BITS bits of type (e.g. 9 magnitude + 1 sign)
00036 #define TYPE_BITS 10
00037 // use the rle entropy coder
00038 #define RLECODER 1
00039 
00040 #include <tarkin.h>
00041 
00042 /*****************************************************************************
00043  * decoder_sys_t : tarkin decoder descriptor
00044  *****************************************************************************/
00045 struct decoder_sys_t
00046 {
00047     /*
00048      * Tarkin properties
00049      */
00050     TarkinStream *tarkin_stream;
00051 
00052     TarkinInfo       ti;                        /* tarkin bitstream settings */
00053     TarkinComment    tc;                   /* tarkin bitstream user comments */
00054     TarkinTime       tarkdate;
00055 
00056     int i_headers;
00057     mtime_t i_pts;
00058 };
00059 
00060 /*****************************************************************************
00061  * Local prototypes
00062  *****************************************************************************/
00063 static int  OpenDecoder  ( vlc_object_t * );
00064 static void CloseDecoder ( vlc_object_t * );
00065 
00066 static void *DecodeBlock ( decoder_t *, block_t ** );
00067 static picture_t *DecodePacket ( decoder_t *, block_t **, ogg_packet * );
00068 
00069 static void tarkin_CopyPicture( decoder_t *, picture_t *, uint8_t *, int );
00070 
00071 /*****************************************************************************
00072  * Module descriptor
00073  *****************************************************************************/
00074 vlc_module_begin();
00075     set_description( _("Tarkin decoder module") );
00076     set_capability( "decoder", 100 );
00077     set_category( CAT_INPUT );
00078     set_subcategory( SUBCAT_INPUT_VCODEC );
00079     set_callbacks( OpenDecoder, CloseDecoder );
00080     add_shortcut( "tarkin" );
00081 vlc_module_end();
00082 
00083 /*****************************************************************************
00084  * OpenDecoder: probe the decoder and return score
00085  *****************************************************************************/
00086 static int OpenDecoder( vlc_object_t *p_this )
00087 {
00088     decoder_t *p_dec = (decoder_t*)p_this;
00089     decoder_sys_t *p_sys;
00090 
00091     if( p_dec->fmt_in.i_codec != VLC_FOURCC('t','a','r','k') )
00092     {
00093         return VLC_EGENERIC;
00094     }
00095 
00096     /* Allocate the memory needed to store the decoder's structure */
00097     if( ( p_dec->p_sys = p_sys =
00098           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
00099     {
00100         msg_Err( p_dec, "out of memory" );
00101         return VLC_EGENERIC;
00102     }
00103 
00104     /* Set output properties */
00105     p_dec->fmt_out.i_cat = VIDEO_ES;
00106     p_sys->i_headers = 0;
00107 
00108     /* Set callbacks */
00109     p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
00110         DecodeBlock;
00111     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
00112         DecodeBlock;
00113 
00114     /* Init supporting Tarkin structures needed in header parsing */
00115     p_sys->tarkin_stream = tarkin_stream_new();
00116     tarkin_info_init( &p_sys->ti );
00117     tarkin_comment_init( &p_sys->tc );
00118 
00119     return VLC_SUCCESS;
00120 }
00121 
00122 /****************************************************************************
00123  * DecodeBlock: the whole thing
00124  ****************************************************************************
00125  * This function must be fed with ogg packets.
00126  ****************************************************************************/
00127 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
00128 {
00129     decoder_sys_t *p_sys = p_dec->p_sys;
00130     block_t *p_block;
00131     ogg_packet oggpacket;
00132 
00133     if( !pp_block ) return NULL;
00134 
00135     if( *pp_block )
00136     {
00137         /* Block to Ogg packet */
00138         oggpacket.packet = (*pp_block)->p_buffer;
00139         oggpacket.bytes = (*pp_block)->i_buffer;
00140     }
00141     else
00142     {
00143         /* Block to Ogg packet */
00144         oggpacket.packet = NULL;
00145         oggpacket.bytes = 0;
00146     }
00147 
00148     p_block = *pp_block;
00149 
00150     oggpacket.granulepos = -1;
00151     oggpacket.b_o_s = 0;
00152     oggpacket.e_o_s = 0;
00153     oggpacket.packetno = 0;
00154 
00155     if( p_sys->i_headers == 0 )
00156     {
00157         /* Take care of the initial Tarkin header */
00158 
00159         oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
00160         if( tarkin_synthesis_headerin( &p_sys->ti, &p_sys->tc, &oggpacket )
00161             < 0 )
00162         {
00163             msg_Err( p_dec, "This bitstream does not contain Tarkin "
00164                      "video data.");
00165             block_Release( p_block );
00166             return NULL;
00167         }
00168         p_sys->i_headers++;
00169 
00170         block_Release( p_block );
00171         return NULL;
00172     }
00173 
00174     if( p_sys->i_headers == 1 )
00175     {
00176         if( tarkin_synthesis_headerin( &p_sys->ti, &p_sys->tc, &oggpacket )
00177             < 0 )
00178         {
00179             msg_Err( p_dec, "2nd Tarkin header is corrupted." );
00180             block_Release( p_block );
00181             return NULL;
00182         }
00183         p_sys->i_headers++;
00184         block_Release( p_block );
00185         return NULL;
00186     }
00187 
00188     if( p_sys->i_headers == 2 )
00189     {
00190         if( tarkin_synthesis_headerin( &p_sys->ti, &p_sys->tc, &oggpacket )
00191             < 0 )
00192         {
00193             msg_Err( p_dec, "3rd Tarkin header is corrupted." );
00194             block_Release( p_block );
00195             return NULL;
00196         }
00197         p_sys->i_headers++;
00198 
00199         /* Initialize the tarkin decoder */
00200         tarkin_synthesis_init( p_sys->tarkin_stream, &p_sys->ti );
00201 
00202         msg_Err( p_dec, "Tarkin codec initialized");
00203 
00204         block_Release( p_block );
00205         return NULL;
00206     }
00207 
00208     return DecodePacket( p_dec, pp_block, &oggpacket );
00209 }
00210 
00211 /*****************************************************************************
00212  * DecodePacket: decodes a Tarkin packet.
00213  *****************************************************************************/
00214 static picture_t *DecodePacket( decoder_t *p_dec, block_t **pp_block,
00215                                 ogg_packet *p_oggpacket )
00216 {
00217     decoder_sys_t *p_sys = p_dec->p_sys;
00218     uint8_t *rgb;
00219 
00220     if( p_oggpacket->bytes )
00221     {
00222         tarkin_synthesis_packetin( p_sys->tarkin_stream, p_oggpacket );
00223         //block_Release( *pp_block ); /* FIXME duplicate packet */
00224         *pp_block = NULL;
00225     }
00226 
00227     if( tarkin_synthesis_frameout( p_sys->tarkin_stream,
00228                                    &rgb, 0, &p_sys->tarkdate ) == 0 )
00229     {
00230         int i_width, i_height, i_chroma, i_stride;
00231         picture_t *p_pic;
00232 
00233         msg_Err( p_dec, "Tarkin frame decoded" );
00234 
00235         i_width = p_sys->tarkin_stream->layer->desc.width;
00236         i_height = p_sys->tarkin_stream->layer->desc.height;
00237 
00238         switch( p_sys->tarkin_stream->layer->desc.format )
00239         {
00240         case TARKIN_RGB24:
00241             i_chroma = VLC_FOURCC('R','V','2','4');
00242             i_stride = i_width * 3;
00243             break;
00244         case TARKIN_RGB32:
00245             i_chroma = VLC_FOURCC('R','V','3','2');
00246             i_stride = i_width * 4;
00247             break;
00248         case TARKIN_RGBA:
00249             i_chroma = VLC_FOURCC('R','G','B','A');
00250             i_stride = i_width * 4;
00251             break;
00252         default:
00253             i_chroma = VLC_FOURCC('I','4','2','0');
00254             i_stride = i_width;
00255             break;
00256         }
00257 
00258         /* Set output properties */
00259         p_dec->fmt_out.video.i_width = i_width;
00260         p_dec->fmt_out.video.i_height = i_height;
00261 
00262         p_dec->fmt_out.video.i_aspect =
00263             VOUT_ASPECT_FACTOR * i_width / i_height;
00264         p_dec->fmt_out.i_codec = i_chroma;
00265 
00266         /* Get a new picture */
00267         if( (p_pic = p_dec->pf_vout_buffer_new( p_dec )) )
00268         {
00269             tarkin_CopyPicture( p_dec, p_pic, rgb, i_stride );
00270 
00271             tarkin_synthesis_freeframe( p_sys->tarkin_stream, rgb );
00272 
00273             p_pic->date = mdate() + DEFAULT_PTS_DELAY/*i_pts*/;
00274 
00275             return p_pic;
00276         }
00277     }
00278 
00279     return NULL;
00280 }
00281 
00282 /*****************************************************************************
00283  * CloseDecoder: tarkin decoder destruction
00284  *****************************************************************************/
00285 static void CloseDecoder( vlc_object_t *p_this )
00286 {
00287     decoder_t *p_dec = (decoder_t *)p_this;
00288     decoder_sys_t *p_sys = p_dec->p_sys;
00289 
00290     tarkin_stream_destroy( p_sys->tarkin_stream );
00291 
00292     free( p_sys );
00293 }
00294 
00295 /*****************************************************************************
00296  * tarkin_CopyPicture: copy a picture from tarkin internal buffers to a
00297  *                     picture_t structure.
00298  *****************************************************************************/
00299 static void tarkin_CopyPicture( decoder_t *p_dec, picture_t *p_pic,
00300                                 uint8_t *p_src, int i_pitch )
00301 {
00302     int i_plane, i_line, i_src_stride, i_dst_stride;
00303     uint8_t *p_dst;
00304 
00305     for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
00306     {
00307         p_dst = p_pic->p[i_plane].p_pixels;
00308         i_dst_stride = p_pic->p[i_plane].i_pitch;
00309         i_src_stride = i_pitch;
00310 
00311         for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines; i_line++ )
00312         {
00313             p_dec->p_vlc->pf_memcpy( p_dst, p_src, i_src_stride );
00314 
00315             p_src += i_src_stride;
00316             p_dst += i_dst_stride;
00317         }
00318     }
00319 }

Generated on Tue Dec 20 10:14:30 2005 for vlc-0.8.4a by  doxygen 1.4.2