udp: Add option overrun_nonfatal
Optionize fail/survive on circular buffer overrun Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
a2eecc110b
commit
3069e70f62
@ -59,6 +59,7 @@ typedef struct {
|
|||||||
int is_multicast;
|
int is_multicast;
|
||||||
int local_port;
|
int local_port;
|
||||||
int reuse_socket;
|
int reuse_socket;
|
||||||
|
int overrun_nonfatal;
|
||||||
struct sockaddr_storage dest_addr;
|
struct sockaddr_storage dest_addr;
|
||||||
int dest_addr_len;
|
int dest_addr_len;
|
||||||
int is_connected;
|
int is_connected;
|
||||||
@ -260,6 +261,7 @@ static int udp_port(struct sockaddr_storage *addr, int addr_len)
|
|||||||
* 'localport=n' : set the local port
|
* 'localport=n' : set the local port
|
||||||
* 'pkt_size=n' : set max packet size
|
* 'pkt_size=n' : set max packet size
|
||||||
* 'reuse=1' : enable reusing the socket
|
* 'reuse=1' : enable reusing the socket
|
||||||
|
* 'overrun_nonfatal=1': survive in case of circular buffer overrun
|
||||||
*
|
*
|
||||||
* @param h media file context
|
* @param h media file context
|
||||||
* @param uri of the remote server
|
* @param uri of the remote server
|
||||||
@ -358,12 +360,6 @@ static void *circular_buffer_task( void *_URLContext)
|
|||||||
/* Whats the minimum we can read so that we dont comletely fill the buffer */
|
/* Whats the minimum we can read so that we dont comletely fill the buffer */
|
||||||
left = av_fifo_space(s->fifo);
|
left = av_fifo_space(s->fifo);
|
||||||
|
|
||||||
/* No Space left, error, what do we do now */
|
|
||||||
if(left < UDP_MAX_PKT_SIZE + 4) {
|
|
||||||
av_log(h, AV_LOG_ERROR, "circular_buffer: OVERRUN\n");
|
|
||||||
s->circular_buffer_error = AVERROR(EIO);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
len = recv(s->udp_fd, s->tmp+4, sizeof(s->tmp)-4, 0);
|
len = recv(s->udp_fd, s->tmp+4, sizeof(s->tmp)-4, 0);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) {
|
if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) {
|
||||||
@ -373,6 +369,20 @@ static void *circular_buffer_task( void *_URLContext)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
AV_WL32(s->tmp, len);
|
AV_WL32(s->tmp, len);
|
||||||
|
if(left < len + 4) {
|
||||||
|
/* No Space left */
|
||||||
|
if (s->overrun_nonfatal) {
|
||||||
|
av_log(h, AV_LOG_WARNING, "Circular buffer overrun. "
|
||||||
|
"Surviving due to overrun_nonfatal option\n");
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
av_log(h, AV_LOG_ERROR, "Circular buffer overrun. "
|
||||||
|
"To avoid, increase fifo_size URL option. "
|
||||||
|
"To survive in such case, use overrun_nonfatal option\n");
|
||||||
|
s->circular_buffer_error = AVERROR(EIO);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
pthread_mutex_lock(&s->mutex);
|
pthread_mutex_lock(&s->mutex);
|
||||||
av_fifo_generic_write(s->fifo, s->tmp, len+4, NULL);
|
av_fifo_generic_write(s->fifo, s->tmp, len+4, NULL);
|
||||||
pthread_cond_signal(&s->cond);
|
pthread_cond_signal(&s->cond);
|
||||||
@ -421,6 +431,13 @@ static int udp_open(URLContext *h, const char *uri, int flags)
|
|||||||
s->reuse_socket = 1;
|
s->reuse_socket = 1;
|
||||||
reuse_specified = 1;
|
reuse_specified = 1;
|
||||||
}
|
}
|
||||||
|
if (av_find_info_tag(buf, sizeof(buf), "overrun_nonfatal", p)) {
|
||||||
|
char *endptr = NULL;
|
||||||
|
s->overrun_nonfatal = strtol(buf, &endptr, 10);
|
||||||
|
/* assume if no digits were found it is a request to enable it */
|
||||||
|
if (buf == endptr)
|
||||||
|
s->overrun_nonfatal = 1;
|
||||||
|
}
|
||||||
if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
|
if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
|
||||||
s->ttl = strtol(buf, NULL, 10);
|
s->ttl = strtol(buf, NULL, 10);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user