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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * control.c
  3.  *****************************************************************************
  4.  * Copyright (C) 1999-2004 the VideoLAN team
  5.  * $Id: 8cf6addf5fee5f334718bcb2502bd55f1e10038d $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@videolan.org>
  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. #ifdef HAVE_CONFIG_H
  24. # include "config.h"
  25. #endif
  26. #include <vlc_common.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include "input_internal.h"
  30. #include "event.h"
  31. #include "resource.h"
  32. static void UpdateBookmarksOption( input_thread_t * );
  33. /****************************************************************************
  34.  * input_Control
  35.  ****************************************************************************/
  36. /**
  37.  * Control function for inputs.
  38.  * param p_input input handle
  39.  * param i_query query type
  40.  * return VLC_SUCCESS if ok
  41.  */
  42. int input_Control( input_thread_t *p_input, int i_query, ...  )
  43. {
  44.     va_list args;
  45.     int     i_result;
  46.     va_start( args, i_query );
  47.     i_result = input_vaControl( p_input, i_query, args );
  48.     va_end( args );
  49.     return i_result;
  50. }
  51. int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
  52. {
  53.     seekpoint_t *p_bkmk, ***ppp_bkmk;
  54.     int i_bkmk = 0;
  55.     int *pi_bkmk;
  56.     int i_int, *pi_int;
  57.     bool b_bool, *pb_bool;
  58.     double f, *pf;
  59.     int64_t i_64, *pi_64;
  60.     char *psz;
  61.     vlc_value_t val;
  62.     switch( i_query )
  63.     {
  64.         case INPUT_GET_POSITION:
  65.             pf = (double*)va_arg( args, double * );
  66.             *pf = var_GetFloat( p_input, "position" );
  67.             return VLC_SUCCESS;
  68.         case INPUT_SET_POSITION:
  69.             f = (double)va_arg( args, double );
  70.             return var_SetFloat( p_input, "position", f );
  71.         case INPUT_GET_LENGTH:
  72.             pi_64 = (int64_t*)va_arg( args, int64_t * );
  73.             *pi_64 = var_GetTime( p_input, "length" );
  74.             return VLC_SUCCESS;
  75.         case INPUT_GET_TIME:
  76.             pi_64 = (int64_t*)va_arg( args, int64_t * );
  77.             *pi_64 = var_GetTime( p_input, "time" );
  78.             return VLC_SUCCESS;
  79.         case INPUT_SET_TIME:
  80.             i_64 = (int64_t)va_arg( args, int64_t );
  81.             return var_SetTime( p_input, "time", i_64 );
  82.         case INPUT_GET_RATE:
  83.             pi_int = (int*)va_arg( args, int * );
  84.             *pi_int = var_GetInteger( p_input, "rate" );
  85.             return VLC_SUCCESS;
  86.         case INPUT_SET_RATE:
  87.             i_int = (int)va_arg( args, int );
  88.             return var_SetInteger( p_input, "rate", i_int );
  89.         case INPUT_GET_STATE:
  90.             pi_int = (int*)va_arg( args, int * );
  91.             *pi_int = var_GetInteger( p_input, "state" );
  92.             return VLC_SUCCESS;
  93.         case INPUT_SET_STATE:
  94.             i_int = (int)va_arg( args, int );
  95.             return var_SetInteger( p_input, "state", i_int );
  96.         case INPUT_GET_AUDIO_DELAY:
  97.             pi_64 = (int64_t*)va_arg( args, int64_t * );
  98.             *pi_64 = var_GetTime( p_input, "audio-delay" );
  99.             return VLC_SUCCESS;
  100.         case INPUT_GET_SPU_DELAY:
  101.             pi_64 = (int64_t*)va_arg( args, int64_t * );
  102.             *pi_64 = var_GetTime( p_input, "spu-delay" );
  103.             return VLC_SUCCESS;
  104.         case INPUT_SET_AUDIO_DELAY:
  105.             i_64 = (int64_t)va_arg( args, int64_t );
  106.             return var_SetTime( p_input, "audio-delay", i_64 );
  107.         case INPUT_SET_SPU_DELAY:
  108.             i_64 = (int64_t)va_arg( args, int64_t );
  109.             return var_SetTime( p_input, "spu-delay", i_64 );
  110.         case INPUT_ADD_INFO:
  111.         {
  112.             char *psz_cat = (char *)va_arg( args, char * );
  113.             char *psz_name = (char *)va_arg( args, char * );
  114.             char *psz_format = (char *)va_arg( args, char * );
  115.             char *psz_value;
  116.             
  117.             if( vasprintf( &psz_value, psz_format, args ) == -1 )
  118.                 return VLC_EGENERIC;
  119.             int i_ret = input_item_AddInfo( p_input->p->p_item,
  120.                                             psz_cat, psz_name, "%s", psz_value );
  121.             free( psz_value );
  122.             if( !p_input->b_preparsing && !i_ret )
  123.                 input_SendEventMetaInfo( p_input );
  124.             return i_ret;
  125.         }
  126.         case INPUT_DEL_INFO:
  127.         {
  128.             char *psz_cat = (char *)va_arg( args, char * );
  129.             char *psz_name = (char *)va_arg( args, char * );
  130.             int i_ret = input_item_DelInfo( p_input->p->p_item,
  131.                                             psz_cat, psz_name );
  132.             if( !p_input->b_preparsing && !i_ret )
  133.                 input_SendEventMetaInfo( p_input );
  134.             return i_ret;
  135.         }
  136.         case INPUT_GET_INFO:
  137.         {
  138.             char *psz_cat = (char *)va_arg( args, char * );
  139.             char *psz_name = (char *)va_arg( args, char * );
  140.             char **ppsz_value = (char **)va_arg( args, char ** );
  141.             int i_ret = VLC_EGENERIC;
  142.             *ppsz_value = NULL;
  143.             *ppsz_value = input_item_GetInfo( p_input->p->p_item,
  144.                                                   psz_cat, psz_name );
  145.             return i_ret;
  146.         }
  147.         case INPUT_SET_NAME:
  148.         {
  149.             char *psz_name = (char *)va_arg( args, char * );
  150.             if( !psz_name ) return VLC_EGENERIC;
  151.             input_item_SetName( p_input->p->p_item, psz_name );
  152.             if( !p_input->b_preparsing )
  153.                 input_SendEventMetaName( p_input, psz_name );
  154.             return VLC_SUCCESS;
  155.         }
  156.         case INPUT_ADD_BOOKMARK:
  157.             p_bkmk = (seekpoint_t *)va_arg( args, seekpoint_t * );
  158.             p_bkmk = vlc_seekpoint_Duplicate( p_bkmk );
  159.             vlc_mutex_lock( &p_input->p->p_item->lock );
  160.             if( !p_bkmk->psz_name )
  161.             {
  162.                  if( asprintf( &p_bkmk->psz_name, _("Bookmark %i"),
  163.                                p_input->p->i_bookmark ) == -1 )
  164.                      p_bkmk->psz_name = NULL;
  165.             }
  166.             TAB_APPEND( p_input->p->i_bookmark, p_input->p->pp_bookmark, p_bkmk );
  167.             vlc_mutex_unlock( &p_input->p->p_item->lock );
  168.             UpdateBookmarksOption( p_input );
  169.             return VLC_SUCCESS;
  170.         case INPUT_CHANGE_BOOKMARK:
  171.             p_bkmk = (seekpoint_t *)va_arg( args, seekpoint_t * );
  172.             i_bkmk = (int)va_arg( args, int );
  173.             vlc_mutex_lock( &p_input->p->p_item->lock );
  174.             if( i_bkmk < p_input->p->i_bookmark )
  175.             {
  176.                 vlc_seekpoint_Delete( p_input->p->pp_bookmark[i_bkmk] );
  177.                 p_input->p->pp_bookmark[i_bkmk] = vlc_seekpoint_Duplicate( p_bkmk );
  178.             }
  179.             vlc_mutex_unlock( &p_input->p->p_item->lock );
  180.             UpdateBookmarksOption( p_input );
  181.             return VLC_SUCCESS;
  182.         case INPUT_DEL_BOOKMARK:
  183.             i_bkmk = (int)va_arg( args, int );
  184.             vlc_mutex_lock( &p_input->p->p_item->lock );
  185.             if( i_bkmk < p_input->p->i_bookmark )
  186.             {
  187.                 p_bkmk = p_input->p->pp_bookmark[i_bkmk];
  188.                 TAB_REMOVE( p_input->p->i_bookmark, p_input->p->pp_bookmark, p_bkmk );
  189.                 vlc_seekpoint_Delete( p_bkmk );
  190.                 vlc_mutex_unlock( &p_input->p->p_item->lock );
  191.                 UpdateBookmarksOption( p_input );
  192.                 return VLC_SUCCESS;
  193.             }
  194.             vlc_mutex_unlock( &p_input->p->p_item->lock );
  195.             return VLC_EGENERIC;
  196.         case INPUT_GET_BOOKMARKS:
  197.             ppp_bkmk = (seekpoint_t ***)va_arg( args, seekpoint_t *** );
  198.             pi_bkmk = (int *)va_arg( args, int * );
  199.             vlc_mutex_lock( &p_input->p->p_item->lock );
  200.             if( p_input->p->i_bookmark )
  201.             {
  202.                 int i;
  203.                 *pi_bkmk = p_input->p->i_bookmark;
  204.                 *ppp_bkmk = malloc( sizeof(seekpoint_t *) *
  205.                                     p_input->p->i_bookmark );
  206.                 for( i = 0; i < p_input->p->i_bookmark; i++ )
  207.                 {
  208.                     (*ppp_bkmk)[i] =
  209.                         vlc_seekpoint_Duplicate( p_input->p->pp_bookmark[i] );
  210.                 }
  211.                 vlc_mutex_unlock( &p_input->p->p_item->lock );
  212.                 return VLC_SUCCESS;
  213.             }
  214.             else
  215.             {
  216.                 *ppp_bkmk = NULL;
  217.                 *pi_bkmk = 0;
  218.                 vlc_mutex_unlock( &p_input->p->p_item->lock );
  219.                 return VLC_EGENERIC;
  220.             }
  221.             break;
  222.         case INPUT_CLEAR_BOOKMARKS:
  223.             vlc_mutex_lock( &p_input->p->p_item->lock );
  224.             while( p_input->p->i_bookmark > 0 )
  225.             {
  226.                 p_bkmk = p_input->p->pp_bookmark[p_input->p->i_bookmark-1];
  227.                 TAB_REMOVE( p_input->p->i_bookmark, p_input->p->pp_bookmark,
  228.                             p_bkmk );
  229.                 vlc_seekpoint_Delete( p_bkmk );
  230.             }
  231.             vlc_mutex_unlock( &p_input->p->p_item->lock );
  232.             UpdateBookmarksOption( p_input );
  233.             return VLC_SUCCESS;
  234.         case INPUT_SET_BOOKMARK:
  235.             i_bkmk = (int)va_arg( args, int );
  236.             val.i_int = i_bkmk;
  237.             input_ControlPush( p_input, INPUT_CONTROL_SET_BOOKMARK, &val );
  238.             return VLC_SUCCESS;
  239.         case INPUT_GET_BOOKMARK:
  240.             p_bkmk = (seekpoint_t *)va_arg( args, seekpoint_t * );
  241.             vlc_mutex_lock( &p_input->p->p_item->lock );
  242.             *p_bkmk = p_input->p->bookmark;
  243.             vlc_mutex_unlock( &p_input->p->p_item->lock );
  244.             return VLC_SUCCESS;
  245.         case INPUT_ADD_OPTION:
  246.         {
  247.             const char *psz_option = va_arg( args, const char * );
  248.             const char *psz_value = va_arg( args, const char * );
  249.             char *str;
  250.             int i;
  251.             if( asprintf( &str, "%s=%s", psz_option, psz_value ) == -1 )
  252.                 return VLC_ENOMEM;
  253.             i = input_item_AddOption( p_input->p->p_item, str,
  254.                                       VLC_INPUT_OPTION_UNIQUE );
  255.             free( str );
  256.             return i;
  257.         }
  258.         case INPUT_GET_VIDEO_FPS:
  259.             pf = (double*)va_arg( args, double * );
  260.             vlc_mutex_lock( &p_input->p->p_item->lock );
  261.             *pf = p_input->p->f_fps;
  262.             vlc_mutex_unlock( &p_input->p->p_item->lock );
  263.             return VLC_SUCCESS;
  264.         case INPUT_ADD_SLAVE:
  265.             psz = (char*)va_arg( args, char * );
  266.             if( psz && *psz )
  267.             {
  268.                 val.psz_string = strdup( psz );
  269.                 input_ControlPush( p_input, INPUT_CONTROL_ADD_SLAVE, &val );
  270.             }
  271.             return VLC_SUCCESS;
  272.         case INPUT_ADD_SUBTITLE:
  273.             psz = (char*)va_arg( args, char * );
  274.             b_bool = (bool)va_arg( args, int );
  275.             if( !psz || *psz == '' )
  276.                 return VLC_EGENERIC;
  277.             if( b_bool && !subtitles_Filter( psz ) )
  278.                 return VLC_EGENERIC;
  279.             val.psz_string = strdup( psz );
  280.             input_ControlPush( p_input, INPUT_CONTROL_ADD_SUBTITLE, &val );
  281.             return VLC_SUCCESS;
  282.         case INPUT_GET_ATTACHMENTS: /* arg1=input_attachment_t***, arg2=int*  res=can fail */
  283.         {
  284.             input_attachment_t ***ppp_attachment = (input_attachment_t***)va_arg( args, input_attachment_t *** );
  285.             int *pi_attachment = (int*)va_arg( args, int * );
  286.             int i;
  287.             vlc_mutex_lock( &p_input->p->p_item->lock );
  288.             if( p_input->p->i_attachment <= 0 )
  289.             {
  290.                 vlc_mutex_unlock( &p_input->p->p_item->lock );
  291.                 *ppp_attachment = NULL;
  292.                 *pi_attachment = 0;
  293.                 return VLC_EGENERIC;
  294.             }
  295.             *pi_attachment = p_input->p->i_attachment;
  296.             *ppp_attachment = malloc( sizeof(input_attachment_t**) * p_input->p->i_attachment );
  297.             for( i = 0; i < p_input->p->i_attachment; i++ )
  298.                 (*ppp_attachment)[i] = vlc_input_attachment_Duplicate( p_input->p->attachment[i] );
  299.             vlc_mutex_unlock( &p_input->p->p_item->lock );
  300.             return VLC_SUCCESS;
  301.         }
  302.         case INPUT_GET_ATTACHMENT:  /* arg1=input_attachment_t**, arg2=char*  res=can fail */
  303.         {
  304.             input_attachment_t **pp_attachment = (input_attachment_t**)va_arg( args, input_attachment_t ** );
  305.             const char *psz_name = (const char*)va_arg( args, const char * );
  306.             int i;
  307.             vlc_mutex_lock( &p_input->p->p_item->lock );
  308.             for( i = 0; i < p_input->p->i_attachment; i++ )
  309.             {
  310.                 if( !strcmp( p_input->p->attachment[i]->psz_name, psz_name ) )
  311.                 {
  312.                     *pp_attachment = vlc_input_attachment_Duplicate( p_input->p->attachment[i] );
  313.                     vlc_mutex_unlock( &p_input->p->p_item->lock );
  314.                     return VLC_SUCCESS;
  315.                 }
  316.             }
  317.             *pp_attachment = NULL;
  318.             vlc_mutex_unlock( &p_input->p->p_item->lock );
  319.             return VLC_EGENERIC;
  320.         }
  321.         case INPUT_SET_RECORD_STATE:
  322.             b_bool = (bool)va_arg( args, int );
  323.             var_SetBool( p_input, "record", b_bool );
  324.             return VLC_SUCCESS;
  325.         case INPUT_GET_RECORD_STATE:
  326.             pb_bool = (bool*)va_arg( args, bool* );
  327.             *pb_bool = var_GetBool( p_input, "record" );
  328.             return VLC_SUCCESS;
  329.         case INPUT_RESTART_ES:
  330.             val.i_int = (int)va_arg( args, int );
  331.             input_ControlPush( p_input, INPUT_CONTROL_RESTART_ES, &val );
  332.             return VLC_SUCCESS;
  333.         case INPUT_GET_AOUT:
  334.         {
  335.             aout_instance_t *p_aout = input_resource_HoldAout( p_input->p->p_resource );
  336.             if( !p_aout )
  337.                 return VLC_EGENERIC;
  338.             aout_instance_t **pp_aout = (aout_instance_t**)va_arg( args, aout_instance_t** );
  339.             *pp_aout = p_aout;
  340.             return VLC_SUCCESS;
  341.         }
  342.         case INPUT_GET_VOUTS:
  343.         {
  344.             vout_thread_t ***ppp_vout = (vout_thread_t***)va_arg( args, vout_thread_t*** );
  345.             int           *pi_vout = (int*)va_arg( args, int* );
  346.             input_resource_HoldVouts( p_input->p->p_resource, ppp_vout, pi_vout );
  347.             if( *pi_vout <= 0 )
  348.                 return VLC_EGENERIC;
  349.             return VLC_SUCCESS;
  350.         }
  351.         default:
  352.             msg_Err( p_input, "unknown query in input_vaControl" );
  353.             return VLC_EGENERIC;
  354.     }
  355. }
  356. static void UpdateBookmarksOption( input_thread_t *p_input )
  357. {
  358.     vlc_mutex_lock( &p_input->p->p_item->lock );
  359.     /* Update the "bookmark" list */
  360.     var_Change( p_input, "bookmark", VLC_VAR_CLEARCHOICES, 0, 0 );
  361.     for( int i = 0; i < p_input->p->i_bookmark; i++ )
  362.     {
  363.         vlc_value_t val, text;
  364.         val.i_int = i;
  365.         text.psz_string = p_input->p->pp_bookmark[i]->psz_name;
  366.         var_Change( p_input, "bookmark", VLC_VAR_ADDCHOICE,
  367.                     &val, &text );
  368.     }
  369.     /* Create the "bookmarks" option value */
  370.     const char *psz_format = "{name=%s,bytes=%"PRId64",time=%"PRId64"}";
  371.     int i_len = strlen( "bookmarks=" );
  372.     for( int i = 0; i < p_input->p->i_bookmark; i++ )
  373.     {
  374.         const seekpoint_t *p_bookmark = p_input->p->pp_bookmark[i];
  375.         i_len += snprintf( NULL, 0, psz_format,
  376.                            p_bookmark->psz_name,
  377.                            p_bookmark->i_byte_offset,
  378.                            p_bookmark->i_time_offset/1000000 );
  379.     }
  380.     char *psz_value = malloc( i_len + p_input->p->i_bookmark + 1 );
  381.     char *psz_next = psz_value;
  382.     psz_next += sprintf( psz_next, "bookmarks=" );
  383.     for( int i = 0; i < p_input->p->i_bookmark && psz_value != NULL; i++ )
  384.     {
  385.         const seekpoint_t *p_bookmark = p_input->p->pp_bookmark[i];
  386.         psz_next += sprintf( psz_next, psz_format,
  387.                              p_bookmark->psz_name,
  388.                              p_bookmark->i_byte_offset,
  389.                              p_bookmark->i_time_offset/1000000 );
  390.         if( i < p_input->p->i_bookmark - 1)
  391.             *psz_next++ = ',';
  392.     }
  393.     vlc_mutex_unlock( &p_input->p->p_item->lock );
  394.     if( psz_value )
  395.         input_item_AddOption( p_input->p->p_item, psz_value, VLC_INPUT_OPTION_UNIQUE );
  396.     free( psz_value );
  397.     input_SendEventBookmark( p_input );
  398. }