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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * svcdsub.c : Overlay Graphics Text (SVCD subtitles) decoder
  3.  *****************************************************************************
  4.  * Copyright (C) 2003, 2004 the VideoLAN team
  5.  * $Id: c6d9ee922994a75a407b306bfa63f081ea637010 $
  6.  *
  7.  * Authors: Rocky Bernstein
  8.  *          Gildas Bazin <gbazin@videolan.org>
  9.  *          Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
  10.  *          Laurent Aimar <fenrir@via.ecp.fr>
  11.  *
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2 of the License, or
  15.  * (at your option) any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; if not, write to the Free Software
  24.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  25.  *****************************************************************************/
  26. /*****************************************************************************
  27.  * Preamble
  28.  *****************************************************************************/
  29. #ifdef HAVE_CONFIG_H
  30. # include "config.h"
  31. #endif
  32. #include <vlc_common.h>
  33. #include <vlc_plugin.h>
  34. #include <vlc_codec.h>
  35. #include <vlc_osd.h>
  36. #include "vlc_bits.h"
  37. /*****************************************************************************
  38.  * Module descriptor.
  39.  *****************************************************************************/
  40. static int  DecoderOpen   ( vlc_object_t * );
  41. static int  PacketizerOpen( vlc_object_t * );
  42. static void DecoderClose  ( vlc_object_t * );
  43. #define DEBUG_TEXT N_("Enable debug")
  44. #define DEBUG_LONGTEXT  
  45.     N_("This integer when viewed in binary is a debugging maskn" 
  46.     "calls                 1n" 
  47.     "packet assembly info  2n" )
  48. vlc_module_begin ()
  49.     set_description( N_("Philips OGT (SVCD subtitle) decoder") )
  50.     set_shortname( N_("SVCD subtitles") )
  51.     set_category( CAT_INPUT )
  52.     set_subcategory( SUBCAT_INPUT_SCODEC )
  53.     set_capability( "decoder", 50 )
  54.     set_callbacks( DecoderOpen, DecoderClose )
  55.     add_integer ( MODULE_STRING "-debug", 0, NULL,
  56.                   DEBUG_TEXT, DEBUG_LONGTEXT, true )
  57.     add_submodule ()
  58.     set_description( N_("Philips OGT (SVCD subtitle) packetizer") )
  59.     set_capability( "packetizer", 50 )
  60.     set_callbacks( PacketizerOpen, DecoderClose )
  61. vlc_module_end ()
  62. /*****************************************************************************
  63.  * Local prototypes
  64.  *****************************************************************************/
  65. static subpicture_t *Decode( decoder_t *, block_t ** );
  66. static block_t *Packetize  ( decoder_t *, block_t ** );
  67. static block_t *Reassemble ( decoder_t *, block_t * );
  68. static void ParseHeader( decoder_t *, block_t * );
  69. static subpicture_t *DecodePacket( decoder_t *, block_t * );
  70. static void SVCDSubRenderImage( decoder_t *, block_t *, subpicture_region_t * );
  71. #define DECODE_DBG_CALL        1 /* calls */
  72. #define DECODE_DBG_PACKET      2 /* packet assembly info */
  73. #define GETINT16(p) ( (p[0] <<  8) +   p[1] )  ; p +=2;
  74. #define GETINT32(p) ( (p[0] << 24) +  (p[1] << 16) +    
  75.                       (p[2] <<  8) +  (p[3]) ) ; p += 4;
  76. typedef enum  {
  77.   SUBTITLE_BLOCK_EMPTY    = 0,
  78.   SUBTITLE_BLOCK_PARTIAL  = 1,
  79.   SUBTITLE_BLOCK_COMPLETE = 2
  80. } packet_state_t;
  81. #ifndef DECODE_DEBUG
  82. #define DECODE_DEBUG 1
  83. #endif
  84. #if DECODE_DEBUG
  85. #define dbg_print(mask, s, args...) 
  86.    if (p_sys && p_sys->i_debug & mask) 
  87.      msg_Dbg(p_dec, "%s: "s, __func__ , ##args)
  88. #else
  89. #define dbg_print(mask, s, args...)
  90. #endif
  91. struct decoder_sys_t
  92. {
  93.   int      i_debug;       /* debugging mask */
  94.   packet_state_t i_state; /* data-gathering state for this subtitle */
  95.   block_t  *p_spu;        /* Bytes of the packet. */
  96.   uint16_t i_image;       /* image number in the subtitle stream */
  97.   uint8_t  i_packet;      /* packet number for above image number */
  98.   size_t   i_spu_size;     /* goal for subtitle_data_pos while gathering,
  99.                              size of used subtitle_data later */
  100.   uint16_t i_image_offset;      /* offset from subtitle_data to compressed
  101.                                    image data */
  102.   size_t i_image_length;           /* size of the compressed image data */
  103.   size_t second_field_offset;      /* offset of odd raster lines */
  104.   size_t metadata_offset;          /* offset to data describing the image */
  105.   size_t metadata_length;          /* length of metadata */
  106.   mtime_t i_duration;   /* how long to display the image, 0 stands
  107.                            for "until next subtitle" */
  108.   uint16_t i_x_start, i_y_start; /* position of top leftmost pixel of
  109.                                     image when displayed */
  110.   uint16_t i_width, i_height;    /* dimensions in pixels of image */
  111.   uint8_t p_palette[4][4];       /* Palette of colors used in subtitle */
  112. };
  113. /*****************************************************************************
  114.  * DecoderOpen: open/initialize the svcdsub decoder.
  115.  *****************************************************************************/
  116. static int DecoderOpen( vlc_object_t *p_this )
  117. {
  118.     decoder_t     *p_dec = (decoder_t*)p_this;
  119.     decoder_sys_t *p_sys;
  120.     if( p_dec->fmt_in.i_codec != VLC_FOURCC( 'o','g','t',' ' ) )
  121.     {
  122.         return VLC_EGENERIC;
  123.     }
  124.     p_dec->p_sys = p_sys = calloc( 1, sizeof( decoder_sys_t ) );
  125.     if( p_sys == NULL )
  126.         return VLC_ENOMEM;
  127.     p_sys->i_debug       = config_GetInt( p_this, MODULE_STRING "-debug" );
  128.     p_sys->i_image       = -1;
  129.     p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
  130.     p_sys->p_spu   = NULL;
  131.     es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'o','g','t',' ' ) );
  132.     p_dec->pf_decode_sub = Decode;
  133.     p_dec->pf_packetize  = Packetize;
  134.     dbg_print( (DECODE_DBG_CALL) , "");
  135.     return VLC_SUCCESS;
  136. }
  137. /*****************************************************************************
  138.  * PacketizerOpen: open/initialize the svcdsub packetizer.
  139.  *****************************************************************************/
  140. static int PacketizerOpen( vlc_object_t *p_this )
  141. {
  142.     if( DecoderOpen( p_this ) != VLC_SUCCESS ) return VLC_EGENERIC;
  143.     return VLC_SUCCESS;
  144. }
  145. /*****************************************************************************
  146.  * DecoderClose: closes the svcdsub decoder/packetizer.
  147.  *****************************************************************************/
  148. void DecoderClose( vlc_object_t *p_this )
  149. {
  150.     decoder_t     *p_dec = (decoder_t*)p_this;
  151.     decoder_sys_t *p_sys = p_dec->p_sys;
  152.     if( p_sys->p_spu ) block_ChainRelease( p_sys->p_spu );
  153.     free( p_sys );
  154. }
  155. /*****************************************************************************
  156.  * Decode:
  157.  *****************************************************************************/
  158. static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
  159. {
  160.     block_t *p_block, *p_spu;
  161.     decoder_sys_t *p_sys = p_dec->p_sys;
  162.     dbg_print( (DECODE_DBG_CALL) , "");
  163.     if( pp_block == NULL || *pp_block == NULL ) return NULL;
  164.     p_block = *pp_block;
  165.     *pp_block = NULL;
  166.     if( !(p_spu = Reassemble( p_dec, p_block )) ) return NULL;
  167.     /* Parse and decode */
  168.     return DecodePacket( p_dec, p_spu );
  169. }
  170. /*****************************************************************************
  171.  * Packetize:
  172.  *****************************************************************************/
  173. static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
  174. {
  175.     block_t *p_block, *p_spu;
  176.     if( pp_block == NULL || *pp_block == NULL ) return NULL;
  177.     p_block = *pp_block;
  178.     *pp_block = NULL;
  179.     if( !(p_spu = Reassemble( p_dec, p_block )) ) return NULL;
  180.     p_spu->i_dts = p_spu->i_pts;
  181.     p_spu->i_length = 0;
  182.     return p_spu;
  183. }
  184. /*****************************************************************************
  185.  Reassemble:
  186.  The data for single screen subtitle may come in one of many
  187.  non-contiguous packets of a stream. This routine is called when the
  188.  next packet in the stream comes in. The job of this routine is to
  189.  parse the header, if this is the beginning, and combine the packets
  190.  into one complete subtitle unit.
  191.  If everything is complete, we will return a block. Otherwise return
  192.  NULL.
  193.  The format of the beginning of the subtitle packet that is used here.
  194.    size    description
  195.    -------------------------------------------
  196.    byte    subtitle channel (0..7) in bits 0-3
  197.    byte    subtitle packet number of this subtitle image 0-N,
  198.            if the subtitle packet is complete, the top bit of the byte is 1.
  199.    uint16  subtitle image number
  200.  *****************************************************************************/
  201. #define SPU_HEADER_LEN 5
  202. static block_t *Reassemble( decoder_t *p_dec, block_t *p_block )
  203. {
  204.     decoder_sys_t *p_sys = p_dec->p_sys;
  205.     uint8_t *p_buffer;
  206.     uint16_t i_expected_image;
  207.     uint8_t  i_packet, i_expected_packet;
  208.     if( p_block->i_buffer < SPU_HEADER_LEN )
  209.     {
  210.         msg_Dbg( p_dec, "invalid packet header (size %zu < %u)" ,
  211.                  p_block->i_buffer, SPU_HEADER_LEN );
  212.         block_Release( p_block );
  213.         return NULL;
  214.     }
  215.     p_buffer = p_block->p_buffer;
  216.     /* Attach to our input thread and see if subtitle is selected. */
  217.     {
  218.         vlc_object_t * p_input;
  219.         vlc_value_t val;
  220.         p_input = vlc_object_find( p_dec, VLC_OBJECT_INPUT, FIND_PARENT );
  221.         if( !p_input ) return NULL;
  222.         if( var_Get( p_input, "sub-track", &val ) )
  223.         {
  224.             vlc_object_release( p_input );
  225.             return NULL;
  226.         }
  227.         vlc_object_release( p_input );
  228.         dbg_print( (DECODE_DBG_PACKET),
  229.                    "val.i_int %x p_buffer[i] %x", val.i_int, p_buffer[1]);
  230.         /* The dummy ES that the menu selection uses has an 0x70 at
  231.            the head which we need to strip off. */
  232.         if( val.i_int == -1 || (val.i_int & 0x03) != p_buffer[1] )
  233.         {
  234.             dbg_print( DECODE_DBG_PACKET, "subtitle not for us.n");
  235.             return NULL;
  236.         }
  237.     }
  238.     if( p_sys->i_state == SUBTITLE_BLOCK_EMPTY )
  239.     {
  240.         i_expected_image  = p_sys->i_image + 1;
  241.         i_expected_packet = 0;
  242.     }
  243.     else
  244.     {
  245.         i_expected_image  = p_sys->i_image;
  246.         i_expected_packet = p_sys->i_packet + 1;
  247.     }
  248.     p_buffer += 2;
  249.     if( *p_buffer & 0x80 )
  250.     {
  251.         p_sys->i_state = SUBTITLE_BLOCK_COMPLETE;
  252.         i_packet       = *p_buffer++ & 0x7F;
  253.     }
  254.     else
  255.     {
  256.         p_sys->i_state = SUBTITLE_BLOCK_PARTIAL;
  257.         i_packet       = *p_buffer++;
  258.     }
  259.     p_sys->i_image = GETINT16(p_buffer);
  260.     if( p_sys->i_image != i_expected_image )
  261.     {
  262.         msg_Warn( p_dec, "expected subtitle image %u but found %u",
  263.                   i_expected_image, p_sys->i_image );
  264.     }
  265.     if( i_packet != i_expected_packet )
  266.     {
  267.         msg_Warn( p_dec, "expected subtitle image packet %u but found %u",
  268.                   i_expected_packet, i_packet );
  269.     }
  270.     p_block->p_buffer += SPU_HEADER_LEN;
  271.     p_block->i_buffer -= SPU_HEADER_LEN;
  272.     p_sys->i_packet = i_packet;
  273.     /* First packet in the subtitle block */
  274.     if( !p_sys->i_packet ) ParseHeader( p_dec, p_block );
  275.     block_ChainAppend( &p_sys->p_spu, p_block );
  276.     if( p_sys->i_state == SUBTITLE_BLOCK_COMPLETE )
  277.     {
  278.         block_t *p_spu = block_ChainGather( p_sys->p_spu );
  279.         if( p_spu->i_buffer != p_sys->i_spu_size )
  280.         {
  281.             msg_Warn( p_dec, "subtitle packets size=%zu should be %zu",
  282.                       p_spu->i_buffer, p_sys->i_spu_size );
  283.         }
  284.     dbg_print( (DECODE_DBG_PACKET),
  285.                  "subtitle packet complete, size=%zu", p_spu->i_buffer );
  286.         p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
  287.         p_sys->p_spu = 0;
  288.         return p_spu;
  289.     }
  290.     return NULL;
  291. }
  292. /******************************************************************************
  293.   The format is roughly as follows (everything is big-endian):
  294.  
  295.    size     description
  296.    -------------------------------------------
  297.    byte     subtitle channel (0..7) in bits 0-3
  298.    byte     subtitle packet number of this subtitle image 0-N,
  299.             if the subtitle packet is complete, the top bit of the byte is 1.
  300.    u_int16  subtitle image number
  301.    u_int16  length in bytes of the rest
  302.    byte     option flags, unknown meaning except bit 3 (0x08) indicates
  303.             presence of the duration field
  304.    byte     unknown
  305.    u_int32  duration in 1/90000ths of a second (optional), start time
  306.             is as indicated by the PTS in the PES header
  307.    u_int32  xpos
  308.    u_int32  ypos
  309.    u_int32  width (must be even)
  310.    u_int32  height (must be even)
  311.    byte[16] palette, 4 palette entries, each contains values for
  312.             Y, U, V and transparency, 0 standing for transparent
  313.    byte     command,
  314.             cmd>>6==1 indicates shift
  315.             (cmd>>4)&3 is direction from, (0=top,1=left,2=right,3=bottom)
  316.    u_int32  shift duration in 1/90000ths of a second
  317.    u_int16  offset of odd-numbered scanlines - subtitle images are
  318.             given in interlace order
  319.    byte[]   limited RLE image data in interlace order (0,2,4... 1,3,5) with
  320.             2-bits per palette number
  321. ******************************************************************************/
  322. static void ParseHeader( decoder_t *p_dec, block_t *p_block )
  323. {
  324.     decoder_sys_t *p_sys = p_dec->p_sys;
  325.     uint8_t *p = p_block->p_buffer;
  326.     uint8_t i_options, i_options2, i_cmd, i_cmd_arg;
  327.     int i;
  328.     p_sys->i_spu_size = GETINT16(p);
  329.     i_options  = *p++;
  330.     i_options2 = *p++;
  331.     if( i_options & 0x08 ) { p_sys->i_duration = GETINT32(p); }
  332.     else p_sys->i_duration = 0; /* Ephemer subtitle */
  333.     p_sys->i_duration *= 100 / 9;
  334.     p_sys->i_x_start = GETINT16(p);
  335.     p_sys->i_y_start = GETINT16(p);
  336.     p_sys->i_width   = GETINT16(p);
  337.     p_sys->i_height  = GETINT16(p);
  338.     for( i = 0; i < 4; i++ )
  339.     {
  340.         p_sys->p_palette[i][0] = *p++; /* Y */
  341.         p_sys->p_palette[i][2] = *p++; /* Cr / V */
  342.         p_sys->p_palette[i][1] = *p++; /* Cb / U */
  343.         p_sys->p_palette[i][3] = *p++; /* T */
  344.     }
  345.     i_cmd = *p++;
  346.     /* We do not really know this, FIXME */
  347.     if( i_cmd ) {i_cmd_arg = GETINT32(p);}
  348.     /* Actually, this is measured against a different origin, so we have to
  349.      * adjust it */
  350.     p_sys->second_field_offset = GETINT16(p);
  351.     p_sys->i_image_offset  = p - p_block->p_buffer;
  352.     p_sys->i_image_length  = p_sys->i_spu_size - p_sys->i_image_offset;
  353.     p_sys->metadata_length = p_sys->i_image_offset;
  354.   if( p_sys->i_debug & DECODE_DBG_PACKET )
  355.   {
  356.       msg_Dbg( p_dec, "x-start: %d, y-start: %d, width: %d, height %d, "
  357.            "spu size: %zu, duration: %"PRIu64" (d:%zu p:%"PRIu16")",
  358.            p_sys->i_x_start, p_sys->i_y_start,
  359.            p_sys->i_width, p_sys->i_height,
  360.            p_sys->i_spu_size, p_sys->i_duration,
  361.            p_sys->i_image_length, p_sys->i_image_offset);
  362.       for( i = 0; i < 4; i++ )
  363.       {
  364.           msg_Dbg( p_dec, "palette[%d]= T: %2x, Y: %2x, u: %2x, v: %2x", i,
  365.            p_sys->p_palette[i][3], p_sys->p_palette[i][0],
  366.            p_sys->p_palette[i][1], p_sys->p_palette[i][2] );
  367.       }
  368.   }
  369. }
  370. /*****************************************************************************
  371.  * DecodePacket: parse and decode an subtitle packet
  372.  *****************************************************************************
  373.  * This function parses and decodes an SPU packet and, if valid, returns a
  374.  * subpicture.
  375.  *****************************************************************************/
  376. static subpicture_t *DecodePacket( decoder_t *p_dec, block_t *p_data )
  377. {
  378.     decoder_sys_t *p_sys = p_dec->p_sys;
  379.     subpicture_t  *p_spu;
  380.     subpicture_region_t *p_region;
  381.     video_format_t fmt;
  382.     video_palette_t palette;
  383.     int i;
  384.     /* Allocate the subpicture internal data. */
  385.     p_spu = decoder_NewSubpicture( p_dec );
  386.     if( !p_spu ) return NULL;
  387.     p_spu->i_start = p_data->i_pts;
  388.     p_spu->i_stop  = p_data->i_pts + p_sys->i_duration;
  389.     p_spu->b_ephemer = true;
  390.     /* Create new subtitle region */
  391.     memset( &fmt, 0, sizeof(video_format_t) );
  392.     fmt.i_chroma = VLC_FOURCC('Y','U','V','P');
  393.     /**
  394.        The video on which the subtitle sits, is scaled, probably
  395.        4:3. However subtitle bitmaps assume an 1:1 aspect ratio.
  396.        FIXME: We should get the video aspect ratio from somewhere.
  397.        Two candidates are the video and the other possibility would be
  398.        the access module.
  399.     */
  400.     fmt.i_aspect = VOUT_ASPECT_FACTOR;
  401.     fmt.i_width = fmt.i_visible_width = p_sys->i_width;
  402.     fmt.i_height = fmt.i_visible_height = p_sys->i_height;
  403.     fmt.i_x_offset = fmt.i_y_offset = 0;
  404.     fmt.p_palette = &palette;
  405.     fmt.p_palette->i_entries = 4;
  406.     for( i = 0; i < fmt.p_palette->i_entries; i++ )
  407.     {
  408.         fmt.p_palette->palette[i][0] = p_sys->p_palette[i][0];
  409.         fmt.p_palette->palette[i][1] = p_sys->p_palette[i][1];
  410.         fmt.p_palette->palette[i][2] = p_sys->p_palette[i][2];
  411.         fmt.p_palette->palette[i][3] = p_sys->p_palette[i][3];
  412.     }
  413.     p_region = subpicture_region_New( &fmt );
  414.     if( !p_region )
  415.     {
  416.         msg_Err( p_dec, "cannot allocate SVCD subtitle region" );
  417.         decoder_DeleteSubpicture( p_dec, p_spu );
  418.         return NULL;
  419.     }
  420.     p_spu->p_region = p_region;
  421.     p_region->i_x = p_sys->i_x_start;
  422.     p_region->i_y = p_sys->i_y_start;
  423.     SVCDSubRenderImage( p_dec, p_data, p_region );
  424.     return p_spu;
  425. }
  426. /*****************************************************************************
  427.  * SVCDSubRenderImage: reorders bytes of image data in subpicture region.
  428.  *****************************************************************************
  429.  The image is encoded using two bits per pixel that select a palette
  430.  entry except that value 0 starts a limited run-length encoding for
  431.  color 0.  When 0 is seen, the next two bits encode one less than the
  432.  number of pixels, so we can encode run lengths from 1 to 4. These get
  433.  filled with the color in palette entry 0.
  434.  The encoding of each line is padded to a whole number of bytes.  The
  435.  first field is padded to an even byte length and the complete subtitle
  436.  is padded to a 4-byte multiple that always include one zero byte at
  437.  the end.
  438.  However we'll transform this so that that the RLE is expanded and
  439.  interlacing will also be removed.
  440.  *****************************************************************************/
  441. static void SVCDSubRenderImage( decoder_t *p_dec, block_t *p_data,
  442.                 subpicture_region_t *p_region )
  443. {
  444.     decoder_sys_t *p_sys = p_dec->p_sys;
  445.     uint8_t *p_dest = p_region->p_picture->Y_PIXELS;
  446.     int i_field;            /* The subtitles are interlaced */
  447.     int i_row, i_column;    /* scanline row/column number */
  448.     uint8_t i_color, i_count;
  449.     bs_t bs;
  450.     bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset,
  451.              p_data->i_buffer - p_sys->i_image_offset );
  452.     for( i_field = 0; i_field < 2; i_field++ )
  453.     {
  454.         for( i_row = i_field; i_row < p_sys->i_height; i_row += 2 )
  455.         {
  456.             for( i_column = 0; i_column < p_sys->i_width; i_column++ )
  457.             {
  458.                 i_color = bs_read( &bs, 2 );
  459.                 if( i_color == 0 && (i_count = bs_read( &bs, 2 )) )
  460.                 {
  461.                     i_count = __MIN( i_count, p_sys->i_width - i_column );
  462.                     memset( &p_dest[i_row * p_region->p_picture->Y_PITCH +
  463.                                     i_column], 0, i_count + 1 );
  464.                     i_column += i_count;
  465.                     continue;
  466.                 }
  467.                 p_dest[i_row * p_region->p_picture->Y_PITCH + i_column] = i_color;
  468.             }
  469.             bs_align( &bs );
  470.         }
  471.         /* odd field */
  472.         bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset +
  473.                  p_sys->second_field_offset,
  474.                  p_data->i_buffer - p_sys->i_image_offset -
  475.                  p_sys->second_field_offset );
  476.     }
  477. }