void test_rtp_frame(struct UdpSocket *sock) { static uint32_t framecounter = 0; static uint32_t timecounter = 0; static uint8_t toggle = 0; toggle = ! toggle; uint8_t format_code = 0x01; uint8_t quality_code = 0x54; if (toggle) { send_rtp_packet(sock, JpegScanDataCh2A,KJpegCh2ScanDataLen,framecounter, timecounter, 0, 1, 64, 48, format_code, quality_code, 0); } else { send_rtp_packet(sock, JpegScanDataCh2B,KJpegCh2ScanDataLen,framecounter, timecounter, 0, 1, 64, 48, format_code, quality_code, 0); } framecounter++; timecounter+=3600; }
void send_rtp_frame(struct UdpSocket *sock, uint8_t * Jpeg, uint32_t JpegLen, int w, int h, uint8_t format_code, uint8_t quality_code, uint8_t has_dri_header, uint32_t delta_t) { static uint32_t packetcounter = 0; static uint32_t timecounter = 0; uint32_t offset = 0; #define MAX_PACKET_SIZE 1400 if (delta_t <= 0) { struct timeval tv; gettimeofday(&tv, 0); uint32_t t = (tv.tv_sec % (256*256)) * 90000 + tv.tv_usec * 9 / 100; timecounter = t; } // Split frame into packets for (;JpegLen > 0;) { uint32_t len = MAX_PACKET_SIZE; uint8_t lastpacket = 0; if (JpegLen <= len) { lastpacket = 1; len = JpegLen; } send_rtp_packet(sock, Jpeg,len,packetcounter, timecounter, offset, lastpacket, w, h, format_code, quality_code, has_dri_header); JpegLen -= len; Jpeg += len; offset += len; packetcounter++; } if (delta_t > 0) { // timestamp = 1 / 90 000 seconds timecounter+=delta_t; } }
static int mpv_send( struct rtp_endpoint *ep, void *d ) { struct rtp_mpv *out = (struct rtp_mpv *)d; int i, j, space, off, min_space; struct iovec v[48]; unsigned char vhdr[4]; /* MPEG video header always follows the RTP header */ PUT_16( vhdr, out->temporal_reference ); vhdr[2] = out->picture_type; /* will be different for each frame */ vhdr[3] = out->vectors; v[1].iov_base = vhdr; v[1].iov_len = 4; i = 0; j = 2; space = ep->max_data_size - 4; /* If this is an I frame, insert the saved Video Sequence Header */ if( out->picture_type == 1 ) { vhdr[2] |= 0x20; /* Sequence-header-present bit */ /* add the block to the frame */ v[j].iov_base = out->vsh; v[j].iov_len = out->vsh_len; space -= v[j].iov_len; ++j; } for( i = 0; i < out->blk_count; ++i ) { /* We can fragment slices, but after the initial fragment, * all the remaining fragments must be put into their own * packets. This means fragmentation only makes sense if * the slice is larger than our MTU. */ if( out->blk[i].len > ep->max_data_size - 4 ) min_space = 4; else min_space = out->blk[i].len; /* If we don't have enough space for this entire block, or if * we're fragmenting and we don't have enough space for the * start code, first send out the previous blocks. */ if( space < min_space ) { if( send_rtp_packet( ep, v, j, out->timestamp, 0 ) < 0 ) return -1; j = 2; vhdr[2] = out->picture_type; space = ep->max_data_size - 4; } /* add the block to the frame */ v[j].iov_base = out->blk[i].d; v[j].iov_len = out->blk[i].len; /* if this is a slice, set the Beginning-of-slice bit */ if( out->blk[i].d[3] > 0 && out->blk[i].d[3] <= 0xAF ) vhdr[2] |= 0x10; /* if the entire block fit, go on to the next block */ if( v[j].iov_len <= space ) { /* if this is a slice, set the End-of-slice bit */ if( out->blk[i].d[3] > 0 && out->blk[i].d[3] <= 0xAF ) vhdr[2] |= 0x08; space -= v[j].iov_len; ++j; continue; } /* block did not fit, so send the first fragment */ v[j].iov_len = space; /* the last byte of the packet is not the end of a slice, so * clear the End-of-slice bit */ vhdr[2] &= ~0x08; if( send_rtp_packet( ep, v, j + 1, out->timestamp, 0 ) < 0 ) return -1; /* send all remaining fragments by themselves */ for( off = space; off < out->blk[i].len; off += v[2].iov_len ) { vhdr[2] = out->picture_type; v[2].iov_base = out->blk[i].d + off; v[2].iov_len = out->blk[i].len - off; if( v[2].iov_len > ep->max_data_size - 4 ) v[2].iov_len = ep->max_data_size - 4; else vhdr[2] |= 0x08; /* End-of-slice bit */ if( send_rtp_packet( ep, v, 3, out->timestamp, ( vhdr[2] & 0x08 ) && ( ( i + 1 ) == out->blk_count ) ) < 0 ) return -1; } j = 2; vhdr[2] = out->picture_type; space = ep->max_data_size - 4; } /* send any unsent blocks */ if( j > 2 && send_rtp_packet( ep, v, j, out->timestamp, 1 ) < 0 ) return -1; return 0; }