📄 rtphint.c
字号:
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is MPEG4IP.
*
* The Initial Developer of the Original Code is Cisco Systems Inc.
* Portions created by Cisco Systems Inc. are
* Copyright (C) Cisco Systems Inc. 2000, 2001. All Rights Reserved.
*
* Contributor(s):
* Dave Mackie dmackie@cisco.com
*/
#include "quicktime.h"
quicktime_rtp_sample_t* quicktime_get_hint_sample(u_char* hintBuf)
{
return (quicktime_rtp_sample_t*)hintBuf;
}
quicktime_rtp_packet_entry_t* quicktime_get_hint_last_packet_entry(
u_char* hintBuf)
{
quicktime_rtp_sample_t* sample = quicktime_get_hint_sample(hintBuf);
u_int16_t numPacketEntries = ntohs(sample->entryCount);
u_char* bufPtr = hintBuf + sizeof(quicktime_rtp_sample_t);
int i;
if (numPacketEntries == 0) {
return NULL;
}
for (i = 0; i < numPacketEntries - 1; i++) {
bufPtr += quicktime_get_packet_size(bufPtr);
}
return (quicktime_rtp_packet_entry_t*)bufPtr;
}
void quicktime_init_hint_sample(u_char* hintBuf, u_int* pHintBufSize)
{
quicktime_rtp_sample_t* sample = quicktime_get_hint_sample(hintBuf);
sample->entryCount = htons(0);
sample->reserved = htons(0);
(*pHintBufSize) = sizeof(quicktime_rtp_sample_t);
}
void quicktime_add_hint_packet(u_char* hintBuf, u_int* pHintBufSize,
u_int payloadNumber, u_int rtpSeqNum)
{
quicktime_rtp_sample_t* sample = quicktime_get_hint_sample(hintBuf);
quicktime_rtp_packet_entry_t* packetEntry =
(quicktime_rtp_packet_entry_t*)(hintBuf + (*pHintBufSize));
sample->entryCount = htons(ntohs(sample->entryCount) + 1);
packetEntry->relativeXmitTime = htonl(0);
packetEntry->headerInfo = htons(payloadNumber);
packetEntry->seqNum = htons(rtpSeqNum);
packetEntry->flags = htons(0);
packetEntry->numDataEntries = htons(0);
(*pHintBufSize) += sizeof(quicktime_rtp_packet_entry_t);
}
void quicktime_set_rtp_hint_timestamp_offset(u_char* hintBuf,
u_int* pHintBufSize, int offset)
{
quicktime_rtp_packet_entry_t* packetEntry =
quicktime_get_hint_last_packet_entry(hintBuf);
u_int32_t* pTlvTableSize = (u_int32_t*)
((u_char*)packetEntry + sizeof(quicktime_rtp_packet_entry_t));
quicktime_rtp_tlv_entry_t* tlvEntry = (quicktime_rtp_tlv_entry_t*)
((u_char*)pTlvTableSize + sizeof(u_int32_t));
/* nothing to do */
if (offset == 0) {
return;
}
if (ntohs(packetEntry->numDataEntries)) {
#ifdef DEBUG
printf("OOPS, have already added data to this hint packet\n");
#endif
return;
}
packetEntry->flags |= htons(1 << 2); /* signal presence of TLV */
*pTlvTableSize = htonl(16);
/* the TLV entry */
tlvEntry->size = htonl(12);
memcpy(tlvEntry->id, "rtpo", sizeof(tlvEntry->id));
*((int32_t*)&tlvEntry->data) = htonl(offset);
(*pHintBufSize) += 16;
}
void quicktime_add_hint_immed_data(u_char* hintBuf, u_int* pHintBufSize,
u_char* data, u_int length)
{
quicktime_rtp_packet_entry_t* packetEntry =
quicktime_get_hint_last_packet_entry(hintBuf);
quicktime_rtp_immed_data_entry_t* dataEntry =
(quicktime_rtp_immed_data_entry_t*)(hintBuf + (*pHintBufSize));
dataEntry->source = 1;
dataEntry->length = MIN(length, sizeof(dataEntry->data));
memcpy(dataEntry->data, data, dataEntry->length);
packetEntry->numDataEntries = htons(ntohs(packetEntry->numDataEntries) + 1);
(*pHintBufSize) += sizeof(quicktime_rtp_immed_data_entry_t);
}
void quicktime_add_hint_sample_data(u_char* hintBuf, u_int* pHintBufSize,
u_int fromSampleNum, u_int offset, u_int length)
{
quicktime_rtp_packet_entry_t* packetEntry =
quicktime_get_hint_last_packet_entry(hintBuf);
quicktime_rtp_sample_data_entry_t* dataEntry =
(quicktime_rtp_sample_data_entry_t*)(hintBuf + (*pHintBufSize));
dataEntry->source = 2;
dataEntry->trackId = 0;
dataEntry->length = htons(length);
dataEntry->fromSampleNum = htonl(fromSampleNum);
dataEntry->offset = htonl(offset);
dataEntry->bytesPerCompressionBlock = htons(0);
dataEntry->samplesPerCompressionBlock = htons(0);
packetEntry->numDataEntries = htons(ntohs(packetEntry->numDataEntries) + 1);
(*pHintBufSize) += sizeof(quicktime_rtp_sample_data_entry_t);
}
void quicktime_set_hint_Mbit(u_char* hintBuf)
{
quicktime_rtp_packet_entry_t* packetEntry =
quicktime_get_hint_last_packet_entry(hintBuf);
packetEntry->headerInfo |= htons(1 << 7);
}
void quicktime_set_hint_Bframe(u_char* hintBuf)
{
quicktime_rtp_packet_entry_t* packetEntry =
quicktime_get_hint_last_packet_entry(hintBuf);
packetEntry->flags |= htons(1 << 1);
}
void quicktime_set_hint_repeat(u_char* hintBuf)
{
quicktime_rtp_packet_entry_t* packetEntry =
quicktime_get_hint_last_packet_entry(hintBuf);
packetEntry->flags |= htons(1 << 0);
}
void quicktime_set_hint_repeat_offset(u_char* hintBuf, u_int32_t offset)
{
quicktime_rtp_packet_entry_t* packetEntry =
quicktime_get_hint_last_packet_entry(hintBuf);
packetEntry->relativeXmitTime = offset;
}
int quicktime_dump_hint_sample(u_char* hintBuf)
{
quicktime_rtp_sample_t* sample = quicktime_get_hint_sample(hintBuf);
int i, numPacketEntries;
u_char* bufPtr;
fprintf(stdout, " entryCount %u\n", ntohs(sample->entryCount));
fprintf(stdout, " reserved %u\n", ntohs(sample->reserved));
/* entryCount of quicktime_rtp_packet_entry_t follow */
numPacketEntries = ntohs(sample->entryCount);
bufPtr = hintBuf + sizeof(quicktime_rtp_sample_t);
for (i = 0; i < numPacketEntries; i++) {
fprintf(stdout, " packet %u\n", i + 1);
bufPtr += quicktime_dump_hint_packet(bufPtr);
}
/* return number of bytes dumped */
return (bufPtr - hintBuf);
}
int quicktime_dump_hint_packet(u_char* hintBuf)
{
quicktime_rtp_packet_entry_t* packetEntry =
(quicktime_rtp_packet_entry_t*)hintBuf;
u_char* bufPtr;
int i;
fprintf(stdout, " relativeXmitTime %lu\n", ntohl(packetEntry->relativeXmitTime));
fprintf(stdout, " headerInfo %x\n", packetEntry->headerInfo);
fprintf(stdout, " seqNum %u\n", ntohs(packetEntry->seqNum));
fprintf(stdout, " flags %x\n", ntohs(packetEntry->flags));
fprintf(stdout, " numDataEntries %u\n", ntohs(packetEntry->numDataEntries));
bufPtr = hintBuf + sizeof(quicktime_rtp_packet_entry_t);
/* if X bit is set in flags, TLV entries exist */
if (packetEntry->flags & htons(1 << 2)) {
u_char* tlvTableStart = bufPtr;
u_int32_t tlvTableSize = ntohl(*(u_int32_t*)bufPtr);
bufPtr += sizeof(u_int32_t);
fprintf(stdout, " tlvTableSize %u\n", tlvTableSize);
i = 1;
do {
fprintf(stdout, " tlvEntry %u\n", i);
bufPtr += quicktime_dump_hint_tlv(bufPtr);
i++;
} while (bufPtr < tlvTableStart + tlvTableSize);
}
/* numDataEntries of qt_rtp_data_entry follow */
for (i = 0; i < ntohs(packetEntry->numDataEntries); i++) {
fprintf(stdout, " dataEntry %u\n", i + 1);
bufPtr += quicktime_dump_hint_data(bufPtr);
}
/* return number of bytes dumped */
return (bufPtr - hintBuf);
}
int quicktime_dump_hint_tlv(u_char* hintBuf)
{
quicktime_rtp_tlv_entry_t* tlvEntry =
(quicktime_rtp_tlv_entry_t*)hintBuf;
fprintf(stdout, " id %.4s\n", tlvEntry->id);
if (!memcmp(tlvEntry->id, "rtpo", 4)) {
fprintf(stdout, " offset %d\n", ntohl(*(u_int32_t*)&tlvEntry->data));
}
return ntohl(tlvEntry->size);
}
int quicktime_dump_hint_data(u_char* hintBuf)
{
quicktime_rtp_data_entry_t* dataEntry =
(quicktime_rtp_data_entry_t*)hintBuf;
fprintf(stdout, " source %u\n", dataEntry->null.source);
if (dataEntry->null.source == 1) {
u_int i;
fprintf(stdout, " length %u\n", dataEntry->immed.length);
fprintf(stdout, " data ");
for (i = 0; i < MIN(dataEntry->immed.length, sizeof(dataEntry->immed.data)); i++) {
fprintf(stdout, "%x ", dataEntry->immed.data[i]);
}
fprintf(stdout, "\n");
} else if (dataEntry->null.source == 2) {
fprintf(stdout, " trackId %u\n", dataEntry->sample.trackId);
fprintf(stdout, " length %u\n", ntohs(dataEntry->sample.length));
fprintf(stdout, " fromSampleNum %u\n", ntohl(dataEntry->sample.fromSampleNum));
fprintf(stdout, " offset %u\n", ntohl(dataEntry->sample.offset));
fprintf(stdout, " bytesPerCompressionBlock %u\n", ntohs(dataEntry->sample.bytesPerCompressionBlock));
fprintf(stdout, " samplesPerCompressionBlock %u\n", ntohs(dataEntry->sample.samplesPerCompressionBlock));
}
/* return number of bytes dumped */
return sizeof(quicktime_rtp_data_entry_t);
}
int quicktime_get_hint_size(u_char* hintBuf)
{
quicktime_rtp_sample_t* sample = quicktime_get_hint_sample(hintBuf);
u_int16_t numPacketEntries = ntohs(sample->entryCount);
u_char* bufPtr = hintBuf + sizeof(quicktime_rtp_sample_t);
int i;
for (i = 0; i < numPacketEntries; i++) {
bufPtr += quicktime_get_packet_size(bufPtr);
}
return (bufPtr - hintBuf);
}
int quicktime_get_packet_entry_size(u_char* hintBuf)
{
quicktime_rtp_packet_entry_t* packetEntry =
(quicktime_rtp_packet_entry_t*)hintBuf;
u_char* bufPtr = hintBuf + sizeof(quicktime_rtp_packet_entry_t);
if (packetEntry->flags & htons(1 << 2)) {
u_int32_t tlvTableSize = ntohl(*(u_int32_t*)bufPtr);
bufPtr += tlvTableSize;
}
return (bufPtr - hintBuf);
}
int quicktime_get_packet_size(u_char* hintBuf)
{
quicktime_rtp_packet_entry_t* packetEntry =
(quicktime_rtp_packet_entry_t*)hintBuf;
u_int numDataEntries = ntohs(packetEntry->numDataEntries);
return quicktime_get_packet_entry_size(hintBuf)
+ (numDataEntries * sizeof(quicktime_rtp_data_entry_t));
}
int quicktime_get_hint_info(u_char* hintBuf, u_int hintBufSize, quicktime_hint_info_t* pHintInfo)
{
quicktime_rtp_sample_t* sample = quicktime_get_hint_sample(hintBuf);
u_int16_t numPacketEntries = ntohs(sample->entryCount);
u_char* bufPtr = hintBuf + sizeof(quicktime_rtp_sample_t);
int i, j;
memset(pHintInfo, 0, sizeof(quicktime_hint_info_t));
pHintInfo->nump = numPacketEntries;
for (i = 0; i < numPacketEntries; i++) {
quicktime_rtp_packet_entry_t* packetEntry =
(quicktime_rtp_packet_entry_t*)bufPtr;
u_int numDataEntries = ntohs(packetEntry->numDataEntries);
u_int32_t rtpPacketLength = 0;
pHintInfo->tmin = MIN(pHintInfo->tmin,
(int32_t)ntohl(packetEntry->relativeXmitTime));
pHintInfo->tmax = MAX(pHintInfo->tmax,
(int32_t)ntohl(packetEntry->relativeXmitTime));
bufPtr += quicktime_get_packet_entry_size(bufPtr);
for (j = 0; j < numDataEntries; j++) {
quicktime_rtp_data_entry_t* dataEntry =
(quicktime_rtp_data_entry_t*)bufPtr;
u_int16_t dataLength = 0;
if (dataEntry->null.source == 1) {
/* immediate data */
dataLength = dataEntry->immed.length;
pHintInfo->dimm += dataLength;
} else if (dataEntry->null.source == 2) {
/* sample data */
dataLength = ntohs(dataEntry->sample.length);
pHintInfo->dmed += dataLength;
}
rtpPacketLength += dataLength;
bufPtr += sizeof(quicktime_rtp_data_entry_t);
}
pHintInfo->trpy += RTP_HEADER_STD_SIZE + rtpPacketLength;
pHintInfo->tpyl += rtpPacketLength;
if (ntohs(packetEntry->flags) & 0x80) {
/* repeated data */
pHintInfo->drep += rtpPacketLength;
}
pHintInfo->pmax = MAX(pHintInfo->pmax,
RTP_HEADER_STD_SIZE + rtpPacketLength);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -