Example #1
0
static void parse_cmd_line(int argc, char **argv, MastSendTool* tool)
{
    int ch;


    // Parse the options/switches
    while ((ch = getopt(argc, argv, "s:t:p:o:z:d:lh?")) != -1)
        switch (ch) {
        case 's':
            tool->set_session_ssrc( optarg );
            break;
        case 't':
            tool->set_multicast_ttl( optarg );
            break;
        case 'p':
            tool->set_payload_mimetype( optarg );
            break;
        case 'o':
            tool->set_payload_mimetype_param( optarg );
            break;
        case 'z':
            tool->set_payload_size_limit( optarg );
            break;
        case 'd':
            tool->set_session_dscp( optarg );
            break;

        case 'l':
            g_loop_file = TRUE;
            break;

        case '?':
        case 'h':
        default:
            usage();
        }


    // Parse the ip address and port
    if (argc > optind) {
        tool->set_session_address( argv[optind++] );
    } else {
        MAST_ERROR("missing address/port to send to");
        usage();
    }


    // Get the input file
    if (argc > optind) {
        g_filename = argv[optind++];
    } else {
        MAST_ERROR("missing audio input filename");
        usage();
    }

}
Example #2
0
static void parse_cmd_line(int argc, char **argv, MastSendTool* tool)
{
	int ch;


	// Parse the options/switches
	while ((ch = getopt(argc, argv, "as:t:p:o:z:d:c:r:h?")) != -1)
	switch (ch) {
		case 's': tool->set_session_ssrc( optarg ); break;
		case 't': tool->set_multicast_ttl( optarg ); break;
		case 'p': tool->set_payload_mimetype( optarg ); break;
		case 'o': tool->set_payload_mimetype_param( optarg ); break;
		case 'z': tool->set_payload_size_limit( optarg ); break;
		case 'd': tool->set_session_dscp( optarg ); break;

		case 'c': tool->set_input_channels( atoi(optarg) ); break;
		case 'a': g_do_autoconnect = TRUE; break;
		case 'r': g_rb_duration = atoi(optarg); break;
		
		case '?':
		case 'h':
		default:
			usage();
	}

	// Parse the ip address and port
	if (argc > optind) {
		tool->set_session_address( argv[optind++] );
	} else {
		MAST_ERROR("missing address/port to send to");
		usage();
	}
	
}
Example #3
0
/* Wait for an RTP packet to arrive and return it */
mblk_t *MastTool::wait_for_rtp_packet( int seconds )
{
	struct timeval timeout;
	fd_set readfds;
	int retval = -1;


	/* reset the session */
	rtp_session_reset( session );
	
	/* set the timeout */
	timeout.tv_sec = seconds;
	timeout.tv_usec = 0;

	/* Watch socket to see when it has input */
	FD_ZERO(&readfds);
	FD_SET( rtp_session_get_rtp_socket(session), &readfds);
	retval = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);


	// Check return value 
	if (retval == -1) {
		MAST_ERROR("select() failed: %s", strerror(errno));
		return NULL;
	} else if (retval==0) {
		MAST_ERROR("Timed out waiting for packet after %d seconds", seconds);
		return NULL;
	}
	
	

	/* recieve packet and put it in queue */
	rtp_session_rtp_recv( session, 0 );
	
	
	/* check that there is something in the queue */
	if (qempty(&session->rtp.rq) ) {
		MAST_ERROR("Queue is empty after trying to recieve packet");
		return NULL;
	}
	
	/* take the packet off the queue and return it */
	return getq(&session->rtp.rq);

}
Example #4
0
/*
  mast_fill_input_buffer()
  Make sure input buffer if full of audio
*/
size_t mast_fill_input_buffer( MastAudioBuffer* buffer )
{
    size_t total_read = 0;
    int frames_wanted = buffer->get_write_space();
    int frames_read = 0;

    if (frames_wanted==0) {
        // No audio wanted
        MAST_DEBUG( "Tried to fill buffer when it is full" );
        return 0;
    }

    // Loop until buffer is full
    while( frames_wanted > 0 ) {
        frames_wanted = buffer->get_write_space();
        frames_read = sf_readf_float( g_input_file, buffer->get_write_ptr(), frames_wanted );

        // Add on the frames read
        if (frames_read > 0) {
            buffer->add_frames( frames_read );
            total_read += frames_read;
        }

        // Reached end of file?
        if (frames_read < frames_wanted) {
            MAST_DEBUG("Reached end of file (frames_wanted=%d, frames_read=%d)", frames_wanted, frames_read);
            if (g_loop_file) {
                // Seek back to the beginning
                if (sf_seek( g_input_file, 0, SEEK_SET )) {
                    MAST_ERROR("Failed to seek to start of file: %s", sf_strerror( g_input_file ) );
                    return 0;
                }
            } else {
                // Reached end of file (and don't want to loop)
                break;
            }
        }
    }

    if (total_read == 0) {
        MAST_ERROR("Failed to read from file: %s", sf_strerror( g_input_file ) );
    }

    return total_read;
}
Example #5
0
static void parse_cmd_line(int argc, char **argv, MastTool* tool)
{
	int ch;

	// Parse the options/switches
	while ((ch = getopt(argc, argv, "h?")) != -1)
	switch (ch) {

/* may still be useful for RTCP		
		case 't': tool->set_multicast_ttl( optarg ); break;
*/

		case '?':
		case 'h':
		default:
			usage();
	}


	// Parse the ip address and port
	if (argc > optind) {
		tool->set_session_address( argv[optind++] );
	} else {
		MAST_ERROR("missing address/port to send to");
		usage();
	}	

	// Get the output file
	if (argc > optind) {
		g_filename = argv[optind++];
	} else {
		MAST_ERROR("missing audio output filename");
		usage();
	}

}
Example #6
0
static void parse_cmd_line(int argc, char **argv, RtpSession* session)
{
    char* local_address = NULL;
    int local_port = DEFAULT_RTP_PORT;
    int ch;


    // Parse the options/switches
    while ((ch = getopt(argc, argv, "h?")) != -1)
        switch (ch) {
        // case 'T': FIXME: timeout?
        case '?':
        case 'h':
        default:
            usage();
        }


    // Parse the ip address and port
    if (argc > optind) {
        local_address = argv[optind];
        optind++;

        // Look for port in the address
        char* portstr = strchr(local_address, '/');
        if (portstr && strlen(portstr)>1) {
            *portstr = 0;
            portstr++;
            local_port = atoi(portstr);
        }

    } else {
        MAST_ERROR("missing address/port to receive from");
        usage();
    }

    // Make sure the port number is even
    if (local_port%2 == 1) local_port--;

    // Set the remote address/port
    if (rtp_session_set_local_addr( session, local_address, local_port )) {
        MAST_FATAL("Failed to set receive address/port (%s/%u)", local_address, local_port);
    } else {
        printf( "Receive address: %s/%u\n", local_address,  local_port );
    }

}
Example #7
0
int main(int argc, char **argv)
{
    MastSendTool *tool = NULL;
    SF_INFO sfinfo;


    // Create the send tool object
    tool = new MastSendTool( MAST_TOOL_NAME );
    tool->enable_scheduling();

    // Parse the command line arguments
    // and configure the session
    parse_cmd_line( argc, argv, tool );

    // Open the input file by filename
    memset( &sfinfo, 0, sizeof(sfinfo) );
    g_input_file = sf_open(g_filename, SFM_READ, &sfinfo);
    if (g_input_file == NULL) MAST_FATAL("Failed to open input file:\n%s", sf_strerror(NULL));
    tool->set_input_channels( sfinfo.channels );
    tool->set_input_samplerate( sfinfo.samplerate );

    // Display some information about the input file
    print_file_info( g_input_file, &sfinfo );

    // Setup signal handlers
    mast_setup_signals();

    // Run the main loop
    tool->run();

    // Clean up
    delete tool;


    // Close input file
    if (sf_close( g_input_file )) {
        MAST_ERROR("Failed to close input file:\n%s", sf_strerror(g_input_file));
    }


    // Success !
    return 0;
}
Example #8
0
/* Take an hex SSRC string (from command line) and set it for session */
void MastTool::set_session_ssrc( const char* ssrc_str )
{
	int ssrc = 0;
	
	// Remove 0x from the start of the string
	if (optarg[0] == '0' && (optarg[1] == 'x' || optarg[1] == 'X')) {
		ssrc_str += 2;
	}
	
	// Parse the hexadecimal number into an integer
	if (sscanf(ssrc_str, "%x", &ssrc)<=0) {
		MAST_ERROR("SSRC should be a hexadeicmal number");
		return;
	}
	
	// Set it in the session
	MAST_DEBUG( "SSRC for session set to 0x%x", ssrc );
	rtp_session_set_ssrc( session, ssrc );

}
Example #9
0
void MastSendTool::run()
{
    // Set things up
    this->prepare();

    // The main loop
    while( mast_still_running() )
    {
        int frames_read = ::mast_fill_input_buffer( input_buffer );
        int payload_bytes = 0;

        // Was there an error?
        if (frames_read < 0) break;

        // Encode audio
        payload_bytes = codec->encode_packet( input_buffer, payload_size_limit, payload_buffer );
        if (payload_bytes<0)
        {
            MAST_ERROR("Codec encode failed" );
            break;
        }

        // We used the audio up
        input_buffer->empty_buffer();

        if (payload_bytes) {
            // Send out an RTP packet
            ::rtp_session_send_with_ts(session, payload_buffer, payload_bytes, ts);

            // Calculate the timestamp increment
            ts+=((frames_read * payloadtype->clock_rate) / codec->get_samplerate());   //  * frames_per_packet;
        }


    }


}
Example #10
0
// Initialise Jack related stuff
static jack_client_t* init_jack( MastSendTool* tool ) 
{
	const char* client_name = tool->get_tool_name();
	jack_client_t* client = NULL;
	jack_status_t status;
	size_t ringbuffer_size = 0;
	int port_count = tool->get_input_channels();
	int i = 0;


    pthread_mutex_init(&g_ringbuffer_cond_mutex, NULL);
    pthread_cond_init(&g_ringbuffer_cond, NULL);

	// Register with Jack
	if ((client = jack_client_open(client_name, g_client_opt, &status)) == 0) {
		MAST_ERROR("Failed to start jack client: 0x%x", status);
		return NULL;
	} else {
		MAST_INFO( "JACK client registered as '%s'", jack_get_client_name( client ) );
	}

	// Create our input port(s)
	if (port_count==1) {
		if (!(g_jackport[0] = jack_port_register(client, "mono", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))) {
			MAST_ERROR("Cannot register mono input port");
			return NULL;
		}
	} else {
		if (!(g_jackport[0] = jack_port_register(client, "left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))) {
			MAST_ERROR("Cannot register left input port");
			return NULL;
		}
		
		if (!(g_jackport[1] = jack_port_register(client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))) {
			MAST_ERROR( "Cannot register left input port");
			return NULL;
		}
	}
	
	// Create ring buffer
	ringbuffer_size = jack_get_sample_rate( client ) * g_rb_duration * port_count * sizeof(int16_t) / 1000;
	MAST_INFO("Duration of the ring buffer is %d ms (%d bytes)", g_rb_duration, (int)ringbuffer_size );
	if (!(g_ringbuffer = jack_ringbuffer_create( ringbuffer_size ))) {
		MAST_ERROR("Cannot create ringbuffer %d", i);
		return NULL;
	}

	// Register callbacks
	jack_on_shutdown(client, shutdown_callback, tool );
	jack_set_buffer_size_callback( client, buffersize_callback, tool);
	jack_set_process_callback(client, process_callback, tool);
	
	// Create conversion buffer
	buffersize_callback( jack_get_buffer_size(client), tool );

	// Activate JACK
	if (jack_activate(client)) MAST_FATAL("Cannot activate JACK client");
	
	/* Auto connect ports ? */
	if (g_do_autoconnect) autoconnect_jack_ports( client, tool->get_input_channels() );
	
	return client;
}
Example #11
0
int main(int argc, char **argv)
{
	MastTool* tool = NULL;
	RtpProfile* profile = &av_profile;
	PayloadType* pt = NULL;
	FILE* output = NULL;
	mblk_t* packet = NULL;
	int ts_diff = 0;
	int ts = 0;

	
	// Create an RTP session
	tool = new MastTool( MAST_TOOL_NAME, RTP_SESSION_RECVONLY );
	tool->enable_scheduling();


	// Parse the command line arguments 
	// and configure the session
	parse_cmd_line( argc, argv, tool );
	

	
	
	// Recieve an initial packet
	packet = tool->wait_for_rtp_packet();
	if (packet == NULL) MAST_FATAL("Failed to receive an initial packet");
	
	// Lookup the payload type
	pt = rtp_profile_get_payload( profile, rtp_get_payload_type( packet ) );
	if (pt == NULL) MAST_FATAL( "Payload type %d isn't registered with oRTP", rtp_get_payload_type( packet ) );
	fprintf(stderr, "Payload type: %s\n", payload_type_get_rtpmap( pt ));
	
	// Work out the duration of the packet
	ts_diff = mast_rtp_packet_duration( packet );
	MAST_DEBUG("ts_diff = %d", ts_diff);


	// Open the output file
	output = open_output_file( g_filename );
	if (output==NULL) MAST_FATAL( "failed to open output file" );
	
	// We can free the packet now
	freemsg( packet );
	


	// Setup signal handlers
	mast_setup_signals();


	// The main loop
	while( mast_still_running() )
	{

		// Read in a packet
		packet = rtp_session_recvm_with_ts( tool->get_session(), ts );
		if (packet==NULL) {

			MAST_DEBUG( "packet is NULL" );

		} else {
			int data_len = mast_rtp_packet_size( packet );
			if (data_len==0) {
				MAST_WARNING("Failed to get size of packet's payload");
			} else {
				unsigned char* data_ptr = packet->b_cont->b_rptr;
				int bytes_written = 0;
				
				// Skip the extra header for MPA payload
				if (rtp_get_payload_type( packet ) == RTP_MPEG_AUDIO_PT) {
					data_ptr += 4;
					data_len -= 4;
				}
				
				// Update the timestamp difference
				ts_diff = mast_rtp_packet_duration( packet );
				MAST_DEBUG("ts_diff = %d", ts_diff);
				MAST_DEBUG("data_len = %d", data_len);

				// Write to disk
				bytes_written = fwrite( data_ptr, 1, data_len, output );
				if (bytes_written != data_len) {
					MAST_ERROR("Failed to write data to disk: %s", strerror(errno) );
					break;
				}
			}
		}
		
		// Increment the timestamp for the next packet
		ts += ts_diff;
	}


	// Close output file
	if (fclose( output )) {
		MAST_ERROR("Failed to close output file:\n%s", strerror(errno));
	}
	
	// Close RTP session
	delete tool;
	
	
	// Success
	return 0;
}