/*returns TRUE if the packet is ok to be sent to output queue*/ static bool_t receiver_check_payload_type(MSFilter *f, ReceiverData *d, mblk_t *m){ int ptn=rtp_get_payload_type(m); PayloadType *pt; if (ptn==d->current_pt) return TRUE; pt=rtp_profile_get_payload(rtp_session_get_profile(d->session), ptn); if (pt==NULL){ ms_warning("Discarding packet with unknown payload type %i",ptn); return FALSE; } if (strcasecmp(pt->mime_type,"CN")==0){ MSCngData cngdata; uint8_t *data=NULL; int datasize=rtp_get_payload(m, &data); if (data){ if (datasize<= sizeof(cngdata.data)){ memcpy(cngdata.data, data, datasize); cngdata.datasize=datasize; ms_filter_notify(f, MS_RTP_RECV_GENERIC_CN_RECEIVED, &cngdata); }else{ ms_warning("CN packet has unexpected size %i", datasize); } } return FALSE; } d->current_pt = ptn; return TRUE; }
static void receiver_process(MSFilter * f) { ReceiverData *d = (ReceiverData *) f->data; mblk_t *m; uint32_t timestamp; if (d->session == NULL) return; timestamp = (uint32_t) (f->ticker->time * (d->rate/1000)); while ((m = rtp_session_recvm_with_ts(d->session, timestamp)) != NULL) { mblk_set_timestamp_info(m, rtp_get_timestamp(m)); mblk_set_marker_info(m, rtp_get_markbit(m)); mblk_set_payload_type(m, rtp_get_payload_type(m)); rtp_get_payload(m,&m->b_rptr); ms_queue_put(f->outputs[0], m); } }
int main(int argc, char **argv) { MastTool* tool = NULL; mblk_t* packet = NULL; mblk_t* body = NULL; PayloadType* pt = NULL; int payload_size = 0; // Create an RTP session tool = new MastTool( MAST_TOOL_NAME, RTP_SESSION_RECVONLY ); if (tool==NULL) return -1; // Parse the command line arguments // and configure the session parse_cmd_line( argc, argv, tool->get_session() ); // Setup signal handlers mast_setup_signals(); // Recieve a single packet packet = tool->wait_for_rtp_packet(); if (packet == NULL) MAST_FATAL("Failed to receive a packet"); body = packet->b_cont; payload_size = (body->b_wptr - body->b_rptr); // Display information about the packet received printf("\n"); printf("RTP Header\n"); printf("==========\n"); printf("Payload type : %u\n", rtp_get_payload_type( packet ) ); printf("Payload size : %u bytes\n", payload_size ); printf("Sequence Number : %u\n", rtp_get_seqnumber( packet ) ); printf("Timestamp : %u\n", rtp_get_timestamp( packet ) ); printf("SSRC Identifier : %x\n", rtp_get_ssrc( packet ) ); printf("Marker Bit : %s\n", rtp_get_markbit( packet ) ? "Set" : "Not Set"); printf("\n"); // Lookup the payload type pt = rtp_profile_get_payload( tool->get_profile(), rtp_get_payload_type( packet ) ); if (pt == NULL) { MAST_WARNING( "Payload type %u isn't registered with oRTP", rtp_get_payload_type( packet ) ); } else { const char* mime_major = "?"; printf("Payload Details\n"); printf("===============\n"); if (pt->type==PAYLOAD_AUDIO_CONTINUOUS) mime_major = "audio"; else if (pt->type==PAYLOAD_AUDIO_PACKETIZED) mime_major = "audio"; else if (pt->type==PAYLOAD_VIDEO) mime_major = "video"; printf("Mime Type : %s/%s\n", mime_major, pt->mime_type); if (pt->clock_rate) printf("Clock Rate : %u Hz\n", pt->clock_rate); if (pt->channels) printf("Channels : %u\n", pt->channels); if (pt->bits_per_sample) printf("Bits per Sample : %u\n", pt->bits_per_sample); if (pt->normal_bitrate) { printf("Normal Bitrate : %u kbps\n", (pt->normal_bitrate/1000)); printf("Packet duration : %u ms\n", (payload_size*1000)/(pt->normal_bitrate/8) ); } if (pt->recv_fmtp) printf("Recieve FMTP : %s\n", pt->recv_fmtp); if (pt->send_fmtp) printf("Send FMTP : %s\n", pt->send_fmtp); printf("\n"); } // Parse the MPEG Audio header if (rtp_get_payload_type( packet ) == RTP_MPEG_AUDIO_PT) { /* FIXME: check fragment offset header (see rfc2250) */ unsigned char* mpa_ptr = body->b_rptr + 4; MPA_Header mh; printf("MPEG Audio Header\n"); printf("=================\n"); if (!mh.parse( mpa_ptr )) { MAST_WARNING("Failed to parse MPEG Audio header"); } else { mh.debug( stdout ); } } // Close RTP session delete tool; // Success ! return 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; }
static int rtp_write_header(AVFormatContext *s1) { RTPDemuxContext *s = s1->priv_data; int payload_type, max_packet_size, n; AVStream *st; if (s1->nb_streams != 1) return -1; st = s1->streams[0]; payload_type = rtp_get_payload_type(st->codec); if (payload_type < 0) payload_type = RTP_PT_PRIVATE; /* private payload type */ s->payload_type = payload_type; // following 2 FIXMEs could be set based on the current time, there is normally no info leak, as RTP will likely be transmitted immediately s->base_timestamp = 0; /* FIXME: was random(), what should this be? */ s->timestamp = s->base_timestamp; s->cur_timestamp = 0; s->ssrc = 0; /* FIXME: was random(), what should this be? */ s->first_packet = 1; s->first_rtcp_ntp_time = AV_NOPTS_VALUE; max_packet_size = url_fget_max_packet_size(s1->pb); if (max_packet_size <= 12) return AVERROR(EIO); s->max_payload_size = max_packet_size - 12; s->max_frames_per_packet = 0; if (s1->max_delay) { if (st->codec->codec_type == CODEC_TYPE_AUDIO) { if (st->codec->frame_size == 0) { av_log(s1, AV_LOG_ERROR, "Cannot respect max delay: frame size = 0\n"); } else { s->max_frames_per_packet = av_rescale_rnd(s1->max_delay, st->codec->sample_rate, AV_TIME_BASE * st->codec->frame_size, AV_ROUND_DOWN); } } if (st->codec->codec_type == CODEC_TYPE_VIDEO) { /* FIXME: We should round down here... */ s->max_frames_per_packet = av_rescale_q(s1->max_delay, (AVRational){1, 1000000}, st->codec->time_base); } } av_set_pts_info(st, 32, 1, 90000); switch(st->codec->codec_id) { case CODEC_ID_MP2: case CODEC_ID_MP3: s->buf_ptr = s->buf + 4; break; case CODEC_ID_MPEG1VIDEO: case CODEC_ID_MPEG2VIDEO: break; case CODEC_ID_MPEG2TS: n = s->max_payload_size / TS_PACKET_SIZE; if (n < 1) n = 1; s->max_payload_size = n * TS_PACKET_SIZE; s->buf_ptr = s->buf; break; case CODEC_ID_AAC: s->read_buf_index = 0; default: if (st->codec->codec_type == CODEC_TYPE_AUDIO) { av_set_pts_info(st, 32, 1, st->codec->sample_rate); } s->buf_ptr = s->buf; break; } return 0; }