tarkin.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:10k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * tarkin.c: tarkin decoder module making use of libtarkin.
  3.  *****************************************************************************
  4.  * Copyright (C) 2001-2003 the VideoLAN team
  5.  * $Id: 8c00db57632a8e8c4dc8642f74e835134011bfea $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <vlc_common.h>
  30. #include <vlc_plugin.h>
  31. #include <vlc_codec.h>
  32. #include <vlc_vout.h>
  33. #include <ogg/ogg.h>
  34. /* FIXME */
  35. // use 16 bit signed integers as wavelet coefficients
  36. #define TYPE int16_t
  37. // we'll actually use TYPE_BITS bits of type (e.g. 9 magnitude + 1 sign)
  38. #define TYPE_BITS 10
  39. // use the rle entropy coder
  40. #define RLECODER 1
  41. #include <tarkin.h>
  42. /*****************************************************************************
  43.  * decoder_sys_t : tarkin decoder descriptor
  44.  *****************************************************************************/
  45. struct decoder_sys_t
  46. {
  47.     /*
  48.      * Tarkin properties
  49.      */
  50.     TarkinStream *tarkin_stream;
  51.     TarkinInfo       ti;                        /* tarkin bitstream settings */
  52.     TarkinComment    tc;                   /* tarkin bitstream user comments */
  53.     TarkinTime       tarkdate;
  54.     int i_headers;
  55.     mtime_t i_pts;
  56. };
  57. /*****************************************************************************
  58.  * Local prototypes
  59.  *****************************************************************************/
  60. static int  OpenDecoder  ( vlc_object_t * );
  61. static void CloseDecoder ( vlc_object_t * );
  62. static void *DecodeBlock ( decoder_t *, block_t ** );
  63. static picture_t *DecodePacket ( decoder_t *, block_t **, ogg_packet * );
  64. static void tarkin_CopyPicture( decoder_t *, picture_t *, uint8_t *, int );
  65. /*****************************************************************************
  66.  * Module descriptor
  67.  *****************************************************************************/
  68. vlc_module_begin ()
  69.     set_description( N_("Tarkin decoder") )
  70.     set_capability( "decoder", 100 )
  71.     set_category( CAT_INPUT )
  72.     set_subcategory( SUBCAT_INPUT_VCODEC )
  73.     set_callbacks( OpenDecoder, CloseDecoder )
  74.     add_shortcut( "tarkin" )
  75. vlc_module_end ()
  76. /*****************************************************************************
  77.  * OpenDecoder: probe the decoder and return score
  78.  *****************************************************************************/
  79. static int OpenDecoder( vlc_object_t *p_this )
  80. {
  81.     decoder_t *p_dec = (decoder_t*)p_this;
  82.     decoder_sys_t *p_sys;
  83.     if( p_dec->fmt_in.i_codec != VLC_FOURCC('t','a','r','k') )
  84.     {
  85.         return VLC_EGENERIC;
  86.     }
  87.     /* Allocate the memory needed to store the decoder's structure */
  88.     if( ( p_dec->p_sys = p_sys =
  89.           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
  90.         return VLC_ENOMEM;
  91.     /* Set output properties */
  92.     p_dec->fmt_out.i_cat = VIDEO_ES;
  93.     p_sys->i_headers = 0;
  94.     /* Set callbacks */
  95.     p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
  96.         DecodeBlock;
  97.     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
  98.         DecodeBlock;
  99.     /* Init supporting Tarkin structures needed in header parsing */
  100.     p_sys->tarkin_stream = tarkin_stream_new();
  101.     tarkin_info_init( &p_sys->ti );
  102.     tarkin_comment_init( &p_sys->tc );
  103.     return VLC_SUCCESS;
  104. }
  105. /****************************************************************************
  106.  * DecodeBlock: the whole thing
  107.  ****************************************************************************
  108.  * This function must be fed with ogg packets.
  109.  ****************************************************************************/
  110. static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
  111. {
  112.     decoder_sys_t *p_sys = p_dec->p_sys;
  113.     block_t *p_block;
  114.     ogg_packet oggpacket;
  115.     if( !pp_block ) return NULL;
  116.     if( *pp_block )
  117.     {
  118.         /* Block to Ogg packet */
  119.         oggpacket.packet = (*pp_block)->p_buffer;
  120.         oggpacket.bytes = (*pp_block)->i_buffer;
  121.     }
  122.     else
  123.     {
  124.         /* Block to Ogg packet */
  125.         oggpacket.packet = NULL;
  126.         oggpacket.bytes = 0;
  127.     }
  128.     p_block = *pp_block;
  129.     oggpacket.granulepos = -1;
  130.     oggpacket.b_o_s = 0;
  131.     oggpacket.e_o_s = 0;
  132.     oggpacket.packetno = 0;
  133.     if( p_sys->i_headers == 0 )
  134.     {
  135.         /* Take care of the initial Tarkin header */
  136.         oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
  137.         if( tarkin_synthesis_headerin( &p_sys->ti, &p_sys->tc, &oggpacket )
  138.             < 0 )
  139.         {
  140.             msg_Err( p_dec, "this bitstream does not contain Tarkin "
  141.                      "video data.");
  142.             block_Release( p_block );
  143.             return NULL;
  144.         }
  145.         p_sys->i_headers++;
  146.         block_Release( p_block );
  147.         return NULL;
  148.     }
  149.     if( p_sys->i_headers == 1 )
  150.     {
  151.         if( tarkin_synthesis_headerin( &p_sys->ti, &p_sys->tc, &oggpacket )
  152.             < 0 )
  153.         {
  154.             msg_Err( p_dec, "2nd Tarkin header is corrupted." );
  155.             block_Release( p_block );
  156.             return NULL;
  157.         }
  158.         p_sys->i_headers++;
  159.         block_Release( p_block );
  160.         return NULL;
  161.     }
  162.     if( p_sys->i_headers == 2 )
  163.     {
  164.         if( tarkin_synthesis_headerin( &p_sys->ti, &p_sys->tc, &oggpacket )
  165.             < 0 )
  166.         {
  167.             msg_Err( p_dec, "3rd Tarkin header is corrupted." );
  168.             block_Release( p_block );
  169.             return NULL;
  170.         }
  171.         p_sys->i_headers++;
  172.         /* Initialize the tarkin decoder */
  173.         tarkin_synthesis_init( p_sys->tarkin_stream, &p_sys->ti );
  174.         msg_Err( p_dec, "Tarkin codec initialized");
  175.         block_Release( p_block );
  176.         return NULL;
  177.     }
  178.     return DecodePacket( p_dec, pp_block, &oggpacket );
  179. }
  180. /*****************************************************************************
  181.  * DecodePacket: decodes a Tarkin packet.
  182.  *****************************************************************************/
  183. static picture_t *DecodePacket( decoder_t *p_dec, block_t **pp_block,
  184.                                 ogg_packet *p_oggpacket )
  185. {
  186.     decoder_sys_t *p_sys = p_dec->p_sys;
  187.     uint8_t *rgb;
  188.     if( p_oggpacket->bytes )
  189.     {
  190.         tarkin_synthesis_packetin( p_sys->tarkin_stream, p_oggpacket );
  191.         //block_Release( *pp_block ); /* FIXME duplicate packet */
  192.         *pp_block = NULL;
  193.     }
  194.     if( tarkin_synthesis_frameout( p_sys->tarkin_stream,
  195.                                    &rgb, 0, &p_sys->tarkdate ) == 0 )
  196.     {
  197.         int i_width, i_height, i_chroma, i_stride;
  198.         picture_t *p_pic;
  199.         msg_Err( p_dec, "Tarkin frame decoded" );
  200.         i_width = p_sys->tarkin_stream->layer->desc.width;
  201.         i_height = p_sys->tarkin_stream->layer->desc.height;
  202.         switch( p_sys->tarkin_stream->layer->desc.format )
  203.         {
  204.         case TARKIN_RGB24:
  205.             i_chroma = VLC_FOURCC('R','V','2','4');
  206.             i_stride = i_width * 3;
  207.             break;
  208.         case TARKIN_RGB32:
  209.             i_chroma = VLC_FOURCC('R','V','3','2');
  210.             i_stride = i_width * 4;
  211.             break;
  212.         case TARKIN_RGBA:
  213.             i_chroma = VLC_FOURCC('R','G','B','A');
  214.             i_stride = i_width * 4;
  215.             break;
  216.         default:
  217.             i_chroma = VLC_FOURCC('I','4','2','0');
  218.             i_stride = i_width;
  219.             break;
  220.         }
  221.         /* Set output properties */
  222.         p_dec->fmt_out.video.i_width = i_width;
  223.         p_dec->fmt_out.video.i_height = i_height;
  224.         p_dec->fmt_out.video.i_aspect =
  225.             VOUT_ASPECT_FACTOR * i_width / i_height;
  226.         p_dec->fmt_out.i_codec = i_chroma;
  227.         /* Get a new picture */
  228.         if( (p_pic = decoder_NewPicture( p_dec )) )
  229.         {
  230.             tarkin_CopyPicture( p_dec, p_pic, rgb, i_stride );
  231.             tarkin_synthesis_freeframe( p_sys->tarkin_stream, rgb );
  232.             p_pic->date = mdate() + DEFAULT_PTS_DELAY/*i_pts*/;
  233.             return p_pic;
  234.         }
  235.     }
  236.     return NULL;
  237. }
  238. /*****************************************************************************
  239.  * CloseDecoder: tarkin decoder destruction
  240.  *****************************************************************************/
  241. static void CloseDecoder( vlc_object_t *p_this )
  242. {
  243.     decoder_t *p_dec = (decoder_t *)p_this;
  244.     decoder_sys_t *p_sys = p_dec->p_sys;
  245.     tarkin_stream_destroy( p_sys->tarkin_stream );
  246.     free( p_sys );
  247. }
  248. /*****************************************************************************
  249.  * tarkin_CopyPicture: copy a picture from tarkin internal buffers to a
  250.  *                     picture_t structure.
  251.  *****************************************************************************/
  252. static void tarkin_CopyPicture( decoder_t *p_dec, picture_t *p_pic,
  253.                                 uint8_t *p_src, int i_pitch )
  254. {
  255.     int i_plane, i_line, i_src_stride, i_dst_stride;
  256.     uint8_t *p_dst;
  257.     for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
  258.     {
  259.         p_dst = p_pic->p[i_plane].p_pixels;
  260.         i_dst_stride = p_pic->p[i_plane].i_pitch;
  261.         i_src_stride = i_pitch;
  262.         for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines; i_line++ )
  263.         {
  264.             vlc_memcpy( p_dst, p_src, i_src_stride );
  265.             p_src += i_src_stride;
  266.             p_dst += i_dst_stride;
  267.         }
  268.     }
  269. }