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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * gather.c: gathering stream output module
  3.  *****************************************************************************
  4.  * Copyright (C) 2003-2004 the VideoLAN team
  5.  * $Id: 41778d7cb4268fb3b347579296431416e5de17fa $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  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_input.h>
  32. #include <vlc_sout.h>
  33. /*****************************************************************************
  34.  * Module descriptor
  35.  *****************************************************************************/
  36. static int      Open    ( vlc_object_t * );
  37. static void     Close   ( vlc_object_t * );
  38. vlc_module_begin ()
  39.     set_description( N_("Gathering stream output") )
  40.     set_capability( "sout stream", 50 )
  41.     add_shortcut( "gather" )
  42.     set_callbacks( Open, Close )
  43. vlc_module_end ()
  44. /*****************************************************************************
  45.  * Exported prototypes
  46.  *****************************************************************************/
  47. static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
  48. static int               Del ( sout_stream_t *, sout_stream_id_t * );
  49. static int               Send( sout_stream_t *, sout_stream_id_t *, block_t* );
  50. struct sout_stream_id_t
  51. {
  52.     bool    b_used;
  53.     es_format_t fmt;
  54.     void          *id;
  55. };
  56. struct sout_stream_sys_t
  57. {
  58.     sout_stream_t   *p_out;
  59.     int              i_id;
  60.     sout_stream_id_t **id;
  61. };
  62. /*****************************************************************************
  63.  * Open:
  64.  *****************************************************************************/
  65. static int Open( vlc_object_t *p_this )
  66. {
  67.     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
  68.     sout_stream_sys_t *p_sys;
  69.     p_stream->p_sys = p_sys = malloc( sizeof( sout_stream_sys_t ) );
  70.     if( p_sys == NULL )
  71.         return VLC_EGENERIC;
  72.     p_sys->p_out    = sout_StreamNew( p_stream->p_sout, p_stream->psz_next );
  73.     if( p_sys->p_out == NULL )
  74.     {
  75.         free( p_sys );
  76.         return VLC_EGENERIC;
  77.     }
  78.     p_stream->pf_add    = Add;
  79.     p_stream->pf_del    = Del;
  80.     p_stream->pf_send   = Send;
  81.     TAB_INIT( p_sys->i_id, p_sys->id );
  82.     return VLC_SUCCESS;
  83. }
  84. /*****************************************************************************
  85.  * Close:
  86.  *****************************************************************************/
  87. static void Close( vlc_object_t * p_this )
  88. {
  89.     sout_stream_t     *p_stream = (sout_stream_t*)p_this;
  90.     sout_stream_sys_t *p_sys = p_stream->p_sys;
  91.     int i;
  92.     for( i = 0; i < p_sys->i_id; i++ )
  93.     {
  94.         sout_stream_id_t *id = p_sys->id[i];
  95.         sout_StreamIdDel( p_sys->p_out, id->id );
  96.         es_format_Clean( &id->fmt );
  97.         free( id );
  98.     }
  99.     TAB_CLEAN( p_sys->i_id, p_sys->id );
  100.     sout_StreamDelete( p_sys->p_out );
  101.     free( p_sys );
  102. }
  103. /*****************************************************************************
  104.  * Add:
  105.  *****************************************************************************/
  106. static sout_stream_id_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt )
  107. {
  108.     sout_stream_sys_t *p_sys = p_stream->p_sys;
  109.     sout_stream_id_t  *id;
  110.     int i;
  111.     /* search a compatible output */
  112.     for( i = 0; i < p_sys->i_id; i++ )
  113.     {
  114.         id = p_sys->id[i];
  115.         if( id->b_used )
  116.             continue;
  117.         if( id->fmt.i_cat != p_fmt->i_cat || id->fmt.i_codec != p_fmt->i_codec )
  118.             continue;
  119.         if( id->fmt.i_cat == AUDIO_ES )
  120.         {
  121.             audio_format_t *p_a = &id->fmt.audio;
  122.             if( p_a->i_rate != p_fmt->audio.i_rate ||
  123.                 p_a->i_channels != p_fmt->audio.i_channels ||
  124.                 p_a->i_blockalign != p_fmt->audio.i_blockalign )
  125.                 continue;
  126.         }
  127.         else if( id->fmt.i_cat == VIDEO_ES )
  128.         {
  129.             video_format_t *p_v = &id->fmt.video;
  130.             if( p_v->i_width != p_fmt->video.i_width ||
  131.                 p_v->i_height != p_fmt->video.i_height )
  132.                 continue;
  133.         }
  134.         /* */
  135.         msg_Dbg( p_stream, "reusing already opened output" );
  136.         id->b_used = true;
  137.         return id;
  138.     }
  139.     /* destroy all outputs from the same category */
  140.     for( i = 0; i < p_sys->i_id; i++ )
  141.     {
  142.         id = p_sys->id[i];
  143.         if( !id->b_used && id->fmt.i_cat == p_fmt->i_cat )
  144.         {
  145.             TAB_REMOVE( p_sys->i_id, p_sys->id, id );
  146.             sout_StreamIdDel( p_sys->p_out, id->id );
  147.             es_format_Clean( &id->fmt );
  148.             free( id );
  149.             i = 0;
  150.             continue;
  151.         }
  152.     }
  153.     msg_Dbg( p_stream, "creating new output" );
  154.     id = malloc( sizeof( sout_stream_id_t ) );
  155.     if( id == NULL )
  156.         return NULL;
  157.     es_format_Copy( &id->fmt, p_fmt );
  158.     id->b_used           = true;
  159.     id->id               = sout_StreamIdAdd( p_sys->p_out, &id->fmt );
  160.     if( id->id == NULL )
  161.     {
  162.         free( id );
  163.         return NULL;
  164.     }
  165.     TAB_APPEND( p_sys->i_id, p_sys->id, id );
  166.     return id;
  167. }
  168. /*****************************************************************************
  169.  * Del:
  170.  *****************************************************************************/
  171. static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
  172. {
  173.     VLC_UNUSED(p_stream);
  174.     id->b_used = false;
  175.     return VLC_SUCCESS;
  176. }
  177. /*****************************************************************************
  178.  * Send:
  179.  *****************************************************************************/
  180. static int Send( sout_stream_t *p_stream,
  181.                  sout_stream_id_t *id, block_t *p_buffer )
  182. {
  183.     sout_stream_sys_t *p_sys = p_stream->p_sys;
  184.     return sout_StreamIdSend( p_sys->p_out, id->id, p_buffer );
  185. }