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