catalinii / minisatip

minisatip is an SATIP server for linux using local DVB-S2, DVB-C, DVB-T or ATSC cards
https://minisatip.org
327 stars 82 forks source link

Buffers length #195

Closed lars18th closed 8 years ago

lars18th commented 8 years ago

Hi @catalinii ,

I like to understand the influence of the buffers in the minisatip. Please can you explain the use of: "-b --buffers X:Y". I like to improve the robustness in a slow system using more memory for buffers, but I don't show any difference changing these values. Also I like to know if it's possible to change the buffer for HTTP client connections.

Thank you for your impressive effort!

catalinii commented 8 years ago

Hi Lars,

generally those parameters sets how big is the kernel buffer and the application DVR buffer. The data is read by the kernel from the dvb card and stored in it's own buffer (second parameter -DVR_BUFFER), then it is read by the application and stored in the ADAPTER_BUFFER.

If you increase those values, minisatip will basically store more data in the buffer before sending it to the streams (over tcp).

If the tcp is sending slower than the data that is received from the DVB card (because of packet loss for example), the buffers will eventually get full and start dropping packets (E_OVERFLOW error), just that if they are bigger it will happen later than if they are smaller.

In this case there is not much we can do as minisatip does not buffer the data before being sent... it just tries to send it in a blocking write.

When I use minisatip over large distances I always go with udp as it's better to loose a small part of the image than for tcp to start retrying lost packets, dropping the window increasing it again and so on... TCP is unusable over links with high RTT.

lars18th commented 8 years ago

Hi @catalinii ,

Thank you very much for your interesting response! I feel you have good experience with video streaming...

However, my concern is related to the use of vtuner-satip-driver. Remember that at time I'm using this option as input for minisatip from a hardware SAT>IP server (in a local LAN). This driver reads (async) from the remote hardware SAT>IP server, and stores data in the kernel driver. Then, my question is: the kernel buffer size is the size of the "output" buffer in the driver? Then, what is the DVR buffer? Also, another question is when using Oscam. In this case, with a slow server, I can increase the buffer in the minisatip for storing more data "pending" to the decryt keys? My problem, at time are intermitent freezes when playing high bitrate encrypted channels. However, the CPU tools don't show that any of the process are consuming a lot of power, then I suspect the problem is a synch problem between buffers and blocking read/writes.

Please, can you explain more about the buffers you use? Thank you!

catalinii commented 8 years ago

the parameter is -b ADAPTER_BUFFER_SIZE:DVR_BUFFER_SIZE

DVR_BUFFER_SIZE is on the kernel side (where the driver stores the data in the kernel before getting to the application), ADAPTER_BUFFER is on minisatip side.

Basically minisatip reads from the dvr until adapter buffer is full, when it start processing it.

About the load, on my mips system at 450Mhz a 2MB/s stream takes around 10-20% of load (without dvbcsa).

Generally to test I would remove tcp out of the way unless you are 100% your network is in a very good shape (meaning just wires, no wireless, no packet loss).

Then you can see basically if the system is handling the load or no, top should show clearly that more specifically on the user %cpu load.

About dvbcsa, if a low bit rate stream is ok and a high bitstream rate is not OK, maybe your problem is the hardware....

what cpu are you using ?

lars18th commented 8 years ago

Hi @catalinii ,

I'm using a low power Atom CPU with regular x86_64 Debian 7. So the problem isn't the cpu load.

Basically minisatip reads from the dvr until adapter buffer is full, when it start processing it.

This is the point that I don't understand. You read from the drv buffer in chunks until empty it or only some packets each time?

Please, help me also to understand this:

I'm only trying to understand how to tweak these values without doing stupid changes (for example, a very huge dvr buffer that only consume resources and increase the latency).

Thank you very much for clarifications!

lars18th commented 8 years ago

Hi @catalinii ,

More comments (I hope you don't trouble for my several requests):

Using a slow remote Oscam server, I see some freezes in the image time to time. In the logs I see this:

[17/11 06:48:33.685751 AD1]: Unable to decrypt blen = 0, parity = 1, key_ok 1 for key 0

The freeze is minial (less than a second), and I feel the problem is that the new key arrives quite later. I think if it's possible to fix this behaviour increasing the buffer. I explain my idea with an algorithm:

1) read one TS packet from buffer. 2) if it's a CA packet then send it to the dvbcsa 3) push all new packets in a second buffer 4) when the second buffer is full, pop messages from it for decrypt.

The idea is use a second buffer for decrypting while waiting for "delayed" keys. What you think? The adapter buffer value has some influence on this?

catalinii commented 8 years ago

1) Minisatip IP reads always the number of bytes left unused in the adapter buffer.

So if they are both equal, and adapter buffer is empty and dvr buffer is full, one read will fill the adapter buffer and empty the dvr buffer. But yeah, if minisatip is not reading fast enough, the dvb part of the kernel will start overwriting old packets and you will see continuity errors.

2) Your cpu is fast enough to handle reading from one dvr to adapter buffer, the problem is that the tcp call might block for few seconds but I will look into the logs and let you know what's there.... You should see messages like:

WARNING: read on socket id ....

For the second comment, an increase in the adapter buffer should help in such cases as the ecm's/pat/pmt are processed from the entire stream before libdvbcsa is decrypting the stream.

lars18th commented 8 years ago

Thank you for the explanation! :)

As I understand:

I'll discuss my results after some testing. ;-)

lars18th commented 8 years ago

Hi @catalinii ,

Related to the buffer, I explain the results of my testing:

1) The size of DVR_BUFFER can't be changed by command line. If you start with "-b XXX:YYY" the result is ALWAYS:

[19/11 09:53:38.004 main]: Done setting DVR buffer to 5775360 bytes

don't care the value of YYY. Please, review the code!

2) The log line related to decoding errors is anoying:

[19/11 10:49:07.657429 AD1]: get_active_key: returning key 0 for pid 86, d/c errs 1286/2, adapter pid errs 269407

The "adapter pid errs" is the TOTAL value, then it not resets from one message to the next. Please, print the value from last message (or partial/total). Also I don't understand the pair "d/c errs". Can you, please, explain it?

3) Increasing to insanely values of ADAPTER_BUFFER (5000*default value), the problem with decoding with slow Oscam server continues. Please, can you explain why you set this default value smaller than the DVR buffer?

4) After more testing with high buffer sizes and HTTP client, I see sometimes this debug message when the image frezees:

[19/11 10:46:07.477678 AD1]: writev returned -1 handle 12, iiov 7 errno 11 error Resource temporarily unavailable Message repeated 1 times

You know why?

I continue testing for isolate why the image freezes very often.

lars18th commented 8 years ago

Hi,

This is a recomendation to any one that uses the vtuner-satip driver with minisatip: Set NICE value of the satip process (vtuner) to "-20" (use renice after starting the process). I found that if the minisatip process has higher priority than the satip (vtuner driver) then some packets are lost.

From this info I suggest that in the multi-threaded version of the minisatip the thread used for read will have more priority than the rest.

I'll continue testing the side effects of the buffer size.

catalinii commented 8 years ago

Hi Lars,

just the error message was using reporting the size wrong but the ioctl uses the right value. It will be fixed in the next commit.

2) d/c errors means decrypt/counter errors ... basically 2 values, first is decrypt error (how many packets are not successfully decrypted due to missing key) second is counter error.

As I said, adapter pid errors happens when using satip so this is normal. By default, when a TS packet is dropped the pid is changed to 8191 and is also market as adapter error.

The point is that I am trying to identify how many packets have been lost before getting to minisatip (if minisatip is used on the other end as well). Again those are just debugging messages that can help identifying issues.

3) The only reason I set it so high is to be able to store the data in case minisatip is in some call that blocks, to avoid losing packets. In general, the dvr buffer should not get filled.

4) that error message geenrally means that the tcp buffer is full....

lars18th commented 8 years ago

Hi @catalinii ,

Thank you for good explanation! I like to increase the reboustness of the minisatip and for this reason I like to explore the influence of the buffers.

Related to your answers:

2) If the pair "d/c" is "decrypt errors/counter errors" then a serious bug exsits in my environment: always the value=d is >0 and the value=c is low but sometimes c!=0. Why this?

2B) Yes, lost packets in SAT>IP client mode is an issue to be fixed. I'll continue doing some more testing for identifiying the issues.

3) Yes, I agree that the problem can be a blocking call. I suggest to isolate all TCP connections outside the main thread. Many (but not all) errors occurs with HTTP clients, so I recomend to improve this part of the code if you can.

3B) I totally agree that the dvr should not get filled, but if the reads from buffer are slow then the buffer really gets full! In my previous post I comment about changing the priority of the vtuner-satip driver. I found that if the "receive" priority of packets gets under "send" priority in this case the stream will have errors. Please, try to reassign different priorities to the working threads inside the minisatip.

4) And it's possible to overcome this? Where is the size of the TCP buffer in the code? I like to test about increasing this value.

Thank you very much! This piece of software is evolving to be the best SAT>IP server in the world!

catalinii commented 8 years ago

2) if the C!=0 then generally some packets are missing... if the number is small <5 it should be OK. About the D, it should be always >0 but generally it should stay the same while watching an encrypted stream. If that one increases it means that the key could get later than expected so it is normal to see artefacts.

You could play with output_buffer and add the following line to stream.c:258

set_socket_send_buffer(sid->rsock, opts.output_buffer);

See if it makes a difference.

BTW, did you tried the whole setup on a difference PC connected wired to the network ?

lars18th commented 8 years ago

Hi @catalinii ,

set_socket_send_buffer(sid->rsock, opts.output_buffer);

This seems to improve a bit, but some other side problems countinue.

See this log after inserting the new code:

[09/12 03:28:22.56095 AD2]: writev returned -1 handle 13, iiov 7 errno 11 error Resource temporarily unavailable
Message repeated 2 times
[09/12 03:28:28.62095 AD2]: writev returned -1 handle 13, iiov 7 errno 11 error Resource temporarily unavailable
Message repeated 2 times
[09/12 03:28:32.66510 AD2]: writev returned -1 handle 13, iiov 7 errno 104 error Connection reset by peer
[09/12 03:28:32.66510 AD2]: Connection REFUSED on stream 0, closing the stream, remote 192.168.1.28:49204
[09/12 03:28:32.66510 AD2]: writev returned -1 handle 13, iiov 7 errno 32 error Broken pipe
[09/12 03:28:32.66525 main]: select_and_execute[8]: Close on socket 13 (sid:0) from 192.168.1.28:49204 - type http errno 0
[09/12 03:28:32.66525 main]: sockets_del: 8 -> handle 13, sid 0
[09/12 03:28:32.66525 main]: Requested stream close 0 timeout 1 type 1
[09/12 03:28:32.66525 main]: closing stream 0
[09/12 03:28:32.66525 main]: sockets_del: 9 -> handle -2, sid 0
[09/12 03:28:32.66525 main]: sockets_del: 9 Last open socket is at index 7 current_handle -2
[09/12 03:28:32.66525 main]: closed adapter 2 for stream 0 m:-1 s:0
[09/12 03:28:32.66525 main]: deleting pids on adapter 2, sid 0, pids=NULL
[09/12 03:28:32.66525 main]: Dumping pids table for adapter 2, pid errors 0

In this log I see that after the change the HTTP client "refuses" the connection... but that doesn't makes sense! The client never closes the connection (or this is my assumption) and only if minisatip closes the socket and try to write on it then this message can appear.

A different story is a reconnection. In this case the client closes, then it reconnects. If minisatip continues with the adapter open, writing to the buffer (overwriting non readed data), then the client can start to read from the same buffer after reconnection. You implement in this way?

lars18th commented 8 years ago

Hi,

Buffers size seems to be correlated with sat>ip client troubles. See issue #109 at http://github.com/catalinii/minisatip/issues/109#issuecomment-169308484

I hope soon to fix this problem. :)

lars18th commented 8 years ago

With last versions, the use of large buffers are innecesary. So I close this issue!