/***************************************************************************** * 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; }
/***************************************************************************** * 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; }
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; }
/** * 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; }
/***************************************************************************** * 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; }
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; }
/***************************************************************************** * 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; }
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; }
/***************************************************************************** * 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; }