int WriteRTPNALU (VideoParameters *p_Vid, NALU_t *n, FILE **f_rtp) { RTPpacket_t *p; byte first_byte; assert ((*f_rtp) != NULL); assert (n != NULL); assert (n->len < 65000); first_byte = (byte) (n->forbidden_bit << 7 | n->nal_reference_idc << 5 | n->nal_unit_type ); // Set RTP structure elements and alloca() memory foor the buffers if ((p = (RTPpacket_t *) malloc (sizeof (RTPpacket_t))) == NULL) no_mem_exit ("RTPWriteNALU-1"); if ((p->packet = malloc (MAXRTPPACKETSIZE)) == NULL) no_mem_exit ("RTPWriteNALU-2"); if ((p->payload = malloc (MAXRTPPACKETSIZE)) == NULL) no_mem_exit ("RTPWriteNALU-3"); p->v=2; p->p=0; p->x=0; p->cc=0; p->m=(n->startcodeprefix_len==4)&1; // a long startcode of Annex B sets marker bit of RTP // Not exactly according to the RTP paylaod spec, but // good enough for now (hopefully). //! For error resilience work, we need the correct //! marker bit. Introduce a nalu->marker and set it in //! terminate_slice()? p->pt=H264PAYLOADTYPE; p->seq = p_Vid->CurrentRTPSequenceNumber++; p->timestamp = p_Vid->CurrentRTPTimestamp; p->ssrc=H264SSRC; p->paylen = 1 + n->len; p->payload[0] = first_byte; memcpy (p->payload+1, n->buf, n->len); // Generate complete RTP packet if (ComposeRTPPacket (p) < 0) { printf ("Cannot compose RTP packet, exit\n"); exit (-1); } if (WriteRTPPacket (p, *f_rtp) < 0) { printf ("Cannot write %d bytes of RTP packet to outfile, exit\n", p->packlen); exit (-1); } free (p->packet); free (p->payload); free (p); return (n->len * 8); }
int aggregationRTPWriteBits (int Marker, int PacketType, int subPacketType, void * bitstream, int BitStreamLenInByte, FILE *out) { RTPpacket_t *p; int offset; // printf( "writing aggregation packet...\n"); assert (out != NULL); assert (BitStreamLenInByte < 65000); assert (bitstream != NULL); assert ((PacketType&0xf) == 4); // Set RTP structure elements and alloca() memory foor the buffers p = (RTPpacket_t *) alloca (sizeof (RTPpacket_t)); p->packet=alloca (MAXRTPPACKETSIZE); p->payload=alloca (MAXRTPPACKETSIZE); p->v=2; p->p=0; p->x=0; p->cc=0; p->m=Marker&1; p->pt=H26LPAYLOADTYPE; p->seq=CurrentRTPSequenceNumber++; p->timestamp=CurrentRTPTimestamp; p->ssrc=H26LSSRC; offset = 0; p->payload[offset++] = PacketType; // This is the first byte of the compound packet // FIRST, write the sei message to aggregation packet, if it is available if ( HaveAggregationSEI() ) { p->payload[offset++] = sei_message[AGGREGATION_SEI].subPacketType; // this is the first byte of the first subpacket *(short*)&(p->payload[offset]) = sei_message[AGGREGATION_SEI].payloadSize; offset += 2; memcpy (&p->payload[offset], sei_message[AGGREGATION_SEI].data, sei_message[AGGREGATION_SEI].payloadSize); offset += sei_message[AGGREGATION_SEI].payloadSize; clear_sei_message(AGGREGATION_SEI); } // SECOND, write other payload to the aggregation packet // to do ... // LAST, write the slice data to the aggregation packet p->payload[offset++] = subPacketType; // this is the first byte of the second subpacket *(short*)&(p->payload[offset]) = BitStreamLenInByte; offset += 2; memcpy (&p->payload[offset], bitstream, BitStreamLenInByte); offset += BitStreamLenInByte; p->paylen = offset; // 1 +3 +seiPayload.payloadSize +3 +BitStreamLenInByte // Now the payload is ready, we can ... // Generate complete RTP packet if (ComposeRTPPacket (p) < 0) { printf ("Cannot compose RTP packet, exit\n"); exit (-1); } if (WriteRTPPacket (p, out) < 0) { printf ("Cannot write %d bytes of RTP packet to outfile, exit\n", p->packlen); exit (-1); } return (p->packlen); }