+
+static int rtp_packetize_t140( sout_stream_t *p_stream, sout_stream_id_t *id,
+ block_t *in )
+{
+ const size_t i_max = id->i_mtu - 12;
+ const uint8_t *p_data = in->p_buffer;
+ size_t i_data = in->i_buffer;
+
+ for( unsigned i_packet = 0; i_data > 0; i_packet++ )
+ {
+ size_t i_payload = i_data;
+
+ /* Make sure we stop on an UTF-8 character boundary
+ * (assuming the input is valid UTF-8) */
+ if( i_data > i_max )
+ {
+ i_payload = i_max;
+
+ while( ( p_data[i_payload] & 0xC0 ) == 0x80 )
+ {
+ if( i_payload == 0 )
+ return VLC_SUCCESS; /* fishy input! */
+
+ i_payload--;
+ }
+ }
+
+ block_t *out = block_New( p_stream, 12 + i_payload );
+ if( out == NULL )
+ return VLC_SUCCESS;
+
+ rtp_packetize_common( id, out, 0, in->i_pts + i_packet );
+ memcpy( out->p_buffer + 12, p_data, i_payload );
+
+ out->i_buffer = 12 + i_payload;
+ out->i_dts = out->i_pts;
+ out->i_length = 0;
+
+ rtp_packetize_send( id, out );
+
+ p_data += i_payload;
+ i_data -= i_payload;
+ }
+
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Non-RTP mux
+ *****************************************************************************/
+
+/** Add an ES to a non-RTP muxed stream */
+static sout_stream_id_t *MuxAdd( sout_stream_t *p_stream, es_format_t *p_fmt )
+{
+ sout_input_t *p_input;
+ sout_mux_t *p_mux = p_stream->p_sys->p_mux;
+ assert( p_mux != NULL );
+
+ p_input = sout_MuxAddStream( p_mux, p_fmt );
+ if( p_input == NULL )
+ {
+ msg_Err( p_stream, "cannot add this stream to the muxer" );
+ return NULL;
+ }
+
+ return (sout_stream_id_t *)p_input;
+}
+
+
+static int MuxSend( sout_stream_t *p_stream, sout_stream_id_t *id,
+ block_t *p_buffer )
+{
+ sout_mux_t *p_mux = p_stream->p_sys->p_mux;
+ assert( p_mux != NULL );
+
+ sout_MuxSendBuffer( p_mux, (sout_input_t *)id, p_buffer );
+ return VLC_SUCCESS;
+}
+
+
+/** Remove an ES from a non-RTP muxed stream */
+static int MuxDel( sout_stream_t *p_stream, sout_stream_id_t *id )
+{
+ sout_mux_t *p_mux = p_stream->p_sys->p_mux;
+ assert( p_mux != NULL );
+
+ sout_MuxDeleteStream( p_mux, (sout_input_t *)id );
+ return VLC_SUCCESS;
+}
+
+
+static int AccessOutGrabberWriteBuffer( sout_stream_t *p_stream,
+ const block_t *p_buffer )
+{
+ sout_stream_sys_t *p_sys = p_stream->p_sys;
+ sout_stream_id_t *id = p_sys->es[0];
+
+ int64_t i_dts = p_buffer->i_dts;
+
+ uint8_t *p_data = p_buffer->p_buffer;
+ unsigned int i_data = p_buffer->i_buffer;
+ unsigned int i_max = id->i_mtu - 12;
+
+ unsigned i_packet = ( p_buffer->i_buffer + i_max - 1 ) / i_max;
+
+ while( i_data > 0 )
+ {
+ unsigned int i_size;
+
+ /* output complete packet */
+ if( p_sys->packet &&
+ p_sys->packet->i_buffer + i_data > i_max )
+ {
+ rtp_packetize_send( id, p_sys->packet );
+ p_sys->packet = NULL;
+ }
+
+ if( p_sys->packet == NULL )
+ {
+ /* allocate a new packet */
+ p_sys->packet = block_New( p_stream, id->i_mtu );
+ rtp_packetize_common( id, p_sys->packet, 1, i_dts );
+ p_sys->packet->i_dts = i_dts;
+ p_sys->packet->i_length = p_buffer->i_length / i_packet;
+ i_dts += p_sys->packet->i_length;
+ }
+
+ i_size = __MIN( i_data,
+ (unsigned)(id->i_mtu - p_sys->packet->i_buffer) );
+
+ memcpy( &p_sys->packet->p_buffer[p_sys->packet->i_buffer],
+ p_data, i_size );
+
+ p_sys->packet->i_buffer += i_size;
+ p_data += i_size;
+ i_data -= i_size;
+ }
+
+ return VLC_SUCCESS;
+}
+
+
+static int AccessOutGrabberWrite( sout_access_out_t *p_access,
+ block_t *p_buffer )
+{
+ sout_stream_t *p_stream = (sout_stream_t*)p_access->p_sys;
+
+ while( p_buffer )
+ {
+ block_t *p_next;
+
+ AccessOutGrabberWriteBuffer( p_stream, p_buffer );
+
+ p_next = p_buffer->p_next;
+ block_Release( p_buffer );
+ p_buffer = p_next;
+ }
+
+ return VLC_SUCCESS;
+}
+
+
+static sout_access_out_t *GrabberCreate( sout_stream_t *p_stream )
+{
+ sout_access_out_t *p_grab;
+
+ p_grab = vlc_object_create( p_stream->p_sout, sizeof( *p_grab ) );
+ if( p_grab == NULL )
+ return NULL;
+
+ p_grab->p_module = NULL;
+ p_grab->p_sout = p_stream->p_sout;
+ p_grab->psz_access = strdup( "grab" );
+ p_grab->p_cfg = NULL;
+ p_grab->psz_path = strdup( "" );
+ p_grab->p_sys = (sout_access_out_sys_t *)p_stream;
+ p_grab->pf_seek = NULL;
+ p_grab->pf_write = AccessOutGrabberWrite;
+ return p_grab;
+}