Commit 87df986d authored by Michael Niedermayer's avatar Michael Niedermayer

Merge remote-tracking branch 'qatar/master'

* qatar/master:
  mss1: validate number of changeable palette entries
  mss1: report palette changed when some additional colours were decoded
  x86: fft: replace call to memcpy by a loop
  udp: Support IGMPv3 source specific multicast and source blocking
  dxva2: include dxva.h if found
  libm: Provide fallback definitions for isnan() and isinf()
  tcp: Pass NULL as hostname to getaddrinfo if the string is empty
  tcp: Set AI_PASSIVE when the socket will be used for listening

Conflicts:
	configure
	libavcodec/mss1.c
	libavformat/udp.c
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents ee7214c5 15358ade
...@@ -1192,6 +1192,7 @@ HAVE_LIST=" ...@@ -1192,6 +1192,7 @@ HAVE_LIST="
dlfcn_h dlfcn_h
dlopen dlopen
dos_paths dos_paths
dxva_h
ebp_available ebp_available
ebx_available ebx_available
exp2 exp2
...@@ -1215,6 +1216,8 @@ HAVE_LIST=" ...@@ -1215,6 +1216,8 @@ HAVE_LIST="
inet_aton inet_aton
inline_asm inline_asm
isatty isatty
isinf
isnan
jack_port_get_latency_range jack_port_get_latency_range
kbhit kbhit
ldbrx ldbrx
...@@ -1259,6 +1262,8 @@ HAVE_LIST=" ...@@ -1259,6 +1262,8 @@ HAVE_LIST="
strerror_r strerror_r
strptime strptime
struct_addrinfo struct_addrinfo
struct_group_source_req
struct_ip_mreq_source
struct_ipv6_mreq struct_ipv6_mreq
struct_rusage_ru_maxrss struct_rusage_ru_maxrss
struct_sockaddr_in6 struct_sockaddr_in6
...@@ -3116,6 +3121,8 @@ fi ...@@ -3116,6 +3121,8 @@ fi
if enabled network; then if enabled network; then
check_type "sys/types.h sys/socket.h" socklen_t check_type "sys/types.h sys/socket.h" socklen_t
check_type netdb.h "struct addrinfo" check_type netdb.h "struct addrinfo"
check_type netinet/in.h "struct group_source_req" -D_BSD_SOURCE
check_type netinet/in.h "struct ip_mreq_source" -D_BSD_SOURCE
check_type netinet/in.h "struct ipv6_mreq" -D_DARWIN_C_SOURCE check_type netinet/in.h "struct ipv6_mreq" -D_DARWIN_C_SOURCE
check_type netinet/in.h "struct sockaddr_in6" check_type netinet/in.h "struct sockaddr_in6"
check_type "sys/types.h sys/socket.h" "struct sockaddr_storage" check_type "sys/types.h sys/socket.h" "struct sockaddr_storage"
...@@ -3131,6 +3138,8 @@ if enabled network; then ...@@ -3131,6 +3138,8 @@ if enabled network; then
network_extralibs="-lws2_32"; } network_extralibs="-lws2_32"; }
check_type ws2tcpip.h socklen_t check_type ws2tcpip.h socklen_t
check_type ws2tcpip.h "struct addrinfo" check_type ws2tcpip.h "struct addrinfo"
check_type ws2tcpip.h "struct group_source_req"
check_type ws2tcpip.h "struct ip_mreq_source"
check_type ws2tcpip.h "struct ipv6_mreq" check_type ws2tcpip.h "struct ipv6_mreq"
check_type ws2tcpip.h "struct sockaddr_in6" check_type ws2tcpip.h "struct sockaddr_in6"
check_type ws2tcpip.h "struct sockaddr_storage" check_type ws2tcpip.h "struct sockaddr_storage"
...@@ -3180,6 +3189,7 @@ check_func_headers windows.h VirtualAlloc ...@@ -3180,6 +3189,7 @@ check_func_headers windows.h VirtualAlloc
check_func_headers glob.h glob check_func_headers glob.h glob
check_header dlfcn.h check_header dlfcn.h
check_header dxva.h
check_header dxva2api.h -D_WIN32_WINNT=0x0600 check_header dxva2api.h -D_WIN32_WINNT=0x0600
check_header libcrystalhd/libcrystalhd_if.h check_header libcrystalhd/libcrystalhd_if.h
check_header malloc.h check_header malloc.h
...@@ -3250,6 +3260,8 @@ enabled vaapi && require vaapi va/va.h vaInitialize -lva ...@@ -3250,6 +3260,8 @@ enabled vaapi && require vaapi va/va.h vaInitialize -lva
check_mathfunc cbrtf check_mathfunc cbrtf
check_mathfunc exp2 check_mathfunc exp2
check_mathfunc exp2f check_mathfunc exp2f
check_mathfunc isinf
check_mathfunc isnan
check_mathfunc llrint check_mathfunc llrint
check_mathfunc llrintf check_mathfunc llrintf
check_mathfunc log2 check_mathfunc log2
......
...@@ -566,6 +566,14 @@ and makes writes return with AVERROR(ECONNREFUSED) if "destination ...@@ -566,6 +566,14 @@ and makes writes return with AVERROR(ECONNREFUSED) if "destination
unreachable" is received. unreachable" is received.
For receiving, this gives the benefit of only receiving packets from For receiving, this gives the benefit of only receiving packets from
the specified peer address/port. the specified peer address/port.
@item sources=@var{address}[,@var{address}]
Only receive packets sent to the multicast group from one of the
specified sender IP addresses.
@item block=@var{address}[,@var{address}]
Ignore packets sent to the multicast group from the specified
sender IP addresses.
@end table @end table
Some usage examples of the udp protocol with @command{ffmpeg} follow. Some usage examples of the udp protocol with @command{ffmpeg} follow.
......
...@@ -25,7 +25,14 @@ ...@@ -25,7 +25,14 @@
#define _WIN32_WINNT 0x0600 #define _WIN32_WINNT 0x0600
#define COBJMACROS #define COBJMACROS
#include "config.h"
#include "dxva2.h" #include "dxva2.h"
#if HAVE_DXVA_H
#include <dxva.h>
#endif
#include "avcodec.h" #include "avcodec.h"
#include "mpegvideo.h" #include "mpegvideo.h"
......
...@@ -557,7 +557,7 @@ static int decode_pal(MSS1Context *ctx, ArithCoder *acoder) ...@@ -557,7 +557,7 @@ static int decode_pal(MSS1Context *ctx, ArithCoder *acoder)
*pal++ = (0xFF << 24) | (r << 16) | (g << 8) | b; *pal++ = (0xFF << 24) | (r << 16) | (g << 8) | b;
} }
return 1; return !!ncol;
} }
static int decode_pivot(MSS1Context *ctx, ArithCoder *acoder, int base) static int decode_pivot(MSS1Context *ctx, ArithCoder *acoder, int base)
...@@ -783,8 +783,10 @@ static av_cold int mss1_decode_init(AVCodecContext *avctx) ...@@ -783,8 +783,10 @@ static av_cold int mss1_decode_init(AVCodecContext *avctx)
av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d\n", av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d\n",
AV_RB32(avctx->extradata + 4), AV_RB32(avctx->extradata + 8)); AV_RB32(avctx->extradata + 4), AV_RB32(avctx->extradata + 8));
c->free_colours = AV_RB32(avctx->extradata + 48); c->free_colours = AV_RB32(avctx->extradata + 48);
if (c->free_colours < 0 || c->free_colours > 256) { if ((unsigned)c->free_colours > 256) {
av_log(avctx, AV_LOG_ERROR, "Invalid free colours %d\n", c->free_colours); av_log(avctx, AV_LOG_ERROR,
"Incorrect number of changeable palette entries: %d\n",
c->free_colours);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
av_log(avctx, AV_LOG_DEBUG, "%d free colour(s)\n", c->free_colours); av_log(avctx, AV_LOG_DEBUG, "%d free colour(s)\n", c->free_colours);
......
...@@ -616,8 +616,6 @@ cglobal fft_calc, 2,5,8 ...@@ -616,8 +616,6 @@ cglobal fft_calc, 2,5,8
.end: .end:
REP_RET REP_RET
cextern_naked memcpy
cglobal fft_permute, 2,7,1 cglobal fft_permute, 2,7,1
mov r4, [r0 + FFTContext.revtab] mov r4, [r0 + FFTContext.revtab]
mov r5, [r0 + FFTContext.tmpbuf] mov r5, [r0 + FFTContext.tmpbuf]
...@@ -638,29 +636,18 @@ cglobal fft_permute, 2,7,1 ...@@ -638,29 +636,18 @@ cglobal fft_permute, 2,7,1
cmp r0, r2 cmp r0, r2
jl .loop jl .loop
shl r2, 3 shl r2, 3
%if ARCH_X86_64 add r1, r2
mov r0, r1 add r5, r2
mov r1, r5 neg r2
%endif ; nbits >= 2 (FFT4) and sizeof(FFTComplex)=8 => at least 32B
%if WIN64 .loopcopy:
sub rsp, 8 movaps xmm0, [r5 + r2]
call memcpy movaps xmm1, [r5 + r2 + 16]
add rsp, 8 movaps [r1 + r2], xmm0
RET movaps [r1 + r2 + 16], xmm1
%elif ARCH_X86_64 add r2, 32
%ifdef PIC jl .loopcopy
jmp memcpy wrt ..plt REP_RET
%else
jmp memcpy
%endif
%else
push r2
push r5
push r1
call memcpy
add esp, 12
RET
%endif
cglobal imdct_calc, 3,5,3 cglobal imdct_calc, 3,5,3
mov r3d, [r0 + FFTContext.mdctsize] mov r3d, [r0 + FFTContext.mdctsize]
......
...@@ -63,7 +63,12 @@ static int tcp_open(URLContext *h, const char *uri, int flags) ...@@ -63,7 +63,12 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
snprintf(portstr, sizeof(portstr), "%d", port); snprintf(portstr, sizeof(portstr), "%d", port);
ret = getaddrinfo(hostname, portstr, &hints, &ai); if (listen_socket)
hints.ai_flags |= AI_PASSIVE;
if (!hostname[0])
ret = getaddrinfo(NULL, portstr, &hints, &ai);
else
ret = getaddrinfo(hostname, portstr, &hints, &ai);
if (ret) { if (ret) {
av_log(h, AV_LOG_ERROR, av_log(h, AV_LOG_ERROR,
"Failed to resolve hostname %s: %s\n", "Failed to resolve hostname %s: %s\n",
......
...@@ -188,6 +188,79 @@ static struct addrinfo* udp_resolve_host(const char *hostname, int port, ...@@ -188,6 +188,79 @@ static struct addrinfo* udp_resolve_host(const char *hostname, int port,
return res; return res;
} }
static int udp_set_multicast_sources(int sockfd, struct sockaddr *addr,
int addr_len, char **sources,
int nb_sources, int include)
{
#if HAVE_STRUCT_GROUP_SOURCE_REQ && defined(MCAST_BLOCK_SOURCE) && !defined(_WIN32)
/* These ones are available in the microsoft SDK, but don't seem to work
* as on linux, so just prefer the v4-only approach there for now. */
int i;
for (i = 0; i < nb_sources; i++) {
struct group_source_req mreqs;
int level = addr->sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0,
SOCK_DGRAM, AF_UNSPEC,
AI_NUMERICHOST);
if (!sourceaddr)
return AVERROR(ENOENT);
mreqs.gsr_interface = 0;
memcpy(&mreqs.gsr_group, addr, addr_len);
memcpy(&mreqs.gsr_source, sourceaddr->ai_addr, sourceaddr->ai_addrlen);
freeaddrinfo(sourceaddr);
if (setsockopt(sockfd, level,
include ? MCAST_JOIN_SOURCE_GROUP : MCAST_BLOCK_SOURCE,
(const void *)&mreqs, sizeof(mreqs)) < 0) {
if (include)
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_JOIN_SOURCE_GROUP)");
else
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_BLOCK_SOURCE)");
return ff_neterrno();
}
}
#elif HAVE_STRUCT_IP_MREQ_SOURCE && defined(IP_BLOCK_SOURCE)
int i;
if (addr->sa_family != AF_INET) {
av_log(NULL, AV_LOG_ERROR,
"Setting multicast sources only supported for IPv4\n");
return AVERROR(EINVAL);
}
for (i = 0; i < nb_sources; i++) {
struct ip_mreq_source mreqs;
struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0,
SOCK_DGRAM, AF_UNSPEC,
AI_NUMERICHOST);
if (!sourceaddr)
return AVERROR(ENOENT);
if (sourceaddr->ai_addr->sa_family != AF_INET) {
freeaddrinfo(sourceaddr);
av_log(NULL, AV_LOG_ERROR, "%s is of incorrect protocol family\n",
sources[i]);
return AVERROR(EINVAL);
}
mreqs.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
mreqs.imr_interface.s_addr = INADDR_ANY;
mreqs.imr_sourceaddr.s_addr = ((struct sockaddr_in *)sourceaddr->ai_addr)->sin_addr.s_addr;
freeaddrinfo(sourceaddr);
if (setsockopt(sockfd, IPPROTO_IP,
include ? IP_ADD_SOURCE_MEMBERSHIP : IP_BLOCK_SOURCE,
(const void *)&mreqs, sizeof(mreqs)) < 0) {
if (include)
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP)");
else
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_BLOCK_SOURCE)");
return ff_neterrno();
}
}
#else
return AVERROR(ENOSYS);
#endif
return 0;
}
static int udp_set_url(struct sockaddr_storage *addr, static int udp_set_url(struct sockaddr_storage *addr,
const char *hostname, int port) const char *hostname, int port)
{ {
...@@ -394,6 +467,8 @@ static int udp_open(URLContext *h, const char *uri, int flags) ...@@ -394,6 +467,8 @@ static int udp_open(URLContext *h, const char *uri, int flags)
struct sockaddr_storage my_addr; struct sockaddr_storage my_addr;
int len; int len;
int reuse_specified = 0; int reuse_specified = 0;
int i, include = 0, num_sources = 0;
char *sources[32];
h->is_streamed = 1; h->is_streamed = 1;
h->max_packet_size = 1472; h->max_packet_size = 1472;
...@@ -443,6 +518,25 @@ static int udp_open(URLContext *h, const char *uri, int flags) ...@@ -443,6 +518,25 @@ static int udp_open(URLContext *h, const char *uri, int flags)
if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) { if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
av_strlcpy(localaddr, buf, sizeof(localaddr)); av_strlcpy(localaddr, buf, sizeof(localaddr));
} }
if (av_find_info_tag(buf, sizeof(buf), "sources", p))
include = 1;
if (include || av_find_info_tag(buf, sizeof(buf), "block", p)) {
char *source_start;
source_start = buf;
while (1) {
char *next = strchr(source_start, ',');
if (next)
*next = '\0';
sources[num_sources] = av_strdup(source_start);
if (!sources[num_sources])
goto fail;
source_start = next + 1;
num_sources++;
if (num_sources >= FF_ARRAY_ELEMS(sources) || !next)
break;
}
}
} }
/* fill the dest addr */ /* fill the dest addr */
...@@ -500,8 +594,21 @@ static int udp_open(URLContext *h, const char *uri, int flags) ...@@ -500,8 +594,21 @@ static int udp_open(URLContext *h, const char *uri, int flags)
} }
if (h->flags & AVIO_FLAG_READ) { if (h->flags & AVIO_FLAG_READ) {
/* input */ /* input */
if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0) if (num_sources == 0 || !include) {
if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
goto fail;
if (num_sources) {
if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 0) < 0)
goto fail;
}
} else if (include && num_sources) {
if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 1) < 0)
goto fail;
} else {
av_log(NULL, AV_LOG_ERROR, "invalid udp settings: inclusive multicast but no sources given\n");
goto fail; goto fail;
}
} }
} }
...@@ -529,6 +636,9 @@ static int udp_open(URLContext *h, const char *uri, int flags) ...@@ -529,6 +636,9 @@ static int udp_open(URLContext *h, const char *uri, int flags)
} }
} }
for (i = 0; i < num_sources; i++)
av_free(sources[i]);
s->udp_fd = udp_fd; s->udp_fd = udp_fd;
#if HAVE_PTHREAD_CANCEL #if HAVE_PTHREAD_CANCEL
...@@ -567,6 +677,8 @@ static int udp_open(URLContext *h, const char *uri, int flags) ...@@ -567,6 +677,8 @@ static int udp_open(URLContext *h, const char *uri, int flags)
if (udp_fd >= 0) if (udp_fd >= 0)
closesocket(udp_fd); closesocket(udp_fd);
av_fifo_free(s->fifo); av_fifo_free(s->fifo);
for (i = 0; i < num_sources; i++)
av_free(sources[i]);
return AVERROR(EIO); return AVERROR(EIO);
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <math.h> #include <math.h>
#include "config.h" #include "config.h"
#include "attributes.h" #include "attributes.h"
#include "intfloat.h"
#if HAVE_MIPSFPU && HAVE_INLINE_ASM #if HAVE_MIPSFPU && HAVE_INLINE_ASM
#include "libavutil/mips/libm_mips.h" #include "libavutil/mips/libm_mips.h"
...@@ -49,6 +50,26 @@ static av_always_inline float cbrtf(float x) ...@@ -49,6 +50,26 @@ static av_always_inline float cbrtf(float x)
#define exp2f(x) ((float)exp2(x)) #define exp2f(x) ((float)exp2(x))
#endif /* HAVE_EXP2F */ #endif /* HAVE_EXP2F */
#if !HAVE_ISINF
static av_always_inline av_const int isinf(float x)
{
uint32_t v = av_float2int(x);
if ((v & 0x7f800000) != 0x7f800000)
return 0;
return !(v & 0x007fffff);
}
#endif /* HAVE_ISINF */
#if !HAVE_ISNAN
static av_always_inline av_const int isnan(float x)
{
uint32_t v = av_float2int(x);
if ((v & 0x7f800000) != 0x7f800000)
return 0;
return v & 0x007fffff;
}
#endif /* HAVE_ISNAN */
#if !HAVE_LLRINT #if !HAVE_LLRINT
#undef llrint #undef llrint
#define llrint(x) ((long long)rint(x)) #define llrint(x) ((long long)rint(x))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment