char const* OnDemandServerMediaSubsession::sdpLines() { if (fSDPLines == NULL) { // We need to construct a set of SDP lines that describe this // subsession (as a unicast stream). To do so, we first create // dummy (unused) source and "RTPSink" objects, // whose parameters we use for the SDP lines: unsigned estBitrate; FramedSource* inputSource = createNewStreamSource(0, estBitrate); if (inputSource == NULL) return NULL; // file not found struct in_addr dummyAddr; dummyAddr.s_addr = 0; Groupsock dummyGroupsock(envir(), dummyAddr, 0, 0); unsigned char rtpPayloadType = 96 + trackNumber()-1; // if dynamic RTPSink* dummyRTPSink = createNewRTPSink(&dummyGroupsock, rtpPayloadType, inputSource); setSDPLinesFromRTPSink(dummyRTPSink, inputSource, estBitrate); Medium::close(dummyRTPSink); closeStreamSource(inputSource); } return fSDPLines; }
char const* EncoderMediaSubsession::sdpLines() { if (fSDPLines == NULL) { // We need to construct a set of SDP lines that describe this // subsession (as a unicast stream). To do so, we first create // dummy (unused) source and "RTPSink" objects, // whose parameters we use for the SDP lines: unsigned estBitrate; if (!fMediaSource) { if (fIsAudio) fMediaSource = createNewAudioSource(0, estBitrate); else fMediaSource = createNewVideoSource(0, estBitrate); } if (fMediaSource == NULL) return NULL; // file not found struct in_addr dummyAddr; dummyAddr.s_addr = 0; Groupsock dummyGroupsock(envir(), dummyAddr, 0, 0); unsigned char rtpPayloadType = 96 + trackNumber()-1; // if dynamic RTPSink* dummyRTPSink = createNewRTPSink(&dummyGroupsock, rtpPayloadType, fMediaSource); if (!fIsAudio) { Debug(ckite_log_message, "setVideoSize fWidth = %d, fHeight = %d\n", fWidth, fHeight); #ifdef SDKH264 ((H264VideoRTPSink*)dummyRTPSink)->setVideoSize(fWidth, fHeight); // set video size #else ((MPEG4ESVideoRTPSink*)dummyRTPSink)->setVideoSize(fWidth, fHeight); // set video size #endif } setSDPLinesFromRTPSink(dummyRTPSink, fMediaSource, estBitrate); Medium::close(dummyRTPSink); closeStreamSource(fMediaSource); fMediaSource = NULL; } return fSDPLines; }
void OnDemandServerMediaSubsession ::getStreamParameters(unsigned clientSessionId, netAddressBits clientAddress, Port const& clientRTPPort, Port const& clientRTCPPort, int tcpSocketNum, unsigned char rtpChannelId, unsigned char rtcpChannelId, netAddressBits& destinationAddress, u_int8_t& /*destinationTTL*/, Boolean& isMulticast, Port& serverRTPPort, Port& serverRTCPPort, void*& streamToken) { if (destinationAddress == 0) destinationAddress = clientAddress; struct in_addr destinationAddr; destinationAddr.s_addr = destinationAddress; isMulticast = False; if (fLastStreamToken != NULL && fReuseFirstSource) { // Special case: Rather than creating a new 'StreamState', // we reuse the one that we've already created: serverRTPPort = ((StreamState*)fLastStreamToken)->serverRTPPort(); serverRTCPPort = ((StreamState*)fLastStreamToken)->serverRTCPPort(); ++((StreamState*)fLastStreamToken)->referenceCount(); streamToken = fLastStreamToken; } else { // Normal case: Create a new media source: unsigned streamBitrate; FramedSource* mediaSource = createNewStreamSource(clientSessionId, streamBitrate); // Create 'groupsock' and 'sink' objects for the destination, // using previously unused server port numbers: RTPSink* rtpSink; BasicUDPSink* udpSink; Groupsock* rtpGroupsock; Groupsock* rtcpGroupsock; portNumBits serverPortNum; if (clientRTCPPort.num() == 0) { // We're streaming raw UDP (not RTP). Create a single groupsock: NoReuse dummy(envir()); // ensures that we skip over ports that are already in use for (serverPortNum = fInitialPortNum; ; ++serverPortNum) { struct in_addr dummyAddr; dummyAddr.s_addr = 0; serverRTPPort = serverPortNum; rtpGroupsock = new Groupsock(envir(), dummyAddr, serverRTPPort, 255); if (rtpGroupsock->socketNum() >= 0) break; // success } rtcpGroupsock = NULL; rtpSink = NULL; udpSink = BasicUDPSink::createNew(envir(), rtpGroupsock); } else { // Normal case: We're streaming RTP (over UDP or TCP). Create a pair of // groupsocks (RTP and RTCP), with adjacent port numbers (RTP port number even): NoReuse dummy(envir()); // ensures that we skip over ports that are already in use for (portNumBits serverPortNum = fInitialPortNum; ; serverPortNum += 2) { struct in_addr dummyAddr; dummyAddr.s_addr = 0; serverRTPPort = serverPortNum; rtpGroupsock = new Groupsock(envir(), dummyAddr, serverRTPPort, 255); if (rtpGroupsock->socketNum() < 0) { delete rtpGroupsock; continue; // try again } serverRTCPPort = serverPortNum+1; rtcpGroupsock = new Groupsock(envir(), dummyAddr, serverRTCPPort, 255); if (rtcpGroupsock->socketNum() < 0) { delete rtpGroupsock; delete rtcpGroupsock; continue; // try again } break; // success } unsigned char rtpPayloadType = 96 + trackNumber()-1; // if dynamic rtpSink = createNewRTPSink(rtpGroupsock, rtpPayloadType, mediaSource); udpSink = NULL; } // Turn off the destinations for each groupsock. They'll get set later // (unless TCP is used instead): if (rtpGroupsock != NULL) rtpGroupsock->removeAllDestinations(); if (rtcpGroupsock != NULL) rtcpGroupsock->removeAllDestinations(); if (rtpGroupsock != NULL) { // Try to use a big send buffer for RTP - at least 0.1 second of // specified bandwidth and at least 50 KB unsigned rtpBufSize = streamBitrate * 25 / 2; // 1 kbps * 0.1 s = 12.5 bytes if (rtpBufSize < 50 * 1024) rtpBufSize = 50 * 1024; increaseSendBufferTo(envir(), rtpGroupsock->socketNum(), rtpBufSize); } // Set up the state of the stream. The stream will get started later: streamToken = fLastStreamToken = new StreamState(*this, serverRTPPort, serverRTCPPort, rtpSink, udpSink, streamBitrate, mediaSource, rtpGroupsock, rtcpGroupsock); } // Record these destinations as being for this client session id: Destinations* destinations; if (tcpSocketNum < 0) { // UDP destinations = new Destinations(destinationAddr, clientRTPPort, clientRTCPPort); } else { // TCP destinations = new Destinations(tcpSocketNum, rtpChannelId, rtcpChannelId); } fDestinationsHashTable->Add((char const*)clientSessionId, destinations); }
qint32 cMediaInfo::writeFilename() { QSqlQuery query; query.prepare("SELECT id FROM file WHERE fileName=:fileName AND fileSize=:fileSize AND fileDate=:fileDate;"); query.bindValue(":fileName", fileName()); query.bindValue(":fileSize", fileSize()); query.bindValue(":fileDate", fileDate()); if(!query.exec()) { myDebug << query.lastError().text(); return(-1); } if(query.next()) query.prepare("UPDATE file SET fileType=:fileType, length=:length, bitrate=:bitrate, sampleRate=:sampleRate, channels=:channels, bitsPerSample=:bitsPerSample, layer=:layer, version=:version, sampleWidth=:sampleWidth, sampleFrames=:sampleFrames, isEncrypted=:isEncrypted, trackGain=:trackGain, albumGain=:albumGain, trackPeak=:trackPeak, albumPeak=:albumPeak, protectionEnabled=:protectionEnabled, channelMode=:channelMode, isCopyrighted=:isCopyrighted, isOriginal=:isOriginal, album=:album, title=:title, copyright=:copyright, trackNumber=:trackNumber, contentGroupDescription=:contentGroupDescription, subTitle=:subTitle, originalAlbum=:originalAlbum, partOfSet=:partOfSet, subTitleOfSet=:subTitleOfSet, internationalStandardRecordingCode=:internationalStandardRecordingCode, leadArtist=:leadArtist, band=:band, conductor=:conductor, interpret=:interpret, originalArtist=:originalArtist, textWriter=:textWriter, originalTextWriter=:originalTextWriter, composer=:composer, encodedBy=:encodedBy, beatsPerMinute=:beatsPerMinute, language=:language, contentType=:contentType, mediaType=:mediaType, mood=:mood, producedNotice=:producedNotice, publisher=:publisher, fileOwner=:fileOwner, internetRadioStationName=:internetRadioStationName, internetRadioStationOwner=:internetRadioStationOwner, originalFilename=:originalFilename, playlistDelay=:playlistDelay, encodingTime=:encodingTime, originalReleaseTime=:originalReleaseTime, recordingTime=:recordingTime, releaseTime=:releaseTime, taggingTime=:taggingTime, swhwSettings=:swhwSettings, albumSortOrder=:albumSortOrder, performerSortOrder=:performerSortOrder, titleSortOrder=:titleSortOrder, synchronizedLyrics=:synchronizedLyrics, unsynchronizedLyrics=:unsynchronizedLyrics WHERE filename=:filename AND filesize=:filesize AND filedate=:filedate;"); else query.prepare("INSERT INTO file (fileName, fileSize, fileDate, fileType, length, bitrate, sampleRate, channels, bitsPerSample, layer, version, sampleWidth, sampleFrames, isEncrypted, trackGain, albumGain, trackPeak, albumPeak, protectionEnabled, channelMode, isCopyrighted, isOriginal, album, title, copyright, trackNumber, contentGroupDescription, subTitle, originalAlbum, partOfSet, subTitleOfSet, internationalStandardRecordingCode, leadArtist, band, conductor, interpret, originalArtist, textWriter, originalTextWriter, composer, encodedBy, beatsPerMinute, language, contentType, mediaType, mood, producedNotice, publisher, fileOwner, internetRadioStationName, internetRadioStationOwner, originalFilename, playlistDelay, encodingTime, originalReleaseTime, recordingTime, releaseTime, taggingTime, swhwSettings, albumSortOrder, performerSortOrder, titleSortOrder, synchronizedLyrics, unsynchronizedLyrics) VALUES (:fileName, :fileSize, :fileDate, :fileType, :length, :bitrate, :sampleRate, :channels, :bitsPerSample, :layer, :version, :sampleWidth, :sampleFrames, :isEncrypted, :trackGain, :albumGain, :trackPeak, :albumPeak, :protectionEnabled, :channelMode, :isCopyrighted, :isOriginal, :album, :title, :copyright, :trackNumber, :contentGroupDescription, :subTitle, :originalAlbum, :partOfSet, :subTitleOfSet, :internationalStandardRecordingCode, :leadArtist, :band, :conductor, :interpret, :originalArtist, :textWriter, :originalTextWriter, :composer, :encodedBy, :beatsPerMinute, :language, :contentType, :mediaType, :mood, :producedNotice, :publisher, :fileOwner, :internetRadioStationName, :internetRadioStationOwner, :originalFilename, :playlistDelay, :encodingTime, :originalReleaseTime, :recordingTime, :releaseTime, :taggingTime, :swhwSettings, :albumSortOrder, :performerSortOrder, :titleSortOrder, :synchronizedLyrics, :unsynchronizedLyrics);"); query.bindValue(":fileName", fileName()); query.bindValue(":fileSize", fileSize()); query.bindValue(":fileDate", fileDate()); query.bindValue(":fileType", fileType()); query.bindValue(":length", length()); query.bindValue(":bitrate", bitrate()); query.bindValue(":sampleRate", sampleRate()); query.bindValue(":channels", channels()); query.bindValue(":bitsPerSample", bitsPerSample()); query.bindValue(":layer", layer()); query.bindValue(":version", version()); query.bindValue(":sampleWidth", sampleWidth()); query.bindValue(":sampleFrames", sampleFrames()); query.bindValue(":isEncrypted", isEncrypted()); query.bindValue(":trackGain", trackGain()); query.bindValue(":albumGain", albumGain()); query.bindValue(":trackPeak", trackPeak()); query.bindValue(":albumPeak", albumPeak()); query.bindValue(":protectionEnabled", protectionEnabled()); query.bindValue(":channelMode", channelMode()); query.bindValue(":isCopyrighted", isCopyrighted()); query.bindValue(":isOriginal", isOriginal()); query.bindValue(":album", album()); query.bindValue(":title", title()); query.bindValue(":copyright", copyright()); query.bindValue(":trackNumber", trackNumber()); query.bindValue(":contentGroupDescription", contentGroupDescription()); query.bindValue(":subTitle", subTitle()); query.bindValue(":originalAlbum", originalAlbum()); query.bindValue(":partOfSet", partOfSet()); query.bindValue(":subTitleOfSet", subTitleOfSet()); query.bindValue(":internationalStandardRecordingCode", internationalStandardRecordingCode()); query.bindValue(":leadArtist", leadArtist()); query.bindValue(":band", band()); query.bindValue(":conductor", conductor()); query.bindValue(":interpret", interpret().join(", ")); query.bindValue(":originalArtist", originalArtist()); query.bindValue(":textWriter", textWriter()); query.bindValue(":originalTextWriter", originalTextWriter()); query.bindValue(":composer", composer()); query.bindValue(":encodedBy", encodedBy()); query.bindValue(":beatsPerMinute", beatsPerMinute()); query.bindValue(":language", language().join(", ")); query.bindValue(":contentType", contentType().join(", ")); query.bindValue(":mediaType", mediaType().join(", ")); query.bindValue(":mood", mood()); query.bindValue(":producedNotice", producedNotice()); query.bindValue(":publisher", publisher()); query.bindValue(":fileOwner", fileOwner()); query.bindValue(":internetRadioStationName", internetRadioStationName()); query.bindValue(":internetRadioStationOwner", internetRadioStationOwner()); query.bindValue(":originalFilename", originalFilename()); query.bindValue(":playlistDelay", playlistDelay()); query.bindValue(":encodingTime", encodingTime()); query.bindValue(":originalReleaseTime", originalReleaseTime()); query.bindValue(":recordingTime", recordingTime()); query.bindValue(":releaseTime", releaseTime()); query.bindValue(":taggingTime", taggingTime()); query.bindValue(":swhwSettings", swhwSettings().join(", ")); query.bindValue(":albumSortOrder", albumSortOrder()); query.bindValue(":performerSortOrder", performerSortOrder()); query.bindValue(":titleSortOrder", titleSortOrder()); query.bindValue(":synchronizedLyrics", synchronizedLyrics().join()); query.bindValue(":unsynchronizedLyrics", unsynchronizedLyrics().join("||")); if(!query.exec()) { myDebug << query.lastError().text(); return(-1); } query.prepare("SELECT id FROM file WHERE fileName=:fileName AND fileSize=:fileSize AND fileDate=:fileDate;"); query.bindValue(":fileName", fileName()); query.bindValue(":fileSize", fileSize()); query.bindValue(":fileDate", fileDate()); if(!query.exec()) { myDebug << query.lastError().text(); return(-1); } if(query.next()) return(query.value("id").toInt()); return(-1); }