H264FileSource::H264FileSource(const char *file) :m_reader(file) { m_speed = 1.0; m_status = 0; m_rtp_clock = 0; m_rtcp_clock = 0; unsigned int ssrc = (unsigned int)rtp_ssrc(); static struct rtp_pack_func_t s_rtpfunc = { H264FileSource::RTPAlloc, H264FileSource::RTPFree, H264FileSource::RTPPacket, }; m_rtppacker = rtp_h264_packer()->create(ssrc, (unsigned short)ssrc, RTP_PAYLOAD_H264, &s_rtpfunc, this); struct rtp_event_t event; event.on_rtcp = OnRTCPEvent; m_rtp = rtp_create(&event, this, ssrc, 90000, 4*1024); rtp_set_info(m_rtp, "RTSPServer", "szj.h264"); }
/* * [ application_name local_ip local_port cname sdp_file [-t trace_file] ] */ int main(int argc, char **argv){ /* create a rtp session, we will assign unique value to identify */ err = rtp_create(&sid); if (err) { err_handle(err); } sdp_parse(sid, argv); /* parse the sdp file */ /* The application will sleep "rtp_start_time" time if "rtp_start_time" > 0 when the application is start. * * NOTE! This is not the same with Start Time in NCTUns * EX: if the Start Time in NCTUn is 5, and rtp_start_time is 3, * then the real time to startup the applicaion is 8. */ if (rtp_start_time > 0) usleep( ((int) rtp_start_time * 1000000) ); initial_session(argc, argv, sid); /* set local receive addr, CNAME, and startup the connectoin */ if (is_audio) /* media type is audio */ delay = (ms_pkt / 1000.); else delay = (1. / framerate); err = rtp_get_sour_rtpsocket(sid, &rtp_sockt); /* get source rtp socket */ if (err) err_handle(err); err = rtp_get_sour_rtcpsocket(sid, &rtcp_sockt); /* get source rtcp socket */ if (err) err_handle(err); if (rtp_sockt > nfds || rtcp_sockt > nfds) { if (rtp_sockt > rtcp_sockt) nfds = rtp_sockt; else nfds = rtcp_sockt; } FD_ZERO(&afds); FD_ZERO(&rfds); FD_SET(rtp_sockt, &afds); FD_SET(rtcp_sockt, &afds); gettimeofday(&start_tv, NULL); starttime = (start_tv.tv_sec + start_tv.tv_usec / 1000000.); now = starttime; rtp_interval = rtp_stop_time - rtp_start_time; /* bytes of each packet = ((bits/sample) / 8 ) * (clock rate) * ( each delay of packet in sec ) */ // packet_size = (int) ( (bits_per_sample / 8.) * sampling_rate * delay); while ((now - starttime) <= rtp_interval) { memcpy(&rfds, &afds, sizeof(rfds)); err = get_rtcp_timeout(sid, &timeout_tv); /* get the send_rtcp_packet time */ if (err) err_handle(err); if (time_expire(&timeout_tv, &now_tv)) { err = rtp_check_on_expire(); /* rtcp on_expire */ if (err) err_handle(err); err = get_rtcp_timeout(sid, &timeout_tv); /* get the send_rtcp_packet time */ if (err) err_handle(err); } nexttime_tv = double_to_timeval(timeval_to_double(timeout_tv) - now); if (select(nfds + 1, &rfds, (fd_set *)0, (fd_set *)0, &nexttime_tv) < 0) { if (errno == EINTR) continue; else { printf("nexttime_tv.tv_sec = %ld\n", nexttime_tv.tv_sec); printf("nexttime_tv.tv_usec = %ld\n", nexttime_tv.tv_usec); printf("select error: %d\n", errno); } } if (FD_ISSET(rtp_sockt, &rfds)) { err = on_receive(sid, rtp_sockt, recvbuf, &recbuflen); if (err) err_handle(err); } else if (FD_ISSET(rtcp_sockt, &rfds)) { err = on_receive(sid, rtcp_sockt, recvbuf, &recbuflen); if (err) err_handle(err); } gettimeofday(&now_tv, NULL); now = (now_tv.tv_sec + now_tv.tv_usec / 1000000.); } // while ((now - starttime) <= rtp_interval) err = rtp_close_connection(sid, reason); if (err) { err_handle(err); } err = rtp_delete(sid); if (err) { err_handle(err); } return 0; }
void MP4FileSource::MP4OnVideo(void* param, uint32_t track, uint8_t object, int /*width*/, int /*height*/, const void* extra, size_t bytes) { int n = 0; MP4FileSource* self = (MP4FileSource*)param; struct media_t* m = &self->m_media[self->m_count++]; m->track = track; m->rtcp_clock = 0; m->ssrc = (uint32_t)rtp_ssrc(); m->timestamp = m->ssrc; m->bandwidth = 4 * 1024 * 1024; m->dts_first = -1; m->dts_last = -1; if (MOV_OBJECT_H264 == object) { struct mpeg4_avc_t avc; mpeg4_avc_decoder_configuration_record_load((const uint8_t*)extra, bytes, &avc); assert(avc.nb_pps + avc.nb_sps > 0); static const char* pattern = "m=video 0 RTP/AVP %d\n" "a=rtpmap:%d H264/90000\n" "a=fmtp:%d profile-level-id=%02X%02X%02X;packetization-mode=1;sprop-parameter-sets="; n = snprintf((char*)self->m_frame.buffer, sizeof(self->m_frame.buffer), pattern, RTP_PAYLOAD_H264, RTP_PAYLOAD_H264, RTP_PAYLOAD_H264, (unsigned int)avc.profile, (unsigned int)avc.compatibility, (unsigned int)avc.level); for (uint8_t i = 0; i < avc.nb_sps; i++) { if(i > 0) self->m_frame.buffer[n++] = ','; n += base64_encode((char*)self->m_frame.buffer + n, avc.sps[i].data, avc.sps[i].bytes); self->m_frame.buffer[n] = '\0'; } for (uint8_t i = 0; i < avc.nb_pps; i++) { self->m_frame.buffer[n++] = ','; n += base64_encode((char*)self->m_frame.buffer + n, avc.pps[i].data, avc.pps[i].bytes); self->m_frame.buffer[n] = '\0'; } self->m_frame.buffer[n++] = '\n'; m->frequency = 90000; m->payload = RTP_PAYLOAD_H264; snprintf(m->name, sizeof(m->name), "%s", "H264"); } else if (MOV_OBJECT_HEVC == object) { assert(0); m->frequency = 90000; m->payload = RTP_PAYLOAD_H264; snprintf(m->name, sizeof(m->name), "%s", "H265"); } else { assert(0); return; } struct rtp_payload_t rtpfunc = { MP4FileSource::RTPAlloc, MP4FileSource::RTPFree, MP4FileSource::RTPPacket, }; m->packer = rtp_payload_encode_create(m->payload, m->name, (uint16_t)m->ssrc, m->ssrc, &rtpfunc, m); struct rtp_event_t event; event.on_rtcp = OnRTCPEvent; m->rtp = rtp_create(&event, self, m->ssrc, m->frequency, m->bandwidth); n += snprintf((char*)self->m_frame.buffer + n, sizeof(self->m_frame.buffer) - n, "a=control:track%d\n", m->track); self->m_sdp += (const char*)self->m_frame.buffer; }
int main(int argc, char **argv){ /* setting commad line information */ local_ip = argv[1]; local_port = atoi(argv[2]); cname = argv[3]; proto = udp; /* create a rtp session, we will assign unique value to identify */ err = rtp_create(&sid); if (err) { err_handle(err); } sdp_parse(sid, argv); if (rtp_start_time > 0) { usleep( ((int) rtp_start_time * 1000000) ); } if ((i = initial_session(argc, argv, sid))) { printf("WARNING : initial_session warning = %d\n", i); } else { printf("initial_session is ok\n"); } if (is_audio) { delay = (ms_pkt / 1000.); } else { delay = (1. / framerate); // unit: ms/sec. we assume that 300 samples/frame, } /* bytes of each packet = ((bits/sample) / 8 ) * (clock rate) * ( each delay of packet in sec ) */ packet_size = (int) ( bits_per_sample * sampling_rate * delay / 8.); /* original_bw = min_bw = 50, so we use the same pkt size */ minbw_pktsize = packet_size; printf("bits_per_sample = %lf, (bits_per_sample/8.) = %lf\n", bits_per_sample, (bits_per_sample/8.)); printf("sampling_rate = %lf\n", sampling_rate); printf("delay = %lf\n", delay); printf("packet_size = %d\n", packet_size); fflush(stdout); /* the bandwidth wa are using, 30 = frames/sec */ cur_bw = get_cur_bw(packet_size); err = rtp_get_sour_rtpsocket(sid, &rtp_sockt); if (err) { err_handle(err); } err = rtp_get_sour_rtcpsocket(sid, &rtcp_sockt); if (err) { err_handle(err); } if (rtp_sockt > nfds || rtcp_sockt > nfds) { if (rtp_sockt > rtcp_sockt) nfds = rtp_sockt; else nfds = rtcp_sockt; } FD_ZERO(&afds); FD_ZERO(&rfds); FD_SET(rtp_sockt, &afds); FD_SET(rtcp_sockt, &afds); gettimeofday(&start_tv, NULL); starttime = (start_tv.tv_sec + start_tv.tv_usec / 1000000.); nexttime = starttime; rtp_interval = rtp_stop_time - rtp_start_time; printf("rtp_interval = %f\n", rtp_interval); fflush(stdout); while (rtp_interval >= 0) { memcpy(&rfds, &afds, sizeof(rfds)); if (RTP_MAX_PKT_SIZE < packet_size){ fprintf(stderr, "RTP_MAX_PKT_SIZE < reads\n"); continue; } addtimestamp = ((int) packet_size * (bits_per_sample / 8.) ); err = rtp_send(sid, marker, addtimestamp, codec_num, (int8 *)sendbuf, packet_size); if (err) { err_handle(err); } marker = 0; /* not the first packet of talkspurt */ rtp_interval -= delay; nexttime += delay; gettimeofday(&now_tv, NULL); now = (now_tv.tv_sec + now_tv.tv_usec / 1000000.); err = get_rtcp_timeout(sid, &timeout_tv); if (err) { err_handle(err); } while (now < nexttime) { /* send next packet until now >= nexttime */ //printf("now = %lf\n", now); //printf("nexttime = %lf\n", nexttime); if (time_expire(&timeout_tv, &now_tv)) { err = rtp_check_on_expire(); if (err) { err_handle(err); } err = get_rtcp_timeout(sid, &timeout_tv); if (err) { err_handle(err); } printf("timeval_to_double(timeout_tv) = %lf\n", timeval_to_double(timeout_tv)); } /* BECAREFUL, if we disable RTCP, the timeval we get will be 0 */ if (timeval_to_double(timeout_tv) == 0 || nexttime < timeval_to_double(timeout_tv)) { nexttime_tv = double_to_timeval(nexttime - now); } else { nexttime_tv = double_to_timeval(timeval_to_double(timeout_tv) - now); } if (select(nfds + 1, &rfds, (fd_set *)0, (fd_set *)0, &nexttime_tv) < 0) { if (errno == EINTR) continue; else { printf("nexttime_tv.tv_sec = %ld\n", nexttime_tv.tv_sec); printf("nexttime_tv.tv_usec = %ld\n", nexttime_tv.tv_usec); printf("select error: %d\n", errno); //exit(1); } } if (FD_ISSET(rtp_sockt, &rfds)) { err = on_receive(sid, rtp_sockt, recvbuf, &recbuflen); if (err) { err_handle(err); } } else if (FD_ISSET(rtcp_sockt, &rfds)) { err = on_receive(sid, rtcp_sockt, recvbuf, &recbuflen); if (err) { err_handle(err); } adapt_bw(get_recent_recv_loosrate(sid, &ssrc)); } gettimeofday(&now_tv, NULL); now = (now_tv.tv_sec + now_tv.tv_usec / 1000000.); } // while(now < nexttime) } // while (interval) err = rtp_close_connection(sid, reason); if (err) { err_handle(err); } err = rtp_delete(sid); if (err) { err_handle(err); } return 0; }
int main(int argc, char **argv){ /* create a rtp session, we will assign unique value to identify */ err = rtp_create(&sid); if (err) { err_handle(err); } sdp_parse(sid, argv); /* parse the sdp file */ /* The application will sleep "rtp_start_time" time if "rtp_start_time" > 0 when the application is start. * * NOTE! This is not the same with Start Time in NCTUns * EX: if the Start Time in NCTUn is 5, and rtp_start_time is 3, * then the real time to startup the applicaion is 8. */ if (rtp_start_time > 0) { usleep( ((int) rtp_start_time * 1000000) ); } initial_session(argc, argv, sid); /* set local receive addr, CNAME, and startup the connectoin */ if (!trans_mode) { /* throughput is static */ if (is_audio) /* media type is audio */ delay = (ms_pkt / 1000.); else delay = (1. / framerate); /* bytes of each packet = ((bits/sample) / 8 ) * (clock rate) * ( each delay of packet in sec ) */ packet_size = (int) ( (bits_per_sample / 8.) * sampling_rate * delay); if (RTP_MAX_PKT_SIZE < packet_size) { fprintf(stderr, "The packet size is bigger than RTP_MAX_PKT_SIZE\n"); exit(1); } } /* original_bw = min_bw = 50, so we use the same pkt size */ minbw_pktsize = packet_size; printf("bits_per_sample = %lf, (bits_per_sample/8.) = %lf\n", bits_per_sample, (bits_per_sample/8.)); printf("sampling_rate = %lf\n", sampling_rate); printf("delay = %lf\n", delay); printf("packet_size = %d\n", packet_size); /* the bandwidth wa are using, 30 = frames/sec */ cur_bw = get_cur_bw(packet_size); err = rtp_get_sour_rtpsocket(sid, &rtp_sockt); if (err) { err_handle(err); } err = rtp_get_sour_rtcpsocket(sid, &rtcp_sockt); if (err) { err_handle(err); } if (rtp_sockt > nfds || rtcp_sockt > nfds) { if (rtp_sockt > rtcp_sockt) nfds = rtp_sockt; else nfds = rtcp_sockt; } FD_ZERO(&afds); FD_ZERO(&rfds); FD_SET(rtp_sockt, &afds); FD_SET(rtcp_sockt, &afds); gettimeofday(&start_tv, NULL); starttime = (start_tv.tv_sec + start_tv.tv_usec / 1000000.); nexttime = starttime; rtp_interval = rtp_stop_time - rtp_start_time; printf("rtp_interval = %f\n", rtp_interval); fflush(stdout); while (rtp_interval >= 0) { memcpy(&rfds, &afds, sizeof(rfds)); if (RTP_MAX_PKT_SIZE < packet_size){ fprintf(stderr, "RTP_MAX_PKT_SIZE < reads\n"); continue; } addtimestamp = ((int) packet_size * (bits_per_sample / 8.) ); err = rtp_send(sid, marker, addtimestamp, codec_num, (int8 *)sendbuf, packet_size); if (err) { err_handle(err); } marker = 0; /* not the first packet of talkspurt */ rtp_interval -= delay; nexttime += delay; gettimeofday(&now_tv, NULL); now = (now_tv.tv_sec + now_tv.tv_usec / 1000000.); err = get_rtcp_timeout(sid, &timeout_tv); if (err) { err_handle(err); } while (now < nexttime) { /* send next packet until now >= nexttime */ //printf("now = %lf\n", now); //printf("nexttime = %lf\n", nexttime); if (time_expire(&timeout_tv, &now_tv)) { err = rtp_check_on_expire(); if (err) { err_handle(err); } err = get_rtcp_timeout(sid, &timeout_tv); if (err) { err_handle(err); } printf("timeval_to_double(timeout_tv) = %lf\n", timeval_to_double(timeout_tv)); } /* BECAREFUL, if we disable RTCP, the timeval we get will be 0 */ if (timeval_to_double(timeout_tv) == 0 || nexttime < timeval_to_double(timeout_tv)) { nexttime_tv = double_to_timeval(nexttime - now); } else { nexttime_tv = double_to_timeval(timeval_to_double(timeout_tv) - now); } if (select(nfds + 1, &rfds, (fd_set *)0, (fd_set *)0, &nexttime_tv) < 0) { if (errno == EINTR) continue; else { printf("nexttime_tv.tv_sec = %ld\n", nexttime_tv.tv_sec); printf("nexttime_tv.tv_usec = %ld\n", nexttime_tv.tv_usec); printf("select error: %d\n", errno); //exit(1); } } if (FD_ISSET(rtp_sockt, &rfds)) { err = on_receive(sid, rtp_sockt, recvbuf, &recbuflen); if (err) { err_handle(err); } } else if (FD_ISSET(rtcp_sockt, &rfds)) { err = on_receive(sid, rtcp_sockt, recvbuf, &recbuflen); if (err) { err_handle(err); } adapt_bw(get_recent_recv_loosrate(sid, &ssrc)); } gettimeofday(&now_tv, NULL); now = (now_tv.tv_sec + now_tv.tv_usec / 1000000.); } // while(now < nexttime) } // while (interval) err = rtp_close_connection(sid, reason); if (err) { err_handle(err); } err = rtp_delete(sid); if (err) { err_handle(err); } return 0; }