Exemplo n.º 1
0
/*****************************************************************************
 * Open: Starts the RTSP server module
 *****************************************************************************/
int OpenVoD( vlc_object_t *p_this )
{
    vod_t *p_vod = (vod_t *)p_this;
    vod_sys_t *p_sys = NULL;
    char *psz_url;

    p_vod->p_sys = p_sys = malloc( sizeof( vod_sys_t ) );
    if( !p_sys ) goto error;

    psz_url = var_InheritString( p_vod, "rtsp-host" );

    if( psz_url == NULL )
        p_sys->psz_rtsp_path = strdup( "/" );
    else
    {
        vlc_url_t url;
        vlc_UrlParse( &url, psz_url, 0 );
        free( psz_url );

        if( url.psz_path == NULL )
            p_sys->psz_rtsp_path = strdup( "/" );
        else
        if( !( strlen( url.psz_path ) > 0
               && url.psz_path[strlen( url.psz_path ) - 1] == '/' ) )
        {
            if( asprintf( &p_sys->psz_rtsp_path, "%s/", url.psz_path ) == -1 )
            {
                p_sys->psz_rtsp_path = NULL;
                vlc_UrlClean( &url );
                goto error;
            }
        }
        else
            p_sys->psz_rtsp_path = strdup( url.psz_path );

        vlc_UrlClean( &url );
    }

    p_vod->pf_media_new = MediaNew;
    p_vod->pf_media_del = MediaAskDel;

    p_sys->p_fifo_cmd = block_FifoNew();
    if( vlc_clone( &p_sys->thread, CommandThread, p_vod, VLC_THREAD_PRIORITY_LOW ) )
    {
        msg_Err( p_vod, "cannot spawn rtsp vod thread" );
        block_FifoRelease( p_sys->p_fifo_cmd );
        goto error;
    }

    return VLC_SUCCESS;

error:
    if( p_sys )
    {
        free( p_sys->psz_rtsp_path );
        free( p_sys );
    }

    return VLC_EGENERIC;
}
Exemplo n.º 2
0
/*****************************************************************************
 * sout_MuxAddStream:
 *****************************************************************************/
sout_input_t *sout_MuxAddStream( sout_mux_t *p_mux, es_format_t *p_fmt )
{
    sout_input_t *p_input;

    if( !p_mux->b_add_stream_any_time && !p_mux->b_waiting_stream )
    {
        msg_Err( p_mux, "cannot add a new stream (unsupported while muxing "
                        "to this format). You can try increasing sout-mux-caching value" );
        return NULL;
    }

    msg_Dbg( p_mux, "adding a new input" );

    /* create a new sout input */
    p_input = malloc( sizeof( sout_input_t ) );
    if( !p_input )
        return NULL;
    p_input->p_fmt  = p_fmt;
    p_input->p_fifo = block_FifoNew();
    p_input->p_sys  = NULL;

    TAB_APPEND( p_mux->i_nb_inputs, p_mux->pp_inputs, p_input );
    if( p_mux->pf_addstream( p_mux, p_input ) < 0 )
    {
        msg_Err( p_mux, "cannot add this stream" );
        TAB_REMOVE( p_mux->i_nb_inputs, p_mux->pp_inputs, p_input );
        block_FifoRelease( p_input->p_fifo );
        free( p_input );
        return NULL;
    }

    return p_input;
}
Exemplo n.º 3
0
stream_t *stream_DemuxNew( demux_t *p_demux, const char *psz_demux, es_out_t *out )
{
    vlc_object_t *p_obj = VLC_OBJECT(p_demux);
    /* We create a stream reader, and launch a thread */
    stream_t     *s;
    stream_sys_t *p_sys;

    s = stream_CommonNew( p_obj );
    if( s == NULL )
        return NULL;
    s->p_input = p_demux->p_input;
    s->pf_read   = DStreamRead;
    s->pf_control= DStreamControl;
    s->pf_destroy= DStreamDelete;

    s->p_sys = p_sys = malloc( sizeof( *p_sys) );
    if( !s->p_sys )
    {
        stream_Delete( s );
        return NULL;
    }

    p_sys->i_pos = 0;
    p_sys->out = out;
    p_sys->p_block = NULL;
    p_sys->psz_name = strdup( psz_demux );
    p_sys->stats.position = 0.;
    p_sys->stats.length = 0;
    p_sys->stats.time = 0;

    /* decoder fifo */
    if( ( p_sys->p_fifo = block_FifoNew() ) == NULL )
    {
        stream_Delete( s );
        free( p_sys->psz_name );
        free( p_sys );
        return NULL;
    }

    atomic_init( &p_sys->active, true );
    vlc_mutex_init( &p_sys->lock );

    if( vlc_clone( &p_sys->thread, DStreamThread, s, VLC_THREAD_PRIORITY_INPUT ) )
    {
        vlc_mutex_destroy( &p_sys->lock );
        block_FifoRelease( p_sys->p_fifo );
        stream_Delete( s );
        free( p_sys->psz_name );
        free( p_sys );
        return NULL;
    }

    return s;
}
Exemplo n.º 4
0
/**
 * Open the module.
 * @param p_this: the filter object
 * @return VLC_SUCCESS or vlc error codes
 */
static int Open(vlc_object_t * p_this)
{
    filter_t *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys;

    p_sys = p_filter->p_sys = (filter_sys_t*)malloc(sizeof(*p_sys));
    if (p_sys == NULL)
        return VLC_ENOMEM;

    /* Create the object for the thread */
    vlc_sem_init(&p_sys->ready, 0);
    p_sys->b_error = false;
    p_sys->i_width = var_InheritInteger(p_filter, "glspectrum-width");
    p_sys->i_height = var_InheritInteger(p_filter, "glspectrum-height");
    p_sys->i_channels = aout_FormatNbChannels(&p_filter->fmt_in.audio);
    p_sys->i_prev_nb_samples = 0;
    p_sys->p_prev_s16_buff = NULL;

    p_sys->f_rotationAngle = 0;
    p_sys->f_rotationIncrement = ROTATION_INCREMENT;

    /* Fetch the FFT window parameters */
    window_get_param( VLC_OBJECT( p_filter ), &p_sys->wind_param );

    /* Create the FIFO for the audio data. */
    p_sys->fifo = block_FifoNew();
    if (p_sys->fifo == NULL)
        goto error;

    /* Create the thread */
    if (vlc_clone(&p_sys->thread, Thread, p_filter,
                  VLC_THREAD_PRIORITY_VIDEO))
        goto error;

    /* Wait for the displaying thread to be ready. */
    vlc_sem_wait(&p_sys->ready);
    if (p_sys->b_error)
    {
        vlc_join(p_sys->thread, NULL);
        goto error;
    }

    p_filter->fmt_in.audio.i_format = VLC_CODEC_FL32;
    p_filter->fmt_out.audio = p_filter->fmt_in.audio;
    p_filter->pf_audio_filter = DoWork;

    return VLC_SUCCESS;

error:
    vlc_sem_destroy(&p_sys->ready);
    free(p_sys);
    return VLC_EGENERIC;
}
Exemplo n.º 5
0
Arquivo: dirac.c Projeto: CSRedRat/vlc
/*****************************************************************************
 * OpenEncoder: probe the encoder and return score
 *****************************************************************************/
static int OpenEncoder( vlc_object_t *p_this )
{
    encoder_t *p_enc = (encoder_t *)p_this;
    encoder_sys_t *p_sys = p_enc->p_sys;
    int i_tmp;
    float f_tmp;
    char *psz_tmp;

    if( p_enc->fmt_out.i_codec != VLC_CODEC_DIRAC &&
        !p_enc->b_force )
    {
        return VLC_EGENERIC;
    }

    if( !p_enc->fmt_in.video.i_frame_rate || !p_enc->fmt_in.video.i_frame_rate_base ||
        !p_enc->fmt_in.video.i_height || !p_enc->fmt_in.video.i_width )
    {
        msg_Err( p_enc, "Framerate and picture dimensions must be non-zero" );
        return VLC_EGENERIC;
    }

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_sys = calloc( 1, sizeof(*p_sys) ) ) == NULL )
        return VLC_ENOMEM;

    p_enc->p_sys = p_sys;
    p_enc->pf_encode_video = Encode;
    p_enc->fmt_out.i_codec = VLC_CODEC_DIRAC;
    p_enc->fmt_out.i_cat = VIDEO_ES;

    if( ( p_sys->p_dts_fifo = block_FifoNew() ) == NULL )
    {
        CloseEncoder( p_this );
        return VLC_ENOMEM;
    }

    ResetPTStlb( p_enc );

    /* guess the video format based upon number of lines and picture height */
    int i = 0;
    VideoFormat guessed_video_fmt = VIDEO_FORMAT_CUSTOM;
    /* Pick the dirac_video_format in this order of preference:
     *  1. an exact match in frame height and an approximate fps match
     *  2. the previous preset with a smaller number of lines.
     */
    do
    {
        if( dirac_format_guess[i].i_height > p_enc->fmt_in.video.i_height )
        {
            guessed_video_fmt = dirac_format_guess[i-1].i_vf;
            break;
        }
        if( dirac_format_guess[i].i_height != p_enc->fmt_in.video.i_height )
            continue;
        int src_fps = p_enc->fmt_in.video.i_frame_rate / p_enc->fmt_in.video.i_frame_rate_base;
        int delta_fps = abs( dirac_format_guess[i].i_approx_fps - src_fps );
        if( delta_fps > 2 )
            continue;

        guessed_video_fmt = dirac_format_guess[i].i_vf;
        break;
    } while( dirac_format_guess[++i].i_height );

    dirac_encoder_context_init( &p_sys->ctx, guessed_video_fmt );

    /* constants set from the input video format */
    p_sys->ctx.src_params.width = p_enc->fmt_in.video.i_width;
    p_sys->ctx.src_params.height = p_enc->fmt_in.video.i_height;
    p_sys->ctx.src_params.frame_rate.numerator = p_enc->fmt_in.video.i_frame_rate;
    p_sys->ctx.src_params.frame_rate.denominator = p_enc->fmt_in.video.i_frame_rate_base;
    unsigned u_asr_num, u_asr_den;
    vlc_ureduce( &u_asr_num, &u_asr_den,
                 p_enc->fmt_in.video.i_sar_num,
                 p_enc->fmt_in.video.i_sar_den, 0 );
    p_sys->ctx.src_params.pix_asr.numerator = u_asr_num;
    p_sys->ctx.src_params.pix_asr.denominator = u_asr_den;

    config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );

    psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_CHROMAFMT );
    if( !psz_tmp )
        goto error;
    else if( !strcmp( psz_tmp, "420" ) ) {
        p_enc->fmt_in.i_codec = VLC_CODEC_I420;
        p_enc->fmt_in.video.i_bits_per_pixel = 12;
        p_sys->ctx.src_params.chroma = format420;
        p_sys->i_buffer_in = p_enc->fmt_in.video.i_width * p_enc->fmt_in.video.i_height * 3 / 2;
    }
    else if( !strcmp( psz_tmp, "422" ) ) {
        p_enc->fmt_in.i_codec = VLC_CODEC_I422;
        p_enc->fmt_in.video.i_bits_per_pixel = 16;
        p_sys->ctx.src_params.chroma = format422;
        p_sys->i_buffer_in = p_enc->fmt_in.video.i_width * p_enc->fmt_in.video.i_height * 2;
    }
    else if( !strcmp( psz_tmp, "444" ) ) {
        p_enc->fmt_in.i_codec = VLC_CODEC_I444;
        p_enc->fmt_in.video.i_bits_per_pixel = 24;
        p_sys->ctx.src_params.chroma = format444;
        p_sys->i_buffer_in = p_enc->fmt_in.video.i_width * p_enc->fmt_in.video.i_height * 3;
    }
    else {
        msg_Err( p_enc, "Invalid chroma format: %s", psz_tmp );
        free( psz_tmp );
        goto error;
    }
    free( psz_tmp );

    p_sys->ctx.enc_params.qf = var_GetFloat( p_enc, ENC_CFG_PREFIX ENC_QUALITY_FACTOR );

    /* use bitrate from sout-transcode-vb in kbps */
    p_sys->ctx.enc_params.trate = p_enc->fmt_out.i_bitrate / 1000;
    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_TARGETRATE );
    if( i_tmp > -1 )
        p_sys->ctx.enc_params.trate = i_tmp;
    p_enc->fmt_out.i_bitrate = p_sys->ctx.enc_params.trate * 1000;

    p_sys->ctx.enc_params.lossless = var_GetBool( p_enc, ENC_CFG_PREFIX ENC_LOSSLESS );

    psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_PREFILTER );
    if( !psz_tmp )
        goto error;
    else if( !strcmp( psz_tmp, "none" ) ) {
        p_sys->ctx.enc_params.prefilter = NO_PF;
    }
    else if( !strcmp( psz_tmp, "cwm" ) ) {
        p_sys->ctx.enc_params.prefilter = CWM;
    }
    else if( !strcmp( psz_tmp, "rectlp" ) ) {
        p_sys->ctx.enc_params.prefilter = RECTLP;
    }
    else if( !strcmp( psz_tmp, "diaglp" ) ) {
        p_sys->ctx.enc_params.prefilter = DIAGLP;
    }
    else {
        msg_Err( p_enc, "Invalid prefilter: %s", psz_tmp );
        free( psz_tmp );
        goto error;
    }
    free( psz_tmp );

    p_sys->ctx.enc_params.prefilter_strength =
        var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_PREFILTER_STRENGTH );

    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_L1SEP );
    if( i_tmp > -1 )
        p_sys->ctx.enc_params.L1_sep = i_tmp;

    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_L1NUM );
    if( i_tmp > -1 )
        p_sys->ctx.enc_params.num_L1 = i_tmp;

    psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_CODINGMODE );
    if( !psz_tmp )
        goto error;
    else if( !strcmp( psz_tmp, "auto" ) ) {
        p_sys->b_auto_field_coding = true;
    }
    else if( !strcmp( psz_tmp, "progressive" ) ) {
        p_sys->b_auto_field_coding = false;
        p_sys->ctx.enc_params.picture_coding_mode = 0;
    }
    else if( !strcmp( psz_tmp, "field" ) ) {
        p_sys->b_auto_field_coding = false;
        p_sys->ctx.enc_params.picture_coding_mode = 1;
    }
    else {
        msg_Err( p_enc, "Invalid codingmode: %s", psz_tmp );
        free( psz_tmp );
        goto error;
    }
    free( psz_tmp );

    psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_MVPREC );
    if( !psz_tmp )
        goto error;
    else if( !strcmp( psz_tmp, "1" ) ) {
        p_sys->ctx.enc_params.mv_precision = MV_PRECISION_PIXEL;
    }
    else if( !strcmp( psz_tmp, "1/2" ) ) {
        p_sys->ctx.enc_params.mv_precision = MV_PRECISION_HALF_PIXEL;
    }
    else if( !strcmp( psz_tmp, "1/4" ) ) {
        p_sys->ctx.enc_params.mv_precision = MV_PRECISION_QUARTER_PIXEL;
    }
    else if( !strcmp( psz_tmp, "1/8" ) ) {
        p_sys->ctx.enc_params.mv_precision = MV_PRECISION_EIGHTH_PIXEL;
    }
    else {
        msg_Err( p_enc, "Invalid mv-prec: %s", psz_tmp );
        free( psz_tmp );
        goto error;
    }
    free( psz_tmp );

    /*
     * {x,y}b{len,sep} must be multiples of 4
     */
    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MCBLK_WIDTH );
    if( i_tmp > -1 )
        p_sys->ctx.enc_params.xbsep = i_tmp / 4 * 4;

    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MCBLK_HEIGHT );
    if( i_tmp > -1 )
        p_sys->ctx.enc_params.ybsep = i_tmp / 4 * 4;

    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MCBLK_OVERLAP );
    if( i_tmp > -1 ) {
        p_sys->ctx.enc_params.xblen = p_sys->ctx.enc_params.xbsep * (100 + i_tmp) / 400 * 4;
        p_sys->ctx.enc_params.yblen = p_sys->ctx.enc_params.ybsep * (100 + i_tmp) / 400 * 4;
    }

    /*
     * {x,y}blen >= {x,y}bsep
     * {x,y}blen <= 2* {x,y}bsep
     */
    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MCBLK_XBLEN );
    if( i_tmp > -1 ) {
        int xblen = __MAX( i_tmp, p_sys->ctx.enc_params.xbsep );
        xblen = __MIN( xblen, 2 * p_sys->ctx.enc_params.xbsep );
        p_sys->ctx.enc_params.xblen = xblen;
    }

    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MCBLK_YBLEN );
    if( i_tmp > -1 ) {
        int yblen = __MAX( i_tmp, p_sys->ctx.enc_params.ybsep );
        yblen = __MIN( yblen, 2 * p_sys->ctx.enc_params.ybsep );
        p_sys->ctx.enc_params.yblen = yblen;
    }

    psz_tmp = var_GetString( p_enc, ENC_CFG_PREFIX ENC_ME_SIMPLESEARCH );
    if( !psz_tmp )
        goto error;
    if( *psz_tmp != '\0' ) {
        /* of the form [0-9]+:[0-9]+ */
        char *psz_start = psz_tmp;
        char *psz_end = psz_tmp;
        p_sys->ctx.enc_params.x_range_me = strtol(psz_start, &psz_end, 10);
        if( *psz_end != ':'  || psz_end == psz_start ) {
            msg_Err( p_enc, "Invalid simple search range: %s", psz_tmp );
            free( psz_tmp );
            goto error;
        }
        psz_start = ++psz_end;
        p_sys->ctx.enc_params.y_range_me = strtol(psz_start, &psz_end, 10);
        if( *psz_end != '\0'  || psz_end == psz_start ) {
            msg_Err( p_enc, "Invalid simple search range: %s", psz_tmp );
            free( psz_tmp );
            goto error;
        }
        if( p_sys->ctx.enc_params.x_range_me < 0 ||
            p_sys->ctx.enc_params.y_range_me < 0 )
        {
            msg_Err( p_enc, "Invalid negative simple search range: %s", psz_tmp );
            free( psz_tmp );
            goto error;
        }
        p_sys->ctx.enc_params.full_search = 1;
    }
    free( psz_tmp );

#if DIRAC_RESEARCH_VERSION_ATLEAST(1,0,1)
    p_sys->ctx.enc_params.combined_me = var_GetBool( p_enc, ENC_CFG_PREFIX ENC_ME_COMBINED );
#endif

    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_DWTINTRA );
    if( i_tmp > -1 )
        p_sys->ctx.enc_params.intra_wlt_filter = i_tmp;

    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_DWTINTER );
    if( i_tmp > -1 )
        p_sys->ctx.enc_params.inter_wlt_filter = i_tmp;

    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_DWTDEPTH );
    if( i_tmp > -1 )
        p_sys->ctx.enc_params.wlt_depth = i_tmp;

    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_MULTIQUANT );
    if( i_tmp > -1 )
        p_sys->ctx.enc_params.multi_quants = i_tmp;

    i_tmp = var_GetInteger( p_enc, ENC_CFG_PREFIX ENC_SPARTITION );
    if( i_tmp > -1 )
        p_sys->ctx.enc_params.spatial_partition = i_tmp;

    p_sys->ctx.enc_params.using_ac = !var_GetBool( p_enc, ENC_CFG_PREFIX ENC_NOAC );

    f_tmp = var_GetFloat( p_enc, ENC_CFG_PREFIX ENC_CPD );
    if( f_tmp > -1 )
        p_sys->ctx.enc_params.cpd = f_tmp;

    /* Allocate the buffer for inputing frames into the encoder */
    if( ( p_sys->p_buffer_in = malloc( p_sys->i_buffer_in ) ) == NULL )
    {
        CloseEncoder( p_this );
        return VLC_ENOMEM;
    }

    /* Set up output buffer */
    /* Unfortunately it isn't possible to determine if the buffer
     * is too small (and then reallocate it) */
    p_sys->i_buffer_out = 4096 + p_sys->i_buffer_in;
    if( ( p_sys->p_buffer_out = malloc( p_sys->i_buffer_out ) ) == NULL )
    {
        CloseEncoder( p_this );
        return VLC_ENOMEM;
    }

    return VLC_SUCCESS;
error:
    CloseEncoder( p_this );
    return VLC_EGENERIC;
}
Exemplo n.º 6
0
static int OpenEncoder( vlc_object_t *p_this )
{
    encoder_t *p_enc = (encoder_t*)p_this;
    encoder_sys_t *p_sys;

    /* FIXME: what about layers 1 and 2 ? shine is an 'MP3' encoder */
    if( p_enc->fmt_out.i_codec != VLC_CODEC_MP3 ||
        p_enc->fmt_out.audio.i_channels > 2 )
        return VLC_EGENERIC;

    /* Shine is strict on its input */
    if( p_enc->fmt_in.audio.i_channels != 2 )
    {
        msg_Err( p_enc, "Only stereo input is accepted, rejecting %d channels",
            p_enc->fmt_in.audio.i_channels );
        return VLC_EGENERIC;
    }

    if( p_enc->fmt_out.i_bitrate <= 0 )
    {
        msg_Err( p_enc, "unknown bitrate" );
        return VLC_EGENERIC;
    }

    msg_Dbg( p_enc, "bitrate %d, samplerate %d, channels %d",
             p_enc->fmt_out.i_bitrate, p_enc->fmt_out.audio.i_rate,
             p_enc->fmt_out.audio.i_channels );

    vlc_mutex_lock( &entrant.lock );
    if( entrant.busy )
    {
        msg_Err( p_enc, "encoder already in progress" );
        vlc_mutex_unlock( &entrant.lock );
        return VLC_EGENERIC;
    }
    entrant.busy = true;
    vlc_mutex_unlock( &entrant.lock );

    p_enc->p_sys = p_sys = calloc( 1, sizeof( *p_sys ) );
    if( !p_sys )
        goto enomem;

    if( !( p_sys->p_fifo = block_FifoNew() ) )
    {
        free( p_sys );
        goto enomem;
    }

    init_mp3_encoder_engine( p_enc->fmt_out.audio.i_rate,
        p_enc->fmt_out.audio.i_channels, p_enc->fmt_out.i_bitrate / 1000 );

    p_enc->pf_encode_audio = EncodeFrame;
    p_enc->fmt_out.i_cat = AUDIO_ES;

    return VLC_SUCCESS;

enomem:
    vlc_mutex_lock( &entrant.lock );
    entrant.busy = false;
    vlc_mutex_unlock( &entrant.lock );
    return VLC_ENOMEM;
}
Exemplo n.º 7
0
/*****************************************************************************
 * Open: open the rtmp connection
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    sout_access_out_t *p_access = (sout_access_out_t *) p_this;
    sout_access_out_sys_t *p_sys;
    char *psz, *p;
    int length_path, length_media_name;
    int i;

    if( !( p_sys = calloc ( 1, sizeof( sout_access_out_sys_t ) ) ) )
        return VLC_ENOMEM;
    p_access->p_sys = p_sys;

    p_sys->p_thread =
        vlc_object_create( p_access, sizeof( rtmp_control_thread_t ) );
    if( !p_sys->p_thread )
    {
        free( p_sys );
        return VLC_ENOMEM;
    }
    vlc_object_attach( p_sys->p_thread, p_access );

    /* Parse URI - remove spaces */
    p = psz = strdup( p_access->psz_path );
    while( ( p = strchr( p, ' ' ) ) != NULL )
        *p = '+';
    vlc_UrlParse( &p_sys->p_thread->url, psz, 0 );
    free( psz );

    if( p_sys->p_thread->url.psz_host == NULL
        || *p_sys->p_thread->url.psz_host == '\0' )
    {
         msg_Warn( p_access, "invalid host" );
         goto error;
    }

    if( p_sys->p_thread->url.i_port <= 0 )
        p_sys->p_thread->url.i_port = 1935;

    if ( p_sys->p_thread->url.psz_path == NULL )
    {
        msg_Warn( p_access, "invalid path" );
        goto error;
    }

    length_path = strlen( p_sys->p_thread->url.psz_path );
    char* psz_tmp = strrchr( p_sys->p_thread->url.psz_path, '/' );
    if( !psz_tmp )
        goto error;
    length_media_name = strlen( psz_tmp ) - 1;

    p_sys->p_thread->psz_application = strndup( p_sys->p_thread->url.psz_path + 1, length_path - length_media_name - 2 );
    p_sys->p_thread->psz_media = strdup( p_sys->p_thread->url.psz_path + ( length_path - length_media_name ) );

    msg_Dbg( p_access, "rtmp: host='%s' port=%d path='%s'",
             p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port, p_sys->p_thread->url.psz_path );

    if( p_sys->p_thread->url.psz_username && *p_sys->p_thread->url.psz_username )
    {
        msg_Dbg( p_access, "      user='******'", p_sys->p_thread->url.psz_username );
    }

    /* Initialize thread variables */
    p_sys->p_thread->b_error= 0;
    p_sys->p_thread->p_fifo_input = block_FifoNew();
    p_sys->p_thread->p_empty_blocks = block_FifoNew();
    p_sys->p_thread->has_audio = 0;
    p_sys->p_thread->has_video = 0;
    p_sys->p_thread->metadata_received = 0;
    p_sys->p_thread->first_media_packet = 1;
    p_sys->p_thread->flv_tag_previous_tag_size = 0x00000000; /* FLV_TAG_FIRST_PREVIOUS_TAG_SIZE */

    p_sys->p_thread->flv_body = rtmp_body_new( -1 );
    p_sys->p_thread->flv_length_body = 0;

    p_sys->p_thread->chunk_size_recv = 128; /* RTMP_DEFAULT_CHUNK_SIZE */
    p_sys->p_thread->chunk_size_send = 128; /* RTMP_DEFAULT_CHUNK_SIZE */
    for(i = 0; i < 64; i++)
    {
        memset( &p_sys->p_thread->rtmp_headers_recv[i], 0, sizeof( rtmp_packet_t ) );
        p_sys->p_thread->rtmp_headers_send[i].length_header = -1;
        p_sys->p_thread->rtmp_headers_send[i].stream_index = -1;
        p_sys->p_thread->rtmp_headers_send[i].timestamp = -1;
        p_sys->p_thread->rtmp_headers_send[i].timestamp_relative = -1;
        p_sys->p_thread->rtmp_headers_send[i].length_encoded = -1;
        p_sys->p_thread->rtmp_headers_send[i].length_body = -1;
        p_sys->p_thread->rtmp_headers_send[i].content_type = -1;
        p_sys->p_thread->rtmp_headers_send[i].src_dst = -1;
        p_sys->p_thread->rtmp_headers_send[i].body = NULL;
    }

    vlc_cond_init( &p_sys->p_thread->wait );
    vlc_mutex_init( &p_sys->p_thread->lock );

    p_sys->p_thread->result_connect = 1;
    /* p_sys->p_thread->result_publish = only used on access */
    p_sys->p_thread->result_play = 1;
    p_sys->p_thread->result_stop = 0;
    p_sys->p_thread->fd = -1;

    /* Open connection */
    if( var_CreateGetBool( p_access, "rtmp-connect" ) > 0 )
    {
#if 0
        p_sys->p_thread->fd = net_ConnectTCP( p_access,
                                              p_sys->p_thread->url.psz_host,
                                              p_sys->p_thread->url.i_port );
#endif
        msg_Err( p_access, "to be implemented" );
        goto error2;
    }
    else
    {
        int *p_fd_listen;

        p_sys->active = 0;
        p_fd_listen = net_ListenTCP( p_access, p_sys->p_thread->url.psz_host,
                                     p_sys->p_thread->url.i_port );
        if( p_fd_listen == NULL )
        {
            msg_Warn( p_access, "cannot listen to %s port %i",
                      p_sys->p_thread->url.psz_host,
                      p_sys->p_thread->url.i_port );
            goto error2;
        }

        do
            p_sys->p_thread->fd = net_Accept( p_access, p_fd_listen );
        while( p_sys->p_thread->fd == -1 );
        net_ListenClose( p_fd_listen );

        if( rtmp_handshake_passive( p_this, p_sys->p_thread->fd ) < 0 )
        {
            msg_Err( p_access, "handshake passive failed");
            goto error2;
        }
    }

    if( vlc_clone( &p_sys->p_thread->thread, ThreadControl, p_sys->p_thread,
                   VLC_THREAD_PRIORITY_INPUT ) )
    {
        msg_Err( p_access, "cannot spawn rtmp control thread" );
        goto error2;
    }

    if( !p_sys->active )
    {
        if( rtmp_connect_passive( p_sys->p_thread ) < 0 )
        {
            msg_Err( p_access, "connect passive failed");
            vlc_cancel( p_sys->p_thread->thread );
            vlc_join( p_sys->p_thread->thread, NULL );
            goto error2;
        }
    }

    p_access->pf_write = Write;
    p_access->pf_seek = Seek;

    return VLC_SUCCESS;

error2:
    vlc_cond_destroy( &p_sys->p_thread->wait );
    vlc_mutex_destroy( &p_sys->p_thread->lock );

    free( p_sys->p_thread->psz_application );
    free( p_sys->p_thread->psz_media );

    if( p_sys->p_thread->fd != -1 )
        net_Close( p_sys->p_thread->fd );
error:
    vlc_UrlClean( &p_sys->p_thread->url );
    vlc_object_release( p_sys->p_thread );
    free( p_sys );

    return VLC_EGENERIC;
}
Exemplo n.º 8
0
static int OpenEncoder( vlc_object_t *p_this )
{
    encoder_t *p_enc = (encoder_t*)p_this;
    encoder_sys_t *p_sys;

    /* shine is an 'MP3' encoder */
    if( (p_enc->fmt_out.i_codec != VLC_CODEC_MP3 && p_enc->fmt_out.i_codec != VLC_CODEC_MPGA) ||
        p_enc->fmt_out.audio.i_channels > 2 )
        return VLC_EGENERIC;

    /* Shine is strict on its input */
    if( p_enc->fmt_in.audio.i_channels != 2 )
    {
        msg_Err( p_enc, "Only stereo input is accepted, rejecting %d channels",
            p_enc->fmt_in.audio.i_channels );
        return VLC_EGENERIC;
    }

    if( p_enc->fmt_out.i_bitrate <= 0 )
    {
        msg_Err( p_enc, "unknown bitrate" );
        return VLC_EGENERIC;
    }

    msg_Dbg( p_enc, "bitrate %d, samplerate %d, channels %d",
             p_enc->fmt_out.i_bitrate, p_enc->fmt_out.audio.i_rate,
             p_enc->fmt_out.audio.i_channels );

    vlc_mutex_lock( &entrant.lock );
    if( entrant.busy )
    {
        msg_Err( p_enc, "encoder already in progress" );
        vlc_mutex_unlock( &entrant.lock );
        return VLC_EGENERIC;
    }
    entrant.busy = true;
    vlc_mutex_unlock( &entrant.lock );

    p_enc->p_sys = p_sys = calloc( 1, sizeof( *p_sys ) );
    if( !p_sys )
        goto enomem;

    if( !( p_sys->p_fifo = block_FifoNew() ) )
    {
        free( p_sys );
        goto enomem;
    }

    shine_config_t cfg = {
        .wave = {
            .channels = p_enc->fmt_out.audio.i_channels,
            .samplerate = p_enc->fmt_out.audio.i_rate,
        },
    };

    shine_set_config_mpeg_defaults(&cfg.mpeg);
    cfg.mpeg.bitr = p_enc->fmt_out.i_bitrate / 1000;
 
    if (shine_check_config(cfg.wave.samplerate, cfg.mpeg.bitr) == -1) {
        msg_Err(p_enc, "Invalid bitrate %d\n", cfg.mpeg.bitr);
        free(p_sys);
        return VLC_EGENERIC;
    }

    p_sys->s = shine_initialise(&cfg);
    p_sys->samples_per_frame = shine_samples_per_pass(p_sys->s);

    p_enc->pf_encode_audio = EncodeFrame;
    p_enc->fmt_out.i_cat = AUDIO_ES;

    p_enc->fmt_in.i_codec = VLC_CODEC_S16N;

    return VLC_SUCCESS;

enomem:
    vlc_mutex_lock( &entrant.lock );
    entrant.busy = false;
    vlc_mutex_unlock( &entrant.lock );
    return VLC_ENOMEM;
}
Exemplo n.º 9
0
Arquivo: udp.c Projeto: qdk0901/vlc
/*****************************************************************************
 * Open: open the file
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    sout_access_out_t       *p_access = (sout_access_out_t*)p_this;
    sout_access_out_sys_t   *p_sys;

    char                *psz_dst_addr = NULL;
    int                 i_dst_port;

    int                 i_handle;

    config_ChainParse( p_access, SOUT_CFG_PREFIX,
                       ppsz_sout_options, p_access->p_cfg );
    config_ChainParse( p_access, "",
                       ppsz_core_options, p_access->p_cfg );

    if (var_Create (p_access, "dst-port", VLC_VAR_INTEGER)
     || var_Create (p_access, "src-port", VLC_VAR_INTEGER)
     || var_Create (p_access, "dst-addr", VLC_VAR_STRING)
     || var_Create (p_access, "src-addr", VLC_VAR_STRING))
    {
        return VLC_ENOMEM;
    }

    if( !( p_sys = malloc ( sizeof( *p_sys ) ) ) )
        return VLC_ENOMEM;
    p_access->p_sys = p_sys;

    i_dst_port = DEFAULT_PORT;
    char *psz_parser = psz_dst_addr = strdup( p_access->psz_path );
    if( !psz_dst_addr )
    {
        free( p_sys );
        return VLC_ENOMEM;
    }

    if (psz_parser[0] == '[')
        psz_parser = strchr (psz_parser, ']');

    psz_parser = strchr (psz_parser ? psz_parser : psz_dst_addr, ':');
    if (psz_parser != NULL)
    {
        *psz_parser++ = '\0';
        i_dst_port = atoi (psz_parser);
    }

    i_handle = net_ConnectDgram( p_this, psz_dst_addr, i_dst_port, -1,
                                 IPPROTO_UDP );
    free (psz_dst_addr);

    if( i_handle == -1 )
    {
         msg_Err( p_access, "failed to create raw UDP socket" );
         free (p_sys);
         return VLC_EGENERIC;
    }
    else
    {
        char addr[NI_MAXNUMERICHOST];
        int port;

        if (net_GetSockAddress (i_handle, addr, &port) == 0)
        {
            msg_Dbg (p_access, "source: %s port %d", addr, port);
            var_SetString (p_access, "src-addr", addr);
            var_SetInteger (p_access, "src-port", port);
        }

        if (net_GetPeerAddress (i_handle, addr, &port) == 0)
        {
            msg_Dbg (p_access, "destination: %s port %d", addr, port);
            var_SetString (p_access, "dst-addr", addr);
            var_SetInteger (p_access, "dst-port", port);
        }
    }
    shutdown( i_handle, SHUT_RD );

    p_sys->i_caching = UINT64_C(1000)
                     * var_GetInteger( p_access, SOUT_CFG_PREFIX "caching");
    p_sys->i_handle = i_handle;
    p_sys->i_mtu = var_CreateGetInteger( p_this, "mtu" );
    p_sys->b_mtu_warning = false;
    p_sys->p_fifo = block_FifoNew();
    p_sys->p_empty_blocks = block_FifoNew();
    p_sys->p_buffer = NULL;

    if( vlc_clone( &p_sys->thread, ThreadWrite, p_access,
                           VLC_THREAD_PRIORITY_HIGHEST ) )
    {
        msg_Err( p_access, "cannot spawn sout access thread" );
        block_FifoRelease( p_sys->p_fifo );
        block_FifoRelease( p_sys->p_empty_blocks );
        net_Close (i_handle);
        free (p_sys);
        return VLC_EGENERIC;
    }

    p_access->pf_write = Write;
    p_access->pf_seek = Seek;
    p_access->pf_control = Control;

    return VLC_SUCCESS;
}