Setting a timeout for av_read_frame - ffmpeg

I am new to FFMPEG and was trying to do HLS streaming using FFMPEG. When i tried using the function "av_read_frame" it returns a negative value whenever data is not available. Is there some method to make this function wait till some data is received or to make this function wait till a timeout is reached?

No, there really isn't. If you look at the simple player ffplay.c which comes with FFmpeg, the read_thread function basically loops on av_read_frame until it returns a non-negative return code. If it returns a negative value, it simply waits for 10ms and retries.

Related

Combining samples quickly in tone.js (or another framework)

I need to programatically combine a bunch of music tracks in a sequence, one after the other, with some overlap between them, based on some rules.
I was looking at tone.js today which is great, and I've just about managed to make work (with players feeding into a recorder), but I realised right at the end that you have to wait for the whole sequence to play out in real time before it can be saved.
I don't want to have to wait an hour to get the file, I need it within a minute maximum. Is this possible with tone.js and if not is there any other programmatic way to do this?
You should be able to use OfflineContext rendering for this. Basically what you have to do is calling Tone.Offline and then get the audioBuffer of the result and save it to a file. You don't need a Recorder node. So something like this:
const audioBufferNode = await Tone.Offline(({ transport }) => {
// Do all your player scheduling along the transport here.
transport.start(0.5); // Start the transport to trigger all scheduled players
}, 4 /* The length of the resulting file */);
To download the audio buffer as a file requires you to read the raw data and write it into a format you wish to download.
A audio buffer to wave writer can be found here:
https://www.russellgood.com/how-to-convert-audiobuffer-to-audio-file

sendto() dgrams do not block for ENOBUFS on OSX

This is more of a observation and also a suggestion for whats the best way to handle this scenario.
I have two threads one just pumps in data and another receives the data and does lot of work before sending it another socket. Both the threads are connected via a Domain socket. The protocol used here is UDP. I did not want to use TCP as it is stream based, which means if there is little space in the queue my data is split and sent. This is bad as Iam sending data that should not be split. Hence I used DGRAM. Interestingly when the send thread overwhelms the recv thread by pumping so much data, at some point the Domain socket buffer gets filled up and sendto() returns ENOBUFS. I was of the opinion that should this happen, sendto() would block until the buffer is available. This would be my desired behaviour. However this does not seem to be the case. I solve this problem in a rather weird way.
CPU Yield method
If I get ENOBUFS, I do a sched_yield(); as there is no pthread_yield() in OSX. After that I try to resend again. If that fails I keep doing the same until it is taken. This is bad as Iam wasting cpu cycles just doing something useless. I would love if sendto() blocked.
Sleep method
I tried to solve the same issue using sleep(1) instead of sched_yield() but this of no use as sleep() would put my process to sleep instead of just that send thread.
Both of them does not seem to work for me and Iam running out of options. Can someone suggest what is the best way to handle this issue? Is there some clever tricks Iam not aware of that can reduce unnecessary cpu cycles? btw, what the man page says about sentto() is wrong, based on this discussion http://lists.freebsd.org/pipermail/freebsd-hackers/2004-January/005385.html
The Upd code in kernel:
The udp_output function in /sys/netinet/udp_usrreq.c, seems clear:
/*
* Calculate data length and get a mbuf
* for UDP and IP headers.
*/
M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
if (m == 0) {
error = ENOBUFS;
if (addr)
splx(s);
goto release;
}
I'm not sure why sendto() isn't blocking for you... but you might try calling this function before you each call to sendto():
#include <stdio.h>
#include <sys/select.h>
// Won't return until there is space available on the socket for writing
void WaitUntilSocketIsReadyForWrite(int socketFD)
{
fd_set writeSet;
FD_ZERO(&writeSet);
FD_SET(socketFD, &writeSet);
if (select(socketFD+1, NULL, &writeSet, NULL, NULL) < 0) perror("select");
}
Btw how big are the packets that you are trying to send?
sendto() on OS X is really nonblocking (that is M_DONTWAIT flag for).
I suggest you to use stream based connection and just receive the whole data on the other side by using MSG_WAITALL flag of the recv function. If your data has strict structure than it would be simple, just pass the correct size to the recv. If not than just send some fixed-size control packet first with the size of the next chunk of data and then the data itself. On the receiver side you would be wait for control packet of fixed size and than the data of size from control packet.

The recommended way of reading data in a multi-channel application

What is the recommended way of using libssh2 to implement the “read data from whichever channel has it first” primitive?
E.g. I have a simple two-tab terminal program, where each tab corresponds to a LIBSSH2 channel. I want to wait until ANY of the 2 channels gets data and then print it.
The single-channel examples use libssh2_channel_read() in a non-blocking way like this:
while(not done) {
1. Try reading with libssh2_channel_read()
2. If returned LIBSSH2_ERROR_EAGAIN, wait with select()
}
The trivial way of extending this to two-channel case would be:
while(not done) {
1. Try reading channel 1
2. Try reading channel 2
3. If BOTH channels returned LIBSSH2_ERROR_EAGAIN, wait with select()
}
This leads to a rare bug when a packet with some data for channel 1 arrives just before reading channel 2. Then both calls return LIBSSH2_ERROR_EAGAIN, but as the attempt to read channel 2 actually recv()’d the data for channel 1, select() will now hang.
The workaround I am currently employing involves keeping raw data counters for the socket and using them to determine if any new data was consumed by libssh2, but I get the feeling of making a really complex workaround for a fairly simple problem. Am I missing something?
Is there some kind of libssh2_session_read_any_channel()?

Attaching a callback to the output element of the Remote IO

I want to capture audio from the microphone of an iOS device and write it to a .caf file.
I'm able to connect a Remote IO audio unit to a multichannel mixer unit (MCMU) and attach a callback to the input of the MCMU. Inside that callback I can successfully write the audio data from the mic to a file using ExtAudioFileAsyncWrite().
I want to simplify things and remove the MCMU from the picture. My thinking is I can simply attach a callback to the output bus of the Remote IO's input scope and inside that callback call ExtAudioFileAsyncWrite().
However when I try this ExtAudioFileAsyncWrite() returns a -50 (paramError).
Is it not possible to attach a callback to the output bus of the input element of the Remote IO?
It is possible. You'll want to use AudioUnitSetProperty to set the kAudioOutputUnitProperty_SetInputCallback property. This callback will function much like a render callback, but will be called whenever the RemoteIO / mic has some new data for you (instead of as a request for data from your program).
Example:
AURenderCallbackStruct callbackInfo = {YourInputCallback, NULL};
AudioUnitSetProperty(remoteIO,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
0,
&callbackInfo,
sizeof(callbackInfo));
This will make the RemoteIO / mic call YourInputCallback whenever it has a new batch of samples. You can use this callback to call ExtAudioFileWriteAsync as you did before. Note that you'll have to call AudioUnitRender on the RemoteIO as well, to get the new samples out of it.
Regarding the -50 error, that's not a very helpful error diagnostic. It basically just says "there was an error with one of your parameters". Most likely your ExtAudioFile was NULL or not set up properly (in which case, one of the ExtAudioFile* functions you used on it earlier would have returned a more helpful error code you can use to diagnose it).

Block TCP-send till ACK returned

I am programming a client application sending TCP/IP packets to a server. Because of timeout issues I want to start a timer as soon as the ACK-Package is returned (so there can be no timeout while the package has not reached the server). I want to use the winapi.
Setting the Socket to blocking mode doesn't help, because the send command returns as soon as the data is written into the buffer (if I am not mistaken). Is there a way to block send till the ACK was returned, or is there any other way to do this without writing my own TCP-implementation?
Regards
It sounds like you want to do the minimum implementation to achieve your goal. In this case you should set your socket to blocking, and following the send which blocks until all data is sent, you call recv which in turn will block until the ACK packet is received or the server end closes or aborts the connection.
If you wanted to go further with your implementation you'd have to structure your client application in such a way that supports asynchronous communication. There are a few techniques with varying degrees of complexity; polling using select() simple, event model using WSASelectEvent/WSAWaitForMultipleEvents challenging, and the IOCompletionPort model which is very complicated.
peudocode... Will wait until ack is recevied, after which time you can call whatever functionallity you want -i chose some made up function send_data.. which would then send information over the socket after receiving the ack.
data = ''
while True
readable, writable, errors = select([socket])
if socket in readble
data += recv(socket)
if is_ack(data)
timer.start() #not sure why you want this
break
send_data(socket)

Resources