alfianrahmn / xuggle

Automatically exported from code.google.com/p/xuggle
0 stars 0 forks source link

Performance concerns in xuggler-red5 adapter #189

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Hello, 

I have successfully set up the VideoTranscoderDemoAdapter on my Red5 server
and it runs correctly.  However, I noticed there were quite a few frames
dropped in the resulting output, so I decided to investigate this further.
 I created a separate app that mimics the input-reading code from the
Transcoder and inserted non-intrusive timing checks (source code is
attached to this post).  Here are my findings:

There is a ~100ms delay between each call to the IStreamListener instance's
packetReceived callback method.
Each call to the input IContainer's readPacket() method takes ~200ms to
execute.

I need to make an application that reads a Red5 input stream, does some
things to it, and then output it back, like the Transcoder.  However, a
~200ms delay just for reading the input packet means I can only output at
most 5 frames per second, which is insufficient.  Would a faster server
machine help alleviate the problem, or is there a software-based solution?

Thanks in advance, 

 - Philippe Milot

Original issue reported on code.google.com by PhilMi...@gmail.com on 29 Jul 2009 at 8:59

Attachments:

GoogleCodeExporter commented 8 years ago
Did you set the buffer time in your flash client to zero?  That's the #1 cause 
of
"performance problems" in the red5 adapter -- i.e. your client is buffering and 
we
can't start work until we get data.  readPacket(...) will block while waiting 
for
data from a client machine.

If your client is not buffering, then the next thing to do is to reduce the
packet-size of audio that the client is sending.  There are some options in 
Flash
that allow you to control this, especially with Speex audio.

Lastly, check out what happens once Red5 actually receives and parses a packet 
-- in
our testing we add about 2-10ms of latency (assuming just transcoding) once 
Red5 has
the packet.  But we can't start work until the entire packet has arrived at the
server, and for example if you're sending MP3 audio, that means you need to 
wait for
at least 572 samples to be collected by a client, then encoded on the client, 
sent
via a network to the Red5 server, and then parsed by Red5 and sent to us.  In 
our
experience with Nellymoser audio on Flash, that round-trip adds about 50-80 ms, 
which
there's nothing we (or anyone) can do about.

If you've confirmed that none of those issues are impacting you, then let me 
know
what you found and I'll reopen.

Hope that helps, 

- Art

Original comment by art.cla...@gmail.com on 29 Jul 2009 at 9:22

GoogleCodeExporter commented 8 years ago
Hello again, 

I have tried setting the bufferTime on the client's NetStream object to zero, 
but it
had no effects on the benchmark results.  Here is a snippet of the client code:

var onConnect:Function = function(evt:NetStatusEvent) : void {
  switch(evt.info.code) {
    case "NetConnection.Connect.Success" :

      ns = new NetStream(nc);
      ns.bufferTime = 0;
      video = new Video(640, 480);
      addChild(video);

      camera = Camera.getCamera();
      camera.setQuality(0, 75);
      camera.setMode(640, 480, 30);

      video.attachCamera(camera);
      ns.attachCamera(camera);
      ns.receiveAudio(false);

      ns.publish(feedName);
    break;
    default: break;
  }
}
nc = new NetConnection();
nc.objectEncoding = ObjectEncoding.AMF0;
nc.addEventListener(NetStatusEvent.NET_STATUS, onConnect, false, 0, true);
nc.connect("rtmp://10.0.0.25/myXugglerRed5App");

As you can see, I am not even sending any audio, just video.  So far the only 
thing I
have found that helps improve the performance slightly is to reduce the 
resolution of
the video, or to prioritize bandwidth over quality (which gives me a crappy 
image). 
I have also profiled my server machine while the benchmark was running and Red5 
and
the machine is barely taxed by this (2% CPU resources, very little RAM used).  
So
upgrading my hardware probably won't solve anything... help!

Original comment by PhilMi...@gmail.com on 30 Jul 2009 at 2:57

GoogleCodeExporter commented 8 years ago
Forgot to mention: we have also profiled the transmission time between the 
client
machine and the server machine; the bottleneck definitely isn't there, we are 
getting
over a meg/s.

Original comment by PhilMi...@gmail.com on 30 Jul 2009 at 3:02

GoogleCodeExporter commented 8 years ago
Hi Phillip,

The timing of packets arriving in your packetReceived callback is determined by 
Red5,
not by Xuggler.  So the fact that it takes 100ms between packetReceived calls 
is in
Red5 or your network settings.  Bear in mind if your video is being sent at 10 
FPS,
then you should only expect packets every 100ms (I know you're asking for 30fps 
from
your client).

As for the additional 100ms (you say readNextPacket takes 200ms to return for 
each
packet), that surprises me.  I've generally seen very low latencies once the 
Red5
packet is put on the Xuggler queue.  

Here's something to try: Run the videotranscoder demo we ship with the adapter, 
and
watch the console.  We spit out timing information every 5 seconds.  Look for 
the
"readNextPacket" datapoint's timing (it'll be in milliseconds).  That's our 
profiling
code showing the timing.  It should be slightly longer than the packetReceived 
delay
from your benchmark (i.e. it should be around 100ms).  If it's much more than 
100ms
(e.g. 200 ms as you see in your benchmark), then there's something weird going 
on
with your setup on your machine and I'll look further.

If Transcoder.java is much closer to your packetReceived latency, then there is 
a bug
somewhere in your benchmarking code.  Compare it to Transcoder.java and make 
sure
you're setting all the same parameters (I did a quick review of your code but 
saw
nothing obvious).

If that all fails, do me a favor -- Create a full fledged Red5 app (complete 
with all
the xml settings) with an ant build file so I can compile it and install it on 
my
server.  Unfortunately I don't have time right now to dive deep into your 
issue, but
it's easier for me to test if you give me a fully formed application I can just
deploy on my server.  I don't need a flash-client (I can use the Red5 publisher
application for that).

Original comment by art.cla...@gmail.com on 30 Jul 2009 at 3:15

GoogleCodeExporter commented 8 years ago
Hi Art, 

I have run the videotranscoder demo and looked at the profiler output; the
readNextPacket profile point gives an (alarming?) ~200ms average.  It seems like
there is a lot of cache miss (I don't know when this is triggered).  I have 
attached
the full output to this post.  I have also attached the requested standalone 
Red5 app
of my Benchmarker for you to try out.  You might have to edit the build.xml to
correctly set the path to the xuggler and red5 dependency jars (I'm kind of a 
newbie
with ant).

Thanks a lot, 

Phil

Original comment by PhilMi...@gmail.com on 30 Jul 2009 at 6:07

Attachments:

GoogleCodeExporter commented 8 years ago
Hi Phil,

Sounds (from the Red5 list) that you confirmed this was an issue either in Red5 
or on
the client.  I'm closing this out as a result.

http://osflash.org/pipermail/red5_osflash.org/2009-August/035328.html

Original comment by art.cla...@gmail.com on 4 Aug 2009 at 10:13

GoogleCodeExporter commented 8 years ago
Hi Phil, 

I think your issue might be similar to mine where I only get halve of the fps 
from 
input. 

For my case, It is because of this code in the StreamListener:
if (type != Red5Message.Type.DISPOSABLE_INTERFRAME) // The FFMPEG FLV decoder 
doesn't handle disposable frames
{
    inputQueue.put(new Red5Message(type, dataPacket));
}

The code above discard the DISPOSABLE_INTERFRAME type which lead to halve of 
the 
frames are dropped. I put the DISPOSABLE_INTERFRAME into the inputQueue as well 
and 
I can get the correct framerate. So far I don't see any issue with ffmpeg FLV 
decoder.

Hope this helps.

Original comment by choonyo...@gmail.com on 21 Aug 2009 at 8:17