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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * fake.c : Fake video input for VLC
  3.  *****************************************************************************
  4.  * Copyright (C) 2005 the VideoLAN team
  5.  * $Id: 0cd8b09c1e1213b51c28e4e63d3b680fc176e9f7 $
  6.  *
  7.  * Author: Christophe Massiot <massiot@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_access.h>
  32. #include <vlc_demux.h>
  33. #include <vlc_image.h>
  34. /*****************************************************************************
  35.  * Module descriptior
  36.  *****************************************************************************/
  37. static int  Open ( vlc_object_t * );
  38. static void Close( vlc_object_t * );
  39. #define CACHING_TEXT N_("Caching value in ms")
  40. #define CACHING_LONGTEXT N_( 
  41.     "Caching value for fake streams. This " 
  42.     "value should be set in milliseconds." )
  43. #define FPS_TEXT N_("Framerate")
  44. #define FPS_LONGTEXT N_( 
  45.     "Number of frames per second (eg. 24, 25, 29.97, 30).")
  46. #define ID_TEXT N_("ID")
  47. #define ID_LONGTEXT N_( 
  48.     "Set the ID of the fake elementary stream for use in " 
  49.     "#duplicate{} constructs (default 0).")
  50. #define DURATION_TEXT N_("Duration in ms")
  51. #define DURATION_LONGTEXT N_( 
  52.     "Duration of the fake streaming before faking an " 
  53.     "end-of-file (default is -1 meaning that the stream is unlimited when " 
  54.     "fake is forced, or lasts for 10 seconds otherwise. 0, means that the " 
  55.     "stream is unlimited).")
  56. vlc_module_begin ()
  57.     set_shortname( N_("Fake") )
  58.     set_description( N_("Fake input") )
  59.     set_category( CAT_INPUT )
  60.     set_subcategory( SUBCAT_INPUT_ACCESS )
  61.     add_integer( "fake-caching", DEFAULT_PTS_DELAY / 1000, NULL,
  62.                  CACHING_TEXT, CACHING_LONGTEXT, true )
  63.     add_float( "fake-fps", 25.0, NULL, FPS_TEXT, FPS_LONGTEXT, true )
  64.     add_integer( "fake-id", 0, NULL, ID_TEXT, ID_LONGTEXT, true )
  65.     add_integer( "fake-duration", -1, NULL, DURATION_TEXT, DURATION_LONGTEXT,
  66.                  true )
  67.     add_shortcut( "fake" )
  68.     set_capability( "access_demux", 10 )
  69.     set_callbacks( Open, Close )
  70. vlc_module_end ()
  71. /*****************************************************************************
  72.  * Access: local prototypes
  73.  *****************************************************************************/
  74. static int Demux  ( demux_t * );
  75. static int Control( demux_t *, int, va_list );
  76. struct demux_sys_t
  77. {
  78.     float f_fps;
  79.     mtime_t i_last_pts, i_duration, i_first_pts, i_end_pts, i_pause_pts;
  80.     es_out_id_t  *p_es_video;
  81. };
  82. /*****************************************************************************
  83.  * Open: opens fake device
  84.  *****************************************************************************/
  85. static int Open( vlc_object_t *p_this )
  86. {
  87.     demux_t     *p_demux = (demux_t*)p_this;
  88.     demux_sys_t *p_sys;
  89.     es_format_t fmt;
  90.     if( *p_demux->psz_access != '' )
  91.     {
  92.         /* if an access is provided, then it has to be "fake" */
  93.         if( strcmp( p_demux->psz_access, "fake" ) )
  94.             return VLC_EGENERIC;
  95.         msg_Dbg( p_demux, "fake:// access_demux detected" );
  96.     }
  97.     else
  98.     {
  99.        /**
  100.         * access is not provided,
  101.         * then let's see if path could be an image
  102.         **/
  103.         if( !p_demux->psz_path || !*p_demux->psz_path )
  104.             return VLC_EGENERIC;
  105.         vlc_fourcc_t i_codec = image_Ext2Fourcc( p_demux->psz_path );
  106.         if( !i_codec )
  107.             return VLC_EGENERIC;
  108.         msg_Dbg( p_demux, "still image detected with codec format %4.4s",
  109.                  (const char*)&i_codec );
  110.     }
  111.     if( p_demux->psz_path && *p_demux->psz_path )
  112.     {
  113.         /* set up fake-file on the fly */
  114.         var_Create( p_demux->p_parent, "fake-file", VLC_VAR_STRING );
  115.         var_SetString( p_demux->p_parent, "fake-file", p_demux->psz_path );
  116.     }
  117.     /* Set up p_demux */
  118.     DEMUX_INIT_COMMON(); p_sys = p_demux->p_sys;
  119.     p_demux->info.i_update = 0;
  120.     p_demux->info.i_title = 0;
  121.     p_demux->info.i_seekpoint = 0;
  122.     p_sys->i_duration =
  123.         (mtime_t)var_CreateGetInteger( p_demux, "fake-duration" ) * 1000;
  124.     if( p_sys->i_duration < 0 )
  125.     {
  126.         if( !strcmp( p_demux->psz_access, "fake" ) )
  127.             p_sys->i_duration = 0;
  128.         else
  129.             p_sys->i_duration = 10000*1000;
  130.     }
  131.     p_sys->f_fps = var_CreateGetFloat( p_demux, "fake-fps" );
  132.     /* Declare the elementary stream */
  133.     es_format_Init( &fmt, VIDEO_ES, VLC_FOURCC('f','a','k','e') );
  134.     fmt.i_id = var_CreateGetInteger( p_demux, "fake-id" );
  135.     p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );
  136.     /* Update default_pts to a suitable value for access */
  137.     var_Create( p_demux, "fake-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
  138.     return VLC_SUCCESS;
  139. }
  140. /*****************************************************************************
  141.  * Close: close device, free resources
  142.  *****************************************************************************/
  143. static void Close( vlc_object_t *p_this )
  144. {
  145.     demux_t     *p_demux = (demux_t *)p_this;
  146.     demux_sys_t *p_sys   = p_demux->p_sys;
  147.     free( p_sys );
  148. }
  149. /*****************************************************************************
  150.  * Control:
  151.  *****************************************************************************/
  152. static int Control( demux_t *p_demux, int i_query, va_list args )
  153. {
  154.     demux_sys_t *p_sys = p_demux->p_sys;
  155.     bool *pb, b;
  156.     int64_t    *pi64, i64;
  157.     double     *pf, f;
  158.     switch( i_query )
  159.     {
  160.         /* Special for access_demux */
  161.         case DEMUX_CAN_PAUSE:
  162.         case DEMUX_CAN_SEEK:
  163.         case DEMUX_CAN_CONTROL_PACE:
  164.             pb = (bool *)va_arg( args, bool * );
  165.             *pb = true;
  166.             return VLC_SUCCESS;
  167.         case DEMUX_SET_PAUSE_STATE:
  168.             b = (bool)va_arg( args, int );
  169.             if ( b )
  170.             {
  171.                 p_sys->i_pause_pts = mdate();
  172.             }
  173.             else if ( p_sys->i_pause_pts )
  174.             {
  175.                 mtime_t i_pause_duration = mdate() - p_sys->i_pause_pts;
  176.                 p_sys->i_first_pts += i_pause_duration;
  177.                 p_sys->i_last_pts += i_pause_duration;
  178.                 if ( p_sys->i_duration )
  179.                     p_sys->i_end_pts += i_pause_duration;
  180.                 p_sys->i_pause_pts = 0;
  181.             }
  182.             return VLC_SUCCESS;
  183.         case DEMUX_GET_PTS_DELAY:
  184.             pi64 = (int64_t *)va_arg( args, int64_t * );
  185.             *pi64 = (int64_t)var_GetInteger( p_demux, "fake-caching" ) * 1000;
  186.             return VLC_SUCCESS;
  187.         case DEMUX_GET_POSITION:
  188.             if( p_sys->i_duration <= 0 )
  189.                 return VLC_EGENERIC;
  190.             pf = (double*)va_arg( args, double* );
  191.             *pf = (double)( p_sys->i_last_pts - p_sys->i_first_pts )
  192.                             / (double)(p_sys->i_duration);
  193.             return VLC_SUCCESS;
  194.         case DEMUX_SET_POSITION:
  195.             if( p_sys->i_duration <= 0 )
  196.                 return VLC_EGENERIC;
  197.             f = (double)va_arg( args, double );
  198.             i64 = f * (double)p_sys->i_duration;
  199.             p_sys->i_first_pts = p_sys->i_last_pts - i64;
  200.             p_sys->i_end_pts = p_sys->i_first_pts + p_sys->i_duration;
  201.             return VLC_SUCCESS;
  202.         case DEMUX_GET_TIME:
  203.             pi64 = (int64_t *)va_arg( args, int64_t * );
  204.             *pi64 = p_sys->i_last_pts - p_sys->i_first_pts;
  205.             return VLC_SUCCESS;
  206.         case DEMUX_GET_LENGTH:
  207.             if( p_sys->i_duration <= 0 )
  208.                 return VLC_EGENERIC;
  209.             pi64 = (int64_t*)va_arg( args, int64_t * );
  210.             *pi64 = p_sys->i_duration;
  211.             return VLC_SUCCESS;
  212.         case DEMUX_SET_TIME:
  213.             i64 = (int64_t)va_arg( args, int64_t );
  214.             p_sys->i_first_pts = p_sys->i_last_pts - i64;
  215.             p_sys->i_end_pts = p_sys->i_first_pts + p_sys->i_duration;
  216.             return VLC_SUCCESS;
  217.         /* TODO implement others */
  218.         default:
  219.             return VLC_EGENERIC;
  220.     }
  221.     return VLC_EGENERIC;
  222. }
  223. /*****************************************************************************
  224.  * Demux:
  225.  *****************************************************************************/
  226. static int Demux( demux_t *p_demux )
  227. {
  228.     demux_sys_t *p_sys = p_demux->p_sys;
  229.     if ( !p_sys->i_last_pts )
  230.     {
  231.         p_sys->i_last_pts = p_sys->i_first_pts = mdate();
  232.         if ( p_sys->i_duration )
  233.             p_sys->i_end_pts = p_sys->i_first_pts + p_sys->i_duration;
  234.     }
  235.     else
  236.     {
  237.         p_sys->i_last_pts += (mtime_t)(1000000.0 / p_sys->f_fps);
  238.         if ( p_sys->i_duration && p_sys->i_last_pts > p_sys->i_end_pts )
  239.             return 0;
  240.         mwait( p_sys->i_last_pts );
  241.     }
  242.     block_t *p_block = block_New( p_demux, 1 );
  243.     p_block->i_flags |= BLOCK_FLAG_TYPE_I;
  244.     p_block->i_dts = p_block->i_pts = p_sys->i_last_pts;
  245.     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
  246.     es_out_Send( p_demux->out, p_sys->p_es_video, p_block );
  247.     return 1;
  248. }