00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <vlc/vlc.h>
00028 #include <vlc/decoder.h>
00029
00030 #include <ogg/ogg.h>
00031
00032
00033
00034 #define TYPE int16_t
00035
00036 #define TYPE_BITS 10
00037
00038 #define RLECODER 1
00039
00040 #include <tarkin.h>
00041
00042
00043
00044
00045 struct decoder_sys_t
00046 {
00047
00048
00049
00050 TarkinStream *tarkin_stream;
00051
00052 TarkinInfo ti;
00053 TarkinComment tc;
00054 TarkinTime tarkdate;
00055
00056 int i_headers;
00057 mtime_t i_pts;
00058 };
00059
00060
00061
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
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
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
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
00105 p_dec->fmt_out.i_cat = VIDEO_ES;
00106 p_sys->i_headers = 0;
00107
00108
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
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
00124
00125
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
00138 oggpacket.packet = (*pp_block)->p_buffer;
00139 oggpacket.bytes = (*pp_block)->i_buffer;
00140 }
00141 else
00142 {
00143
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
00158
00159 oggpacket.b_o_s = 1;
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
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
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
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
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
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;
00274
00275 return p_pic;
00276 }
00277 }
00278
00279 return NULL;
00280 }
00281
00282
00283
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
00297
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 }