Changeset aa407ea9ca0beca090021e1bc26c4d9f84f003df

Show
Ignore:
Timestamp:
26/08/08 23:27:56 (3 months ago)
Author:
Laurent Aimar <fenrir@videolan.org>
git-committer:
Laurent Aimar <fenrir@videolan.org> 1219786076 +0200
git-parent:

[b08b569203e1789fdec40e943ac57fbbf16a52a9]

git-author:
Laurent Aimar <fenrir@videolan.org> 1219748058 +0200
Message:

Added record support at the stream_t level in core.

The record access_filter will become useless as soon as all demuxers that can
support it will be modified.
The record support is half done. I will also add es_out_t record functionnalities,
and a way to selected one of them if both are supported.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/vlc_demux.h

    r915ba6e raa407ea  
    125125    DEMUX_GET_ATTACHMENTS,      /* arg1=input_attachment_t***, int* res=can fail */ 
    126126 
     127    /* RECORD you should accept it only if the stream can be recorded without 
     128     * any modification or header addition. */ 
     129    DEMUX_CAN_RECORD,           /* arg1=bool*   res=can fail(assume false) */ 
     130    DEMUX_SET_RECORD_STATE,     /* arg1=bool    res=can fail */ 
     131 
     132 
    127133    /* II. Specific access_demux queries */ 
    128     DEMUX_CAN_PAUSE,            /* arg1= bool*    can fail (assume false)*/ 
     134    DEMUX_CAN_PAUSE = 0x1000,   /* arg1= bool*    can fail (assume false)*/ 
    129135    DEMUX_SET_PAUSE_STATE,      /* arg1= bool     can fail */ 
    130136 
  • include/vlc_input.h

    r6baf831 raa407ea  
    525525 
    526526    /* On the fly input slave */ 
    527     INPUT_ADD_SLAVE        /* arg1= char * */ 
     527    INPUT_ADD_SLAVE,       /* arg1= char * */ 
     528 
     529    /* On the fly record while playing */ 
     530    INPUT_SET_RECORD_STATE, /* arg1=bool    res=can fail */ 
     531    INPUT_GET_RECORD_STATE, /* arg1=bool*   res=can fail */ 
    528532}; 
    529533 
  • include/vlc_stream.h

    rebd8003 raa407ea  
    6565                             if access unreachable or access control answer */ 
    6666 
    67     STREAM_GET_CONTENT_TYPE,   /**< arg1= char **         res=can file */ 
     67    STREAM_GET_CONTENT_TYPE,    /**< arg1= char **         res=can fail */ 
     68 
     69    /* SET_RECORD: 
     70     * XXX only data read through stream_Read/Block will be recorded */ 
     71    STREAM_SET_RECORD_STATE,     /**< arg1=bool, arg2=const char *psz_ext (if arg1 is true)  res=can fail */ 
    6872}; 
    6973 
  • modules/control/hotkeys.c

    r2feb063 raa407ea  
    811811                osd_MenuActivate( VLC_OBJECT(p_intf) ); 
    812812            } 
     813            else if( i_action == ACTIONID_RECORD ) 
     814            { 
     815                if( var_GetBool( p_input, "can-record" ) ) 
     816                { 
     817                    const bool b_record = !var_GetBool( p_input, "record" ); 
     818 
     819                    if( b_record ) 
     820                        vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Recording") ); 
     821                    else 
     822                        vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Recording done") ); 
     823                    var_SetBool( p_input, "record", b_record ); 
     824                } 
     825            } 
    813826        } 
    814827        if( p_vout ) 
  • modules/demux/ts.c

    ra060c85 raa407ea  
    371371    /* */ 
    372372    bool        b_meta; 
     373 
     374    /* */ 
     375    bool        b_start_record; 
    373376}; 
    374377 
     
    643646    p_sys->i_ts_read = 50; 
    644647    p_sys->csa = NULL; 
     648    p_sys->b_start_record = false; 
    645649 
    646650    /* Init PAT handler */ 
     
    10921096        } 
    10931097 
     1098        if( p_sys->b_start_record ) 
     1099        { 
     1100            /* Enable recording once synchronized */ 
     1101            stream_Control( p_demux->s, STREAM_SET_RECORD_STATE, true, "ts" ); 
     1102            p_sys->b_start_record = false; 
     1103        } 
     1104 
    10941105        if( p_sys->b_udp_out ) 
    10951106        { 
     
    11911202    demux_sys_t *p_sys = p_demux->p_sys; 
    11921203    double f, *pf; 
     1204    bool b_bool, *pb_bool; 
    11931205    int64_t i64; 
    11941206    int64_t *pi64; 
     
    13861398            return VLC_SUCCESS; 
    13871399        } 
     1400 
     1401        case DEMUX_CAN_RECORD: 
     1402            pb_bool = (bool*)va_arg( args, bool * ); 
     1403            *pb_bool = true; 
     1404            return VLC_SUCCESS; 
     1405 
     1406        case DEMUX_SET_RECORD_STATE: 
     1407            b_bool = (bool)va_arg( args, int ); 
     1408 
     1409            if( !b_bool ) 
     1410                stream_Control( p_demux->s, STREAM_SET_RECORD_STATE, false ); 
     1411            p_sys->b_start_record = b_bool; 
     1412            return VLC_SUCCESS; 
    13881413 
    13891414        case DEMUX_GET_FPS: 
  • modules/gui/qt4/components/interface_widgets.cpp

    rfce957a raa407ea  
    373373        i_input_id = p_item->i_id; 
    374374 
    375         if( var_Type( THEMIM->getInput(), "record-toggle" ) == VLC_VAR_VOID ) 
    376             recordButton->setVisible( true ); 
    377         else 
    378             recordButton->setVisible( false ); 
     375        recordButton->setVisible( var_GetBool( THEMIM->getInput(), "can-record" ) ); 
    379376    } 
    380377    else 
     378    { 
    381379        recordButton->setVisible( false ); 
     380    } 
    382381 
    383382    ABButton->setEnabled( enable ); 
     
    465464    { 
    466465        /* This method won't work fine if the stream can't be cut anywhere */ 
    467         if( var_Type( p_input, "record-toggle" ) == VLC_VAR_VOID ) 
    468             var_TriggerCallback( p_input, "record-toggle" ); 
     466        const bool b_recording = var_GetBool( p_input, "record" ); 
     467        var_SetBool( p_input, "record", !b_recording ); 
    469468#if 0 
    470469        else 
  • src/input/control.c

    rd11fd0d raa407ea  
    6464 
    6565    int i_int, *pi_int; 
     66    bool b_bool, *pb_bool; 
    6667    double f, *pf; 
    6768    int64_t i_64, *pi_64; 
     
    599600        } 
    600601 
     602        case INPUT_SET_RECORD_STATE: 
     603            b_bool = (bool)va_arg( args, int ); 
     604            var_SetBool( p_input, "record", b_bool ); 
     605            return VLC_SUCCESS; 
     606 
     607        case INPUT_GET_RECORD_STATE: 
     608            pb_bool = (bool*)va_arg( args, bool* ); 
     609            *pb_bool = var_GetBool( p_input, "record" ); 
     610            return VLC_SUCCESS; 
    601611 
    602612        default: 
  • src/input/decoder.c

    r4ca1e8b raa407ea  
    735735} 
    736736 
    737  
    738 static void optimize_video_pts( decoder_t *p_dec ) 
    739 
    740     picture_t * oldest_pict = NULL; 
    741     picture_t * youngest_pict = NULL; 
     737static void DecoderOptimizePtsDelay( decoder_t *p_dec ) 
     738
     739    input_thread_t *p_input = p_dec->p_owner->p_input; 
     740    vout_thread_t *p_vout = p_dec->p_owner->p_vout; 
     741    input_thread_private_t *p_priv = p_input->p; 
     742 
     743    picture_t *p_old = NULL; 
     744    picture_t *p_young = NULL; 
    742745    int i; 
    743746 
    744     input_thread_t * p_input = p_dec->p_owner->p_input; 
    745     vout_thread_t * p_vout = p_dec->p_owner->p_vout; 
    746     input_thread_private_t * p_priv = p_input->p; 
    747  
    748747    /* Enable with --auto-adjust-pts-delay */ 
    749     if( !p_priv->pts_adjust.auto_adjust ) return; 
     748    if( !p_priv->pts_adjust.b_auto_adjust ) 
     749        return; 
    750750 
    751751    for( i = 0; i < I_RENDERPICTURES; i++ ) 
    752752    { 
    753         picture_t * pic = PP_RENDERPICTURE[i]; 
    754         if( pic->i_status != READY_PICTURE ) 
     753        picture_t *p_pic = PP_RENDERPICTURE[i]; 
     754 
     755        if( p_pic->i_status != READY_PICTURE ) 
    755756            continue; 
    756757 
    757         if( !oldest_pict || pic->date < oldest_pict->date ) 
    758             oldest_pict = pic; 
    759         if( !youngest_pict || pic->date > youngest_pict->date ) 
    760             youngest_pict = pic; 
    761     } 
    762  
    763     if( !youngest_pict || !oldest_pict
     758        if( !p_old || p_pic->date < p_old->date ) 
     759            p_old = p_pic; 
     760        if( !p_young || p_pic->date > p_young->date ) 
     761            p_young = p_pic; 
     762    } 
     763 
     764    if( !p_young || !p_old
    764765        return; 
    765766 
     
    776777     * why we may end up in having a negative pts_delay, 
    777778     * to compensate that artificial delay. */ 
    778     mtime_t buffer_size = youngest_pict->date - oldest_pict->date; 
    779     int64_t pts_slide = 0; 
    780     if( buffer_size < 10000 ) 
     779    const mtime_t i_buffer_length = p_young->date - p_old->date; 
     780    int64_t i_pts_slide = 0; 
     781    if( i_buffer_length < 10000 ) 
    781782    { 
    782783        if( p_priv->pts_adjust.i_num_faulty > 10 ) 
    783784        { 
    784             pts_slide = __MAX(p_input->i_pts_delay *3 / 2, 10000); 
     785            i_pts_slide = __MAX(p_input->i_pts_delay *3 / 2, 10000); 
    785786            p_priv->pts_adjust.i_num_faulty = 0; 
    786787        } 
    787         if( p_priv->pts_adjust.to_high ) 
    788         { 
    789             p_priv->pts_adjust.to_high = !p_priv->pts_adjust.to_high; 
     788        if( p_priv->pts_adjust.b_to_high ) 
     789        { 
     790            p_priv->pts_adjust.b_to_high = !p_priv->pts_adjust.b_to_high; 
    790791            p_priv->pts_adjust.i_num_faulty = 0; 
    791792        } 
    792793        p_priv->pts_adjust.i_num_faulty++; 
    793794    } 
    794     else if( buffer_size > 100000 ) 
     795    else if( i_buffer_length > 100000 ) 
    795796    { 
    796797        if( p_priv->pts_adjust.i_num_faulty > 25 ) 
    797798        { 
    798             pts_slide = -buffer_size/2; 
     799            i_pts_slide = -i_buffer_length/2; 
    799800            p_priv->pts_adjust.i_num_faulty = 0; 
    800801        } 
    801         if( p_priv->pts_adjust.to_high ) 
    802         { 
    803             p_priv->pts_adjust.to_high = !p_priv->pts_adjust.to_high; 
     802        if( p_priv->pts_adjust.b_to_high ) 
     803        { 
     804            p_priv->pts_adjust.b_to_high = !p_priv->pts_adjust.b_to_high; 
    804805            p_priv->pts_adjust.i_num_faulty = 0; 
    805806        } 
    806807        p_priv->pts_adjust.i_num_faulty++; 
    807808    } 
    808     if( pts_slide
    809     { 
    810         mtime_t origi_delay = p_input->i_pts_delay; 
    811  
    812         p_input->i_pts_delay += pts_slide; 
     809    if( i_pts_slide != 0
     810    { 
     811        const mtime_t i_pts_delay_org = p_input->i_pts_delay; 
     812 
     813        p_input->i_pts_delay += i_pts_slide; 
    813814 
    814815        /* Don't play with the pts delay for more than -2<->3sec */ 
     
    817818        else if( p_input->i_pts_delay > 3000000 ) 
    818819            p_input->i_pts_delay = 3000000; 
    819         pts_slide = p_input->i_pts_delay - origi_delay
     820        i_pts_slide = p_input->i_pts_delay - i_pts_delay_org
    820821 
    821822        msg_Dbg( p_input, "Sliding the pts by %dms pts delay at %dms picture buffer was %dms", 
    822             (int)pts_slide/1000, (int)p_input->i_pts_delay/1000, (int)buffer_size/1000); 
     823            (int)i_pts_slide/1000, (int)p_input->i_pts_delay/1000, (int)i_buffer_length/1000); 
    823824 
    824825        vlc_mutex_lock( &p_vout->picture_lock ); 
    825826        /* Slide all the picture */ 
    826827        for( i = 0; i < I_RENDERPICTURES; i++ ) 
    827             PP_RENDERPICTURE[i]->date += pts_slide; 
     828            PP_RENDERPICTURE[i]->date += i_pts_slide; 
    828829        /* FIXME: slide aout/spu */ 
    829830        vlc_mutex_unlock( &p_vout->picture_lock ); 
    830  
    831831    } 
    832832} 
     
    873873        vout_DatePicture( p_vout, p_pic, p_pic->date ); 
    874874 
    875         optimize_video_pts( p_dec ); 
     875        DecoderOptimizePtsDelay( p_dec ); 
    876876 
    877877        vout_DisplayPicture( p_vout, p_pic ); 
  • src/input/demux.c

    r7979cfc raa407ea  
    281281        case DEMUX_SET_GROUP: 
    282282        case DEMUX_GET_ATTACHMENTS: 
     283        case DEMUX_CAN_RECORD: 
     284        case DEMUX_SET_RECORD_STATE: 
    283285            return VLC_EGENERIC; 
    284286 
     
    527529        case STREAM_CONTROL_ACCESS: 
    528530        case STREAM_GET_CONTENT_TYPE: 
     531        case STREAM_SET_RECORD_STATE: 
    529532            return VLC_EGENERIC; 
    530533 
  • src/input/input.c

    rdd68bab raa407ea  
    113113 *    or not, for that check position != 0.0) 
    114114 *  - can-pause 
     115 *  - can-record (if a stream can be recorded while playing) 
    115116 *  - teletext-es to get the index of spu track that is teletext --1 if no teletext) 
    116117 * * For intf callback upon changes 
     
    185186    p_input->i_state = INIT_S; 
    186187    p_input->p->i_rate  = INPUT_RATE_DEFAULT; 
     188    p_input->p->b_recording = false; 
    187189    TAB_INIT( p_input->p->i_bookmark, p_input->p->bookmark ); 
    188190    TAB_INIT( p_input->p->i_attachment, p_input->p->attachment ); 
     
    236238    input_ControlVarInit( p_input ); 
    237239 
     240    /* */ 
     241    p_input->p->pts_adjust.b_auto_adjust = var_GetBool( p_input, "auto-adjust-pts-delay" ); 
    238242    p_input->p->input.i_cr_average = var_GetInteger( p_input, "cr-average" ); 
    239243 
     
    14531457        { 
    14541458            double f_pos; 
     1459 
     1460            if( p_input->p->b_recording ) 
     1461            { 
     1462                msg_Err( p_input, "INPUT_CONTROL_SET_POSITION(_OFFSET) ignored while recording" ); 
     1463                break; 
     1464            } 
    14551465            if( i_type == INPUT_CONTROL_SET_POSITION ) 
    14561466            { 
     
    14891499            int64_t i_time; 
    14901500            int i_ret; 
     1501 
     1502            if( p_input->p->b_recording ) 
     1503            { 
     1504                msg_Err( p_input, "INPUT_CONTROL_SET_TIME(_OFFSET) ignored while recording" ); 
     1505                break; 
     1506            } 
    14911507 
    14921508            if( i_type == INPUT_CONTROL_SET_TIME ) 
     
    17451761        case INPUT_CONTROL_SET_TITLE_NEXT: 
    17461762        case INPUT_CONTROL_SET_TITLE_PREV: 
     1763            if( p_input->p->b_recording ) 
     1764            { 
     1765                msg_Err( p_input, "INPUT_CONTROL_SET_TITLE(*) ignored while recording" ); 
     1766                break; 
     1767            } 
    17471768            if( p_input->p->input.b_title_demux && 
    17481769                p_input->p->input.i_title > 0 ) 
     
    17921813        case INPUT_CONTROL_SET_SEEKPOINT_NEXT: 
    17931814        case INPUT_CONTROL_SET_SEEKPOINT_PREV: 
     1815            if( p_input->p->b_recording ) 
     1816            { 
     1817                msg_Err( p_input, "INPUT_CONTROL_SET_SEEKPOINT(*) ignored while recording" ); 
     1818                break; 
     1819            } 
     1820 
    17941821            if( p_input->p->input.b_title_demux && 
    17951822                p_input->p->input.i_title > 0 ) 
     
    19191946            break; 
    19201947 
     1948        case INPUT_CONTROL_SET_RECORD_STATE: 
     1949            if( p_input->p->input.b_can_record ) 
     1950            { 
     1951                if( !!p_input->p->b_recording != !!val.b_bool ) 
     1952                { 
     1953                    if( demux_Control( p_input->p->input.p_demux, 
     1954                                       DEMUX_SET_RECORD_STATE, val.b_bool ) ) 
     1955                        val.b_bool = false; 
     1956 
     1957                    p_input->p->b_recording = val.b_bool; 
     1958                } 
     1959 
     1960                var_Change( p_input, "record", VLC_VAR_SETVALUE, &val, NULL ); 
     1961 
     1962                b_force_update = true; 
     1963            } 
     1964            break; 
     1965 
    19211966        case INPUT_CONTROL_SET_BOOKMARK: 
    19221967        default: 
     
    20572102static input_source_t *InputSourceNew( input_thread_t *p_input ) 
    20582103{ 
    2059     (void)p_input
    2060     input_source_t *in = (input_source_t*) malloc( sizeof( input_source_t ) ); 
     2104    VLC_UNUSED(p_input)
     2105    input_source_t *in = malloc( sizeof( input_source_t ) ); 
    20612106    if( in ) 
    20622107        memset( in, 0, sizeof( input_source_t ) ); 
     
    23202365            goto error; 
    23212366        } 
     2367 
     2368        if( demux_Control( in->p_demux, DEMUX_CAN_RECORD, &in->b_can_record ) ) 
     2369            in->b_can_record = false; 
     2370        var_SetBool( p_input, "can-record", in->b_can_record ); 
    23222371 
    23232372        /* Get title from demux */ 
  • src/input/input_internal.h

    r3f5d4a9 raa407ea  
    6464    bool b_can_pace_control; 
    6565    bool b_can_rate_control; 
     66    bool b_can_record; 
    6667    bool b_rescale_ts; 
    6768 
     
    8586 
    8687    int         i_rate; 
     88    bool        b_recording; 
    8789    /* */ 
    8890    int64_t     i_start;    /* :start-time,0 by default */ 
     
    117119 
    118120    /* pts delay fixup */ 
    119     struct { 
     121    struct 
     122    { 
    120123        int  i_num_faulty; 
    121         bool to_high; 
    122         bool auto_adjust; 
     124        bool b_to_high; 
     125        bool b_auto_adjust; 
    123126    } pts_adjust; 
    124127 
     
    192195 
    193196    INPUT_CONTROL_ADD_SLAVE, 
     197 
     198    INPUT_CONTROL_SET_RECORD_STATE, 
    194199}; 
    195200 
  • src/input/stream.c

    r3f5d4a9 raa407ea  
    2626#endif 
    2727 
     28#include <dirent.h> 
     29 
    2830#include <vlc_common.h> 
     31#include <vlc_charset.h> 
     32#include <vlc_strings.h> 
     33#include <vlc_osd.h> 
    2934 
    3035#include <assert.h> 
     
    187192    /* Preparse mode ? */ 
    188193    bool      b_quick; 
     194 
     195    /* */ 
     196    struct 
     197    { 
     198        bool b_active; 
     199 
     200        FILE *f;    /* TODO it could be replaced by access_output_t one day */ 
     201    } record; 
    189202}; 
    190203 
     
    213226static void UStreamDestroy( stream_t *s ); 
    214227static int  ASeek( stream_t *s, int64_t i_pos ); 
     228static int  ARecordSetState( stream_t *s, bool b_record, const char *psz_extension ); 
     229static void ARecordWrite( stream_t *s, const uint8_t *p_buffer, size_t i_buffer ); 
    215230 
    216231/**************************************************************************** 
     
    315330        p_sys->method = Stream; 
    316331 
     332    p_sys->record.b_active = false; 
     333 
    317334    p_sys->i_pos = p_access->info.i_pos; 
    318335 
     
    513530    vlc_object_detach( s ); 
    514531 
    515     if( p_sys->method == Block ) block_ChainRelease( p_sys->block.p_first ); 
    516     else if ( p_sys->method == Immediate ) free( p_sys->immediate.p_buffer ); 
    517     else free( p_sys->stream.p_buffer ); 
     532    if( p_sys->record.b_active ) 
     533        ARecordSetState( s, false, NULL ); 
     534 
     535    if( p_sys->method == Block ) 
     536        block_ChainRelease( p_sys->block.p_first ); 
     537    else if ( p_sys->method == Immediate ) 
     538        free( p_sys->immediate.p_buffer ); 
     539    else 
     540        free( p_sys->stream.p_buffer ); 
    518541 
    519542    free( p_sys->p_peek ); 
     
    618641 
    619642    bool *p_bool; 
     643    bool b_bool; 
     644    const char *psz_string; 
    620645    int64_t    *pi_64, i_64; 
    621646    int        i_int; 
     
    678703            return access_Control( p_access, ACCESS_GET_CONTENT_TYPE, 
    679704                                    va_arg( args, char ** ) ); 
     705        case STREAM_SET_RECORD_STATE: 
     706            b_bool = (bool)va_arg( args, int ); 
     707            psz_string = NULL; 
     708            if( b_bool ) 
     709                psz_string = (const char*)va_arg( args, const char* ); 
     710            return ARecordSetState( s, b_bool, psz_string ); 
    680711 
    681712        default: 
     
    686717} 
    687718 
    688  
     719/**************************************************************************** 
     720 * ARecord*: record stream functions 
     721 ****************************************************************************/ 
     722 
     723/* TODO FIXME nearly the same logic that snapshot code */ 
     724static char *ARecordGetFileName( stream_t *s, const char *psz_path, const char *psz_prefix, const char *psz_extension ) 
     725
     726    char *psz_file; 
     727    DIR *path; 
     728 
     729    path = utf8_opendir( psz_path ); 
     730    if( path ) 
     731    { 
     732        closedir( path ); 
     733 
     734        const char *psz_prefix = "vlc-record-%Y-%m-%d-%H:%M:%S-$p";  // TODO allow conf ? 
     735        char *psz_tmp = str_format( s, psz_prefix ); 
     736        if( !psz_tmp ) 
     737            return NULL; 
     738 
     739        filename_sanitize( psz_tmp ); 
     740        if( asprintf( &psz_file, "%s"DIR_SEP"%s.%s", 
     741                      psz_path, psz_tmp, psz_extension ) < 0 ) 
     742            psz_file = NULL; 
     743        free( psz_tmp ); 
     744        return psz_file; 
     745    } 
     746    else 
     747    { 
     748        psz_file = str_format( s, psz_path ); 
     749        path_sanitize( psz_file ); 
     750        return psz_file; 
     751    } 
     752
     753 
     754static int  ARecordStart( stream_t *s, const char *psz_extension ) 
     755
     756    stream_sys_t *p_sys = s->p_sys; 
     757 
     758    DIR *path; 
     759    char *psz_file; 
     760    FILE *f; 
     761 
     762    /* */ 
     763    if( !psz_extension ) 
     764        psz_extension = "dat"; 
     765 
     766    /* Retreive path */ 
     767    char *psz_path = var_CreateGetString( s, "input-record-path" ); 
     768    if( !psz_path || *psz_path == '\0' ) 
     769    { 
     770        free( psz_path ); 
     771        psz_path = strdup( config_GetHomeDir() ); 
     772    } 
     773 
     774    if( !psz_path ) 
     775        return VLC_ENOMEM; 
     776 
     777    /* Create file name 
     778     * TODO allow prefix configuration */ 
     779    psz_file = ARecordGetFileName( s, psz_path, "vlc-record-%Y-%m-%d-%H:%M:%S-$p", psz_extension ); 
     780 
     781    free( psz_path ); 
     782 
     783    if( !psz_file ) 
     784        return VLC_ENOMEM; 
     785 
     786    f = utf8_fopen( psz_file, "wb" ); 
     787    if( !f ) 
     788    { 
     789        free( psz_file ); 
     790        return VLC_EGENERIC; 
     791    } 
     792    msg_Dbg( s, "Recording into %s", psz_file ); 
     793    free( psz_file ); 
     794 
     795    /* */ 
     796    p_sys->record.f = f; 
     797    p_sys->record.b_active = true; 
     798    return VLC_SUCCESS; 
     799
     800static int  ARecordStop( stream_t *s ) 
     801
     802    stream_sys_t *p_sys = s->p_sys; 
     803 
     804    assert( p_sys->record.b_active ); 
     805 
     806    msg_Dbg( s, "Recording completed" ); 
     807    fclose( p_sys->record.f ); 
     808    p_sys->record.b_active = false; 
     809    return VLC_SUCCESS; 
     810
     811 
     812static int  ARecordSetState( stream_t *s, bool b_record, const char *psz_extension ) 
     813
     814    stream_sys_t *p_sys = s->p_sys; 
     815 
     816    if( !!p_sys->record.b_active == !!b_record ) 
     817        return VLC_SUCCESS; 
     818 
     819    if( b_record ) 
     820        return ARecordStart( s, psz_extension ); 
     821    else 
     822        return ARecordStop( s ); 
     823
     824static void ARecordWrite( stream_t *s, const uint8_t *p_buffer, size_t i_buffer ) 
     825
     826    stream_sys_t *p_sys = s->p_sys; 
     827 
     828    assert( p_sys->record.b_active ); 
     829 
     830    if( i_buffer ) 
     831        fwrite( p_buffer, 1, i_buffer, p_sys->record.f ); 
     832
    689833 
    690834/**************************************************************************** 
     
    822966    } 
    823967 
     968    if( p_sys->record.b_active && i_data > 0 ) 
     969        ARecordWrite( s, p_read, i_data ); 
     970 
    824971    p_sys->i_pos += i_data; 
    825972    return i_data; 
     
    11651312        } 
    11661313    } 
     1314 
     1315    if( p_sys->record.b_active && i_data > 0 ) 
     1316        ARecordWrite( s, p_read, i_data ); 
    11671317 
    11681318    return i_data; 
     
    15521702        } 
    15531703    } 
     1704 
     1705    if( p_sys->record.b_active && i_copy > 0 ) 
     1706        ARecordWrite( s, p_read, i_copy ); 
    15541707 
    15551708    p_sys->i_pos += i_to_read; 
  • src/input/var.c

    r94ae971 raa407ea  
    6262                             vlc_value_t oldval, vlc_value_t newval, void * ); 
    6363 
     64static int RecordCallback( vlc_object_t *p_this, char const *psz_cmd, 
     65                           vlc_value_t oldval, vlc_value_t newval, 
     66                           void *p_data ); 
     67 
    6468typedef struct 
    6569{ 
     
    9498    CALLBACK( "audio-es", ESCallback ), 
    9599    CALLBACK( "spu-es", ESCallback ), 
     100    CALLBACK( "record", RecordCallback ), 
    96101 
    97102    CALLBACK( NULL, NULL ) 
     
    189194    val.i_time = 0; 
    190195    var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL ); 
    191  
    192     p_input->p->pts_adjust.auto_adjust = var_CreateGetBool( 
    193             p_input, "auto-adjust-pts-delay" ); 
    194196 
    195197    /* Video ES */ 
     
    405407void input_ConfigVarInit ( input_thread_t *p_input ) 
    406408{ 
    407     vlc_value_t val; 
    408  
    409409    /* Create Object Variables for private use only */ 
    410410 
     
    461461        var_Create( p_input, "clock-synchro", 
    462462                    VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); 
     463        var_Create( p_input, "auto-adjust-pts-delay", 
     464                    VLC_VAR_BOOL | VLC_VAR_DOINHERIT); 
    463465    } 
    464466 
    465467    var_Create( p_input, "seekable", VLC_VAR_BOOL ); 
    466     val.b_bool = true; /* Fixed later*/ 
    467     var_Change( p_input, "seekable", VLC_VAR_SETVALUE, &val, NULL ); 
     468    var_SetBool( p_input, "seekable", true ); /* Fixed later*/ 
     469 
    468470    var_Create( p_input, "can-pause", VLC_VAR_BOOL ); 
    469     val.b_bool = true; /* Fixed later*/ 
    470     var_Change( p_input, "can-pause", VLC_VAR_SETVALUE, &val, NULL ); 
     471    var_SetBool( p_input, "can-pause", true ); /* Fixed later*/ 
     472 
     473    var_Create( p_input, "can-record", VLC_VAR_BOOL ); 
     474    var_SetBool( p_input, "can-record", false ); /* Fixed later*/ 
     475 
     476    var_Create( p_input, "record", VLC_VAR_BOOL ); 
     477    var_SetBool( p_input, "record", false ); 
     478 
    471479    var_Create( p_input, "teletext-es", VLC_VAR_INTEGER ); 
    472480    var_SetInteger( p_input, "teletext-es", -1 ); 
     
    777785    return VLC_SUCCESS; 
    778786} 
     787 
     788static int RecordCallback( vlc_object_t *p_this, char const *psz_cmd, 
     789                           vlc_value_t oldval, vlc_value_t newval, 
     790                           void *p_data ) 
     791{ 
     792    input_thread_t *p_input = (input_thread_t*)p_this; 
     793    VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data); 
     794 
     795    input_ControlPush( p_input, INPUT_CONTROL_SET_RECORD_STATE, &newval ); 
     796 
     797    return VLC_SUCCESS; 
     798} 
  • src/libvlc-module.c

    reff2497 raa407ea  
    676676    "bytes=optional-byte-offset},{...}\"") 
    677677 
     678#define INPUT_RECORD_PATH_TEXT N_("Record directory or filename") 
     679#define INPUT_RECORD_PATH_LONGTEXT N_( \ 
     680    "Directory or filename where the records will be stored" ) 
     681 
    678682// DEPRECATED 
    679683#define SUB_CAT_LONGTEXT N_( \ 
     
    17371741    add_bool( "network-synchronisation", false, NULL, NETSYNC_TEXT, 
    17381742              NETSYNC_LONGTEXT, true ); 
     1743 
     1744    add_string( "input-record-path", NULL, NULL, INPUT_RECORD_PATH_TEXT, 
     1745                INPUT_RECORD_PATH_LONGTEXT, true ); 
    17391746 
    17401747/* Decoder options */