00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "MPEG4GenericRTPSink.hh"
00022
00023 MPEG4GenericRTPSink
00024 ::MPEG4GenericRTPSink(UsageEnvironment& env, Groupsock* RTPgs,
00025 u_int8_t rtpPayloadFormat,
00026 u_int32_t rtpTimestampFrequency,
00027 char const* sdpMediaTypeString,
00028 char const* mpeg4Mode, char const* configString,
00029 unsigned numChannels)
00030 : MultiFramedRTPSink(env, RTPgs, rtpPayloadFormat,
00031 rtpTimestampFrequency, "MPEG4-GENERIC", numChannels),
00032 fSDPMediaTypeString(strDup(sdpMediaTypeString)),
00033 fMPEG4Mode(strDup(mpeg4Mode)), fConfigString(strDup(configString)) {
00034
00035 if (mpeg4Mode == NULL) {
00036 env << "MPEG4GenericRTPSink error: NULL \"mpeg4Mode\" parameter\n";
00037 } else if (strcmp(mpeg4Mode, "AAC-hbr") != 0) {
00038 env << "MPEG4GenericRTPSink error: Unknown \"mpeg4Mode\" parameter: \""
00039 << mpeg4Mode << "\"\n";
00040 }
00041
00042
00043 char const* fmtpFmt =
00044 "a=fmtp:%d "
00045 "streamtype=%d;profile-level-id=1;"
00046 "mode=%s;sizelength=13;indexlength=3;indexdeltalength=3;"
00047 "config=%s\r\n";
00048 unsigned fmtpFmtSize = strlen(fmtpFmt)
00049 + 3
00050 + 3
00051 + strlen(fMPEG4Mode)
00052 + strlen(fConfigString);
00053 char* fmtp = new char[fmtpFmtSize];
00054 sprintf(fmtp, fmtpFmt,
00055 rtpPayloadType(),
00056 strcmp(fSDPMediaTypeString, "video") == 0 ? 4 : 5,
00057 fMPEG4Mode,
00058 fConfigString);
00059 fFmtpSDPLine = strDup(fmtp);
00060 delete[] fmtp;
00061 }
00062
00063 MPEG4GenericRTPSink::~MPEG4GenericRTPSink() {
00064 delete[] fFmtpSDPLine;
00065 delete[] (char*)fConfigString;
00066 delete[] (char*)fMPEG4Mode;
00067 delete[] (char*)fSDPMediaTypeString;
00068 }
00069
00070 MPEG4GenericRTPSink*
00071 MPEG4GenericRTPSink::createNew(UsageEnvironment& env, Groupsock* RTPgs,
00072 u_int8_t rtpPayloadFormat,
00073 u_int32_t rtpTimestampFrequency,
00074 char const* sdpMediaTypeString,
00075 char const* mpeg4Mode,
00076 char const* configString, unsigned numChannels) {
00077 return new MPEG4GenericRTPSink(env, RTPgs, rtpPayloadFormat,
00078 rtpTimestampFrequency,
00079 sdpMediaTypeString, mpeg4Mode,
00080 configString, numChannels);
00081 }
00082
00083 Boolean MPEG4GenericRTPSink
00084 ::frameCanAppearAfterPacketStart(unsigned char const* ,
00085 unsigned ) const {
00086
00087 return False;
00088 }
00089
00090 void MPEG4GenericRTPSink
00091 ::doSpecialFrameHandling(unsigned fragmentationOffset,
00092 unsigned char* frameStart,
00093 unsigned numBytesInFrame,
00094 struct timeval frameTimestamp,
00095 unsigned numRemainingBytes) {
00096
00097
00098
00099 unsigned fullFrameSize
00100 = fragmentationOffset + numBytesInFrame + numRemainingBytes;
00101 unsigned char headers[4];
00102 headers[0] = 0; headers[1] = 16 ;
00103 headers[2] = fullFrameSize >> 5; headers[3] = (fullFrameSize&0x1F)<<3;
00104
00105 setSpecialHeaderBytes(headers, sizeof headers);
00106
00107 if (numRemainingBytes == 0) {
00108
00109
00110 setMarkerBit();
00111 }
00112
00113
00114
00115 MultiFramedRTPSink::doSpecialFrameHandling(fragmentationOffset,
00116 frameStart, numBytesInFrame,
00117 frameTimestamp,
00118 numRemainingBytes);
00119 }
00120
00121 unsigned MPEG4GenericRTPSink::specialHeaderSize() const {
00122 return 2 + 2;
00123 }
00124
00125 char const* MPEG4GenericRTPSink::sdpMediaType() const {
00126 return fSDPMediaTypeString;
00127 }
00128
00129 char const* MPEG4GenericRTPSink::auxSDPLine() {
00130 return fFmtpSDPLine;
00131 }