[Live-devel] erratic MJPEG streaming
xavier
nikoxan at mixmail.com
Tue Jul 27 21:06:48 PDT 2004
Hi Ross and thank you another time for your advise, your help's become priceless.
As you told me in your last response,
> This is easy: You are trying to simulate streaming motion-JPEG at a
> particular frame rate, so just set these parameters based on this simulated
> frame rate.
My RPVRFramedSource (derived from JPEGVideoSource) class tries to simulate a motion-JPEG
with a few or only one still image. I filled in the parameters the way you told me and now
the play function looks like this:
fFrameSize = len;
if (fFrameSize > fMaxSize)
{
fNumTruncatedBytes = fFrameSize - fMaxSize;
fFrameSize = fMaxSize;
}
memmove(fTo, strm, fFrameSize);
gettimeofday(&fPresentationTime, &quin);
fDurationInMicroseconds=100000;//10fps
nextTask()
= envir().taskScheduler().scheduleDelayedTask(0, (TaskFunc*)afterGetting,
this);
but I still got the same problems as usual: vlc gets the streaming parameters correctly,
but a green screen is displayed, whilst my image appears only from time to time. Tried it
with 4 stored frames in disk, which are delivered in order, just to see if the image
displayed would change, and it really does: my 4 images are shown fastly and green screen
again. So the situation is that sometimes I can see the stream correctly, and sometimes a
green screen or nothing appears.
Thought it was a vlc problem, but tried
openRTSP -m rtsp://217.124.80.191:7070/testStream
and *any* of the jpegs stored can be opened to see what it is being received.
As I am getting a bit of desperate, I send you the code of the server using my
RPVRFramedSource(maybe I got troubled in a silly line, but I cannot find where the problem
lies).
If it worked, could it be considered as an example of JPEGVideoSource using?
Sorry about all this messy code in my post and thank you very much for your help.
Xavier
UsageEnvironment* env;
RTPSink *mjpegSink;
RPVRFramedSource *videoRPVRSource;
// To stream using "source-specific multicast" (SSM), uncomment the following:
//#define USE_SSM 1
#ifdef USE_SSM
Boolean const isSSM = True;
#else
Boolean const isSSM = False;
#endif
// To set up an internal RTSP server, uncomment the following:
#define IMPLEMENT_RTSP_SERVER 1
// (Note that this RTSP server works for multicast only)
#ifdef IMPLEMENT_RTSP_SERVER
RTSPServer* rtspServer;
RTCPInstance* audioRTCP;
RTCPInstance* videoRTCP;
#endif
// To stream *only* MPEG "I" frames (e.g., to reduce network bandwidth),
// change the following "False" to "True":
Boolean iFramesOnly = False;
void play(); // forward
void main()
{
// Begin by setting up our usage environment:
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
env = BasicUsageEnvironment::createNew(*scheduler);
// Create 'groupsocks' for RTP and RTCP:
char* destinationAddressStr
#ifdef USE_SSM
= "232.255.42.42";
#else
= "239.255.42.42";
// Note: This is a multicast address. If you wish to stream using
// unicast instead, then replace this string with the unicast address
// of the (single) destination. (You may also need to make a similar
// change to the receiver program.)
#endif
const unsigned short rtpPortNumVideo = 8888;
const unsigned short rtcpPortNumVideo = rtpPortNumVideo+1;
const unsigned char ttl = 7; // low, in case routers don't admin scope
struct in_addr destinationAddress;
destinationAddress.s_addr = our_inet_addr(destinationAddressStr);
const Port rtpPortVideo(rtpPortNumVideo);
const Port rtcpPortVideo(rtcpPortNumVideo);
Groupsock rtpGroupsockVideo(*env, destinationAddress, rtpPortVideo, ttl);
Groupsock rtcpGroupsockVideo(*env, destinationAddress, rtcpPortVideo, ttl);
#ifdef USE_SSM
rtpGroupsockVideo.multicastSendOnly();
rtcpGroupsockVideo.multicastSendOnly();
#endif
const unsigned maxCNAMElen = 100;
unsigned char CNAME[maxCNAMElen+1];
gethostname((char*)CNAME, maxCNAMElen);
CNAME[maxCNAMElen] = '\0'; // just in case
const unsigned totalSessionBandwidthVideo = 4500; // in kbps; for RTCP b/w share
// Create a 'MJPEG Video RTP' sink from the RTP 'groupsock':
mjpegSink = JPEGVideoRTPSink::createNew(*env, &rtpGroupsockVideo);
#ifdef IMPLEMENT_RTSP_SERVER
RTCPInstance* videoRTCP =
#endif
RTCPInstance::createNew(*env, &rtcpGroupsockVideo,
totalSessionBandwidthVideo, CNAME,
mjpegSink, NULL /* we're a server */, isSSM);
// Note: This starts RTCP running automatically
#ifdef IMPLEMENT_RTSP_SERVER
rtspServer = RTSPServer::createNew(*env,7070);
// Note that this (attempts to) start a server on the default RTSP server
// port: 554. To use a different port number, add it as an extra
// (optional) parameter to the "RTSPServer::createNew()" call above.
if (rtspServer == NULL) {
*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
exit();
}
ServerMediaSession* sms
= ServerMediaSession::createNew(*env, "testStream", "My Video Out",
"Session streamed by \"this program\"",
isSSM);
sms->addSubsession(PassiveServerMediaSubsession::createNew(*mjpegSink, videoRTCP));
rtspServer->addServerMediaSession(sms);
url_rtsp = rtspServer->rtspURL(sms);
*env << "Play this stream using the URL \"" << url_rtsp << "\"\n";
#endif
// Finally, start the streaming:
*env << "Beginning streaming...\n";
play();
env->taskScheduler().doEventLoop(); // does not return
}
void afterPlaying(void* clientData) {
// One of the sinks has ended playing.
// Check whether any of the sources have a pending read. If so,
// wait until its sink ends playing also:
if(videoRPVRSource->isCurrentlyAwaitingData())
return;
// Now that the sink has ended, close input source,
// and start playing again:
*env << "...done reading from live input\n";
mjpegSink->stopPlaying();
// ensures that is shut down
Medium::close(videoRPVRSource);
// Start playing once again:
play();
}
void play() {
videoRPVRSource=RPVRFramedSource::createNew(*env);
// Finally, start playing the sink.
*env << "Beginning to read ..\n";
mjpegSink->startPlaying(*videoRPVRSource, afterPlaying, mjpegSink);
}
---------------------------------------------------------
¿Te gustan las apuestas? ¡Pues ahora juega también online! Y buena suerte... http://sorteos.ya.com
Ya.com ADSL Router Wi-Fi: Sólo 29,90 /mes + IVA*. Router + Antivirus y firewall ¡Gratis! http://acceso.ya.com/adsl/256router
More information about the live-devel
mailing list