From a93fb678011094f89a54c1e1d783d46f9591f8e3 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 9 Jul 2015 02:07:09 +0200 Subject: [PATCH 001/250] Android SDK missing ifaddrs support. --- Makefile.in | 1 + xbmc/network/linux/android-ifaddrs/Makefile | 6 + xbmc/network/linux/android-ifaddrs/README.md | 6 + xbmc/network/linux/android-ifaddrs/ifaddrs.c | 663 +++++++++++++++++++++++++++ xbmc/network/linux/android-ifaddrs/ifaddrs.h | 54 +++ 5 files changed, 730 insertions(+) create mode 100644 xbmc/network/linux/android-ifaddrs/Makefile create mode 100644 xbmc/network/linux/android-ifaddrs/README.md create mode 100644 xbmc/network/linux/android-ifaddrs/ifaddrs.c create mode 100644 xbmc/network/linux/android-ifaddrs/ifaddrs.h diff --git a/Makefile.in b/Makefile.in index c858252..09d5a79 100644 --- a/Makefile.in +++ b/Makefile.in @@ -155,6 +155,7 @@ DIRECTORY_ARCHIVES += xbmc/network/linux/network_linux.a DIRECTORY_ARCHIVES += xbmc/powermanagement/android/powermanagement_android.a DIRECTORY_ARCHIVES += xbmc/storage/android/storage_android.a DIRECTORY_ARCHIVES += xbmc/windowing/X11/windowing_X11.a +DIRECTORY_ARCHIVES += xbmc/network/linux/android-ifaddrs/android-ifaddrs.a else DIRECTORY_ARCHIVES += xbmc/input/linux/input_linux.a DIRECTORY_ARCHIVES += xbmc/input/touch/input_touch.a diff --git a/xbmc/network/linux/android-ifaddrs/Makefile b/xbmc/network/linux/android-ifaddrs/Makefile new file mode 100644 index 0000000..39e43ea --- /dev/null +++ b/xbmc/network/linux/android-ifaddrs/Makefile @@ -0,0 +1,6 @@ +SRCS=ifaddrs.c + +LIB=android-ifaddrs.a + +include ../../../../Makefile.include +-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) diff --git a/xbmc/network/linux/android-ifaddrs/README.md b/xbmc/network/linux/android-ifaddrs/README.md new file mode 100644 index 0000000..dc05bdf --- /dev/null +++ b/xbmc/network/linux/android-ifaddrs/README.md @@ -0,0 +1,6 @@ +android-ifaddrs +=============== + +An implementation of getifaddrs() for Android, since the NDK does not natively support it. + +Works just like you would expect on regular Linux. License information is present in each file (BSD license). diff --git a/xbmc/network/linux/android-ifaddrs/ifaddrs.c b/xbmc/network/linux/android-ifaddrs/ifaddrs.c new file mode 100644 index 0000000..c59d8bc --- /dev/null +++ b/xbmc/network/linux/android-ifaddrs/ifaddrs.c @@ -0,0 +1,663 @@ +/* +Copyright (c) 2013, Kenneth MacKay +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "ifaddrs.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct NetlinkList +{ + struct NetlinkList *m_next; + struct nlmsghdr *m_data; + unsigned int m_size; +} NetlinkList; + +static int netlink_socket(void) +{ + int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if(l_socket < 0) + { + return -1; + } + + struct sockaddr_nl l_addr; + memset(&l_addr, 0, sizeof(l_addr)); + l_addr.nl_family = AF_NETLINK; + if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0) + { + close(l_socket); + return -1; + } + + return l_socket; +} + +static int netlink_send(int p_socket, int p_request) +{ + struct + { + struct nlmsghdr m_hdr; + struct rtgenmsg m_msg; + } l_data; + + memset(&l_data, 0, sizeof(l_data)); + + l_data.m_hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)); + l_data.m_hdr.nlmsg_type = p_request; + l_data.m_hdr.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; + l_data.m_hdr.nlmsg_pid = 0; + l_data.m_hdr.nlmsg_seq = p_socket; + l_data.m_msg.rtgen_family = AF_UNSPEC; + + struct sockaddr_nl l_addr; + memset(&l_addr, 0, sizeof(l_addr)); + l_addr.nl_family = AF_NETLINK; + return (sendto(p_socket, &l_data.m_hdr, l_data.m_hdr.nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr))); +} + +static int netlink_recv(int p_socket, void *p_buffer, size_t p_len) +{ + struct msghdr l_msg; + struct iovec l_iov = { p_buffer, p_len }; + struct sockaddr_nl l_addr; + + for(;;) + { + l_msg.msg_name = (void *)&l_addr; + l_msg.msg_namelen = sizeof(l_addr); + l_msg.msg_iov = &l_iov; + l_msg.msg_iovlen = 1; + l_msg.msg_control = NULL; + l_msg.msg_controllen = 0; + l_msg.msg_flags = 0; + int l_result = recvmsg(p_socket, &l_msg, 0); + + if(l_result < 0) + { + if(errno == EINTR) + { + continue; + } + return -2; + } + + if(l_msg.msg_flags & MSG_TRUNC) + { // buffer was too small + return -1; + } + return l_result; + } +} + +static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done) +{ + size_t l_size = 4096; + void *l_buffer = NULL; + + for(;;) + { + free(l_buffer); + l_buffer = malloc(l_size); + if (l_buffer == NULL) + { + return NULL; + } + + int l_read = netlink_recv(p_socket, l_buffer, l_size); + *p_size = l_read; + if(l_read == -2) + { + free(l_buffer); + return NULL; + } + if(l_read >= 0) + { + pid_t l_pid = getpid(); + struct nlmsghdr *l_hdr; + for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read)) + { + if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) + { + continue; + } + + if(l_hdr->nlmsg_type == NLMSG_DONE) + { + *p_done = 1; + break; + } + + if(l_hdr->nlmsg_type == NLMSG_ERROR) + { + free(l_buffer); + return NULL; + } + } + return l_buffer; + } + + l_size *= 2; + } +} + +static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size) +{ + NetlinkList *l_item = malloc(sizeof(NetlinkList)); + if (l_item == NULL) + { + return NULL; + } + + l_item->m_next = NULL; + l_item->m_data = p_data; + l_item->m_size = p_size; + return l_item; +} + +static void freeResultList(NetlinkList *p_list) +{ + NetlinkList *l_cur; + while(p_list) + { + l_cur = p_list; + p_list = p_list->m_next; + free(l_cur->m_data); + free(l_cur); + } +} + +static NetlinkList *getResultList(int p_socket, int p_request) +{ + if(netlink_send(p_socket, p_request) < 0) + { + return NULL; + } + + NetlinkList *l_list = NULL; + NetlinkList *l_end = NULL; + int l_size; + int l_done = 0; + while(!l_done) + { + struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done); + if(!l_hdr) + { // error + freeResultList(l_list); + return NULL; + } + + NetlinkList *l_item = newListItem(l_hdr, l_size); + if (!l_item) + { + freeResultList(l_list); + return NULL; + } + if(!l_list) + { + l_list = l_item; + } + else + { + l_end->m_next = l_item; + } + l_end = l_item; + } + return l_list; +} + +static size_t maxSize(size_t a, size_t b) +{ + return (a > b ? a : b); +} + +static size_t calcAddrLen(sa_family_t p_family, int p_dataSize) +{ + switch(p_family) + { + case AF_INET: + return sizeof(struct sockaddr_in); + case AF_INET6: + return sizeof(struct sockaddr_in6); + case AF_PACKET: + return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize); + default: + return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize); + } +} + +static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size) +{ + switch(p_family) + { + case AF_INET: + memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size); + break; + case AF_INET6: + memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size); + break; + case AF_PACKET: + memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size); + ((struct sockaddr_ll*)p_dest)->sll_halen = p_size; + break; + default: + memcpy(p_dest->sa_data, p_data, p_size); + break; + } + p_dest->sa_family = p_family; +} + +static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry) +{ + if(!*p_resultList) + { + *p_resultList = p_entry; + } + else + { + struct ifaddrs *l_cur = *p_resultList; + while(l_cur->ifa_next) + { + l_cur = l_cur->ifa_next; + } + l_cur->ifa_next = p_entry; + } +} + +static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList) +{ + struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr); + + size_t l_nameSize = 0; + size_t l_addrSize = 0; + size_t l_dataSize = 0; + + size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); + struct rtattr *l_rta; + for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) + { + void *l_rtaData = RTA_DATA(l_rta); + size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); + switch(l_rta->rta_type) + { + case IFLA_ADDRESS: + case IFLA_BROADCAST: + l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize)); + break; + case IFLA_IFNAME: + l_nameSize += NLMSG_ALIGN(l_rtaSize + 1); + break; + case IFLA_STATS: + l_dataSize += NLMSG_ALIGN(l_rtaSize); + break; + default: + break; + } + } + + struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize); + if (l_entry == NULL) + { + return -1; + } + memset(l_entry, 0, sizeof(struct ifaddrs)); + l_entry->ifa_name = ""; + + char *l_index = ((char *)l_entry) + sizeof(struct ifaddrs); + char *l_name = l_index + sizeof(int); + char *l_addr = l_name + l_nameSize; + char *l_data = l_addr + l_addrSize; + + // save the interface index so we can look it up when handling the addresses. + memcpy(l_index, &l_info->ifi_index, sizeof(int)); + + l_entry->ifa_flags = l_info->ifi_flags; + + l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); + for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) + { + void *l_rtaData = RTA_DATA(l_rta); + size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); + switch(l_rta->rta_type) + { + case IFLA_ADDRESS: + case IFLA_BROADCAST: + { + size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize); + makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize); + ((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index; + ((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type; + if(l_rta->rta_type == IFLA_ADDRESS) + { + l_entry->ifa_addr = (struct sockaddr *)l_addr; + } + else + { + l_entry->ifa_broadaddr = (struct sockaddr *)l_addr; + } + l_addr += NLMSG_ALIGN(l_addrLen); + break; + } + case IFLA_IFNAME: + strncpy(l_name, l_rtaData, l_rtaDataSize); + l_name[l_rtaDataSize] = '\0'; + l_entry->ifa_name = l_name; + break; + case IFLA_STATS: + memcpy(l_data, l_rtaData, l_rtaDataSize); + l_entry->ifa_data = l_data; + break; + default: + break; + } + } + + addToEnd(p_resultList, l_entry); + return 0; +} + +static struct ifaddrs *findInterface(int p_index, struct ifaddrs **p_links, int p_numLinks) +{ + int l_num = 0; + struct ifaddrs *l_cur = *p_links; + while(l_cur && l_num < p_numLinks) + { + char *l_indexPtr = ((char *)l_cur) + sizeof(struct ifaddrs); + int l_index; + memcpy(&l_index, l_indexPtr, sizeof(int)); + if(l_index == p_index) + { + return l_cur; + } + + l_cur = l_cur->ifa_next; + ++l_num; + } + return NULL; +} + +static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, int p_numLinks) +{ + struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr); + struct ifaddrs *l_interface = findInterface(l_info->ifa_index, p_resultList, p_numLinks); + + if(l_info->ifa_family == AF_PACKET) + { + return 0; + } + + size_t l_nameSize = 0; + size_t l_addrSize = 0; + + int l_addedNetmask = 0; + + size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); + struct rtattr *l_rta; + for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) + { + void *l_rtaData = RTA_DATA(l_rta); + size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); + + switch(l_rta->rta_type) + { + case IFA_ADDRESS: + case IFA_LOCAL: + if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask) + { // make room for netmask + l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); + l_addedNetmask = 1; + } + case IFA_BROADCAST: + l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); + break; + case IFA_LABEL: + l_nameSize += NLMSG_ALIGN(l_rtaSize + 1); + break; + default: + break; + } + } + + struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize); + if (l_entry == NULL) + { + return -1; + } + memset(l_entry, 0, sizeof(struct ifaddrs)); + l_entry->ifa_name = (l_interface ? l_interface->ifa_name : ""); + + char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs); + char *l_addr = l_name + l_nameSize; + + l_entry->ifa_flags = l_info->ifa_flags; + if(l_interface) + { + l_entry->ifa_flags |= l_interface->ifa_flags; + } + + l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); + for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) + { + void *l_rtaData = RTA_DATA(l_rta); + size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); + switch(l_rta->rta_type) + { + case IFA_ADDRESS: + case IFA_BROADCAST: + case IFA_LOCAL: + { + size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize); + makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize); + if(l_info->ifa_family == AF_INET6) + { + if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData)) + { + ((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index; + } + } + + if(l_rta->rta_type == IFA_ADDRESS) + { // apparently in a point-to-point network IFA_ADDRESS contains the dest address and IFA_LOCAL contains the local address + if(l_entry->ifa_addr) + { + l_entry->ifa_dstaddr = (struct sockaddr *)l_addr; + } + else + { + l_entry->ifa_addr = (struct sockaddr *)l_addr; + } + } + else if(l_rta->rta_type == IFA_LOCAL) + { + if(l_entry->ifa_addr) + { + l_entry->ifa_dstaddr = l_entry->ifa_addr; + } + l_entry->ifa_addr = (struct sockaddr *)l_addr; + } + else + { + l_entry->ifa_broadaddr = (struct sockaddr *)l_addr; + } + l_addr += NLMSG_ALIGN(l_addrLen); + break; + } + case IFA_LABEL: + strncpy(l_name, l_rtaData, l_rtaDataSize); + l_name[l_rtaDataSize] = '\0'; + l_entry->ifa_name = l_name; + break; + default: + break; + } + } + + if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6)) + { + unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128); + unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen); + char l_mask[16] = {0}; + unsigned i; + for(i=0; i<(l_prefix/8); ++i) + { + l_mask[i] = 0xff; + } + if(l_prefix % 8) + { + l_mask[i] = 0xff << (8 - (l_prefix % 8)); + } + + makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8); + l_entry->ifa_netmask = (struct sockaddr *)l_addr; + } + + addToEnd(p_resultList, l_entry); + return 0; +} + +static int interpretLinks(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList) +{ + int l_numLinks = 0; + pid_t l_pid = getpid(); + for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) + { + unsigned int l_nlsize = p_netlinkList->m_size; + struct nlmsghdr *l_hdr; + for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) + { + if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) + { + continue; + } + + if(l_hdr->nlmsg_type == NLMSG_DONE) + { + break; + } + + if(l_hdr->nlmsg_type == RTM_NEWLINK) + { + if(interpretLink(l_hdr, p_resultList) == -1) + { + return -1; + } + ++l_numLinks; + } + } + } + return l_numLinks; +} + +static int interpretAddrs(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks) +{ + pid_t l_pid = getpid(); + for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) + { + unsigned int l_nlsize = p_netlinkList->m_size; + struct nlmsghdr *l_hdr; + for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) + { + if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) + { + continue; + } + + if(l_hdr->nlmsg_type == NLMSG_DONE) + { + break; + } + + if(l_hdr->nlmsg_type == RTM_NEWADDR) + { + if (interpretAddr(l_hdr, p_resultList, p_numLinks) == -1) + { + return -1; + } + } + } + } + return 0; +} + +int getifaddrs(struct ifaddrs **ifap) +{ + if(!ifap) + { + return -1; + } + *ifap = NULL; + + int l_socket = netlink_socket(); + if(l_socket < 0) + { + return -1; + } + + NetlinkList *l_linkResults = getResultList(l_socket, RTM_GETLINK); + if(!l_linkResults) + { + close(l_socket); + return -1; + } + + NetlinkList *l_addrResults = getResultList(l_socket, RTM_GETADDR); + if(!l_addrResults) + { + close(l_socket); + freeResultList(l_linkResults); + return -1; + } + + int l_result = 0; + int l_numLinks = interpretLinks(l_socket, l_linkResults, ifap); + if(l_numLinks == -1 || interpretAddrs(l_socket, l_addrResults, ifap, l_numLinks) == -1) + { + l_result = -1; + } + + freeResultList(l_linkResults); + freeResultList(l_addrResults); + close(l_socket); + return l_result; +} + +void freeifaddrs(struct ifaddrs *ifa) +{ + struct ifaddrs *l_cur; + while(ifa) + { + l_cur = ifa; + ifa = ifa->ifa_next; + free(l_cur); + } +} diff --git a/xbmc/network/linux/android-ifaddrs/ifaddrs.h b/xbmc/network/linux/android-ifaddrs/ifaddrs.h new file mode 100644 index 0000000..9cd19fe --- /dev/null +++ b/xbmc/network/linux/android-ifaddrs/ifaddrs.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1995, 1999 + * Berkeley Software Design, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp + */ + +#ifndef _IFADDRS_H_ +#define _IFADDRS_H_ + +struct ifaddrs { + struct ifaddrs *ifa_next; + char *ifa_name; + unsigned int ifa_flags; + struct sockaddr *ifa_addr; + struct sockaddr *ifa_netmask; + struct sockaddr *ifa_dstaddr; + void *ifa_data; +}; + +/* + * This may have been defined in . Note that if is + * to be included it must be included before this header file. + */ +#ifndef ifa_broadaddr +#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ +#endif + +#include + +__BEGIN_DECLS +extern int getifaddrs(struct ifaddrs **ifap); +extern void freeifaddrs(struct ifaddrs *ifa); +__END_DECLS + +#endif -- 2.7.1 From 7264fbb7a494c53fb34221ca46e0c9e6db9c9df9 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 9 Jul 2015 02:10:26 +0200 Subject: [PATCH 002/250] Private netlink.h copy from Linux. OSX provides netlink interface and calls, but doesn't provide .h files. Having this, we can further simplify OSX/Android/Linux networking code - same API will be used across all three platforms - less #ifdefs --- xbmc/network/osx/priv_netlink.h | 120 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 xbmc/network/osx/priv_netlink.h diff --git a/xbmc/network/osx/priv_netlink.h b/xbmc/network/osx/priv_netlink.h new file mode 100644 index 0000000..9630969 --- /dev/null +++ b/xbmc/network/osx/priv_netlink.h @@ -0,0 +1,120 @@ +/* + * wpa_supplicant - Private copy of Linux netlink/rtnetlink definitions. + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include + +#ifndef PRIV_NETLINK_H +#define PRIV_NETLINK_H + +/* + * This should be replaced with user space header once one is available with C + * library, etc.. + */ + +#ifndef IFF_LOWER_UP +#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */ +#endif +#ifndef IFF_DORMANT +#define IFF_DORMANT 0x20000 /* driver signals dormant */ +#endif + +#ifndef IFLA_IFNAME +#define IFLA_IFNAME 3 +#endif +#ifndef IFLA_WIRELESS +#define IFLA_WIRELESS 11 +#endif +#ifndef IFLA_OPERSTATE +#define IFLA_OPERSTATE 16 +#endif +#ifndef IFLA_LINKMODE +#define IFLA_LINKMODE 17 +#define IF_OPER_DORMANT 5 +#define IF_OPER_UP 6 +#endif + +#define NLM_F_REQUEST 1 + +#define NETLINK_ROUTE 0 +#define RTMGRP_LINK 1 +#define RTM_BASE 0x10 +#define RTM_NEWLINK (RTM_BASE + 0) +#define RTM_DELLINK (RTM_BASE + 1) +#define RTM_SETLINK (RTM_BASE + 3) + +#define NLMSG_ALIGNTO 4 +#define NLMSG_ALIGN(len) (((len) + NLMSG_ALIGNTO - 1) & ~(NLMSG_ALIGNTO - 1)) +#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) +#define NLMSG_LENGTH(len) ((len) + NLMSG_ALIGN(sizeof(struct nlmsghdr))) +#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len)) +#define NLMSG_DATA(nlh) ((void*) (((char*) nlh) + NLMSG_LENGTH(0))) +#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \ + (struct nlmsghdr *) \ + (((char *)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len))) +#define NLMSG_OK(nlh,len) ((len) >= (int) sizeof(struct nlmsghdr) && \ + (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \ + (int) (nlh)->nlmsg_len <= (len)) +#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len))) + +#define RTA_ALIGNTO 4 +#define RTA_ALIGN(len) (((len) + RTA_ALIGNTO - 1) & ~(RTA_ALIGNTO - 1)) +#define RTA_OK(rta,len) \ +((len) > 0 && (rta)->rta_len >= sizeof(struct rtattr) && \ +(rta)->rta_len <= (len)) +#define RTA_NEXT(rta,attrlen) \ +((attrlen) -= RTA_ALIGN((rta)->rta_len), \ +(struct rtattr *) (((char *)(rta)) + RTA_ALIGN((rta)->rta_len))) +#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len)) +#define RTA_DATA(rta) ((void *) (((char *) (rta)) + RTA_LENGTH(0))) + +#define PF_NETLINK PF_ROUTE +#define AF_NETLINK AF_ROUTE + +typedef int32_t u32; +typedef int16_t u16; + +struct sockaddr_nl +{ + sa_family_t nl_family; + unsigned short nl_pad; + u32 nl_pid; + u32 nl_groups; +}; + +struct nlmsghdr +{ + u32 nlmsg_len; + u16 nlmsg_type; + u16 nlmsg_flags; + u32 nlmsg_seq; + u32 nlmsg_pid; +}; + +struct ifinfomsg +{ + unsigned char ifi_family; + unsigned char __ifi_pad; + unsigned short ifi_type; + int ifi_index; + unsigned ifi_flags; + unsigned ifi_change; +}; + +struct rtattr +{ + unsigned short rta_len; + unsigned short rta_type; +}; + +#endif /* PRIV_NETLINK_H */ -- 2.7.1 From ce21f1f188f35b64d7375945f2a3854a0e54c4fc Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 21 Jul 2015 18:34:46 +0200 Subject: [PATCH 003/250] Propery shutdown connection / close sockets and clear errors. Otherwise the ES can't rebind on crash/fast restart. --- xbmc/network/TCPServer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/xbmc/network/TCPServer.cpp b/xbmc/network/TCPServer.cpp index 9628cd7..ec6c5f3 100644 --- a/xbmc/network/TCPServer.cpp +++ b/xbmc/network/TCPServer.cpp @@ -467,8 +467,11 @@ void CTCPServer::Deinitialize() m_connections.clear(); - for (unsigned int i = 0; i < m_servers.size(); i++) - closesocket(m_servers[i]); + for (unsigned int i = m_servers.size(); i > 0; i--) + { + shutdown(m_servers[i-1], SHUT_RDWR); + closesocket(m_servers[i-1]); + } m_servers.clear(); -- 2.7.1 From 1e1b33fa07524ce3fa6edfa1117b69bfe0dc8c39 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 04:57:40 +0200 Subject: [PATCH 004/250] Create new helper methods needed for IPv6 stack implementation and easy IPv6/v4 address manipulation. --- xbmc/network/Network.cpp | 191 ++++++++++++++++++++++++++++++++++++++ xbmc/network/Network.h | 121 ++++++++++++++++++++++++ xbmc/network/linux/NetworkLinux.h | 2 + 3 files changed, 314 insertions(+) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index 5247036..ee88beb 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -31,6 +31,9 @@ #include "win32/WIN32Util.h" #include "utils/CharsetConverter.h" #endif +#ifdef TARGET_DARWIN +#include // for malloc() and free() +#endif #include "utils/StringUtils.h" using namespace KODI::MESSAGING; @@ -142,6 +145,37 @@ CNetwork::~CNetwork() CApplicationMessenger::GetInstance().PostMsg(TMSG_NETWORKMESSAGE, SERVICES_DOWN, 0); } +std::string CNetwork::GetIpStr(const struct sockaddr *sa) +{ + std::string result; + if (!sa) + return result; + + char s[INET6_ADDRSTRLEN] = {0}; + switch(sa->sa_family) + { + case AF_INET: + inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), s, INET6_ADDRSTRLEN); + break; + case AF_INET6: + inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), s, INET6_ADDRSTRLEN); + break; + default: + return result; + } + + result = s; + return result; +} + +std::string CNetwork::GetIpStr(unsigned long address) +{ + struct in_addr in = { htonl(address) }; + std::string addr = inet_ntoa(in); + + return addr; +} + int CNetwork::ParseHex(char *str, unsigned char *addr) { int len = 0; @@ -161,6 +195,58 @@ int CNetwork::ParseHex(char *str, unsigned char *addr) return len; } +bool CNetwork::ConvIPv4(const std::string &address, struct sockaddr_in *sa, unsigned short port) +{ + if (address.empty()) + return false; + + struct in_addr sin_addr; + int ret = inet_pton(AF_INET, address.c_str(), &sin_addr); + + if (ret > 0 && sa) + { + sa->sin_family = AF_INET; + sa->sin_port = htons(port); + memcpy(&(sa->sin_addr), &sin_addr, sizeof(struct in_addr)); + } + + return (ret > 0); +} + +bool CNetwork::ConvIPv6(const std::string &address, struct sockaddr_in6 *sa, unsigned short port) +{ + if (address.empty()) + return false; + + struct in6_addr sin6_addr; + int ret = inet_pton(AF_INET6, address.c_str(), &sin6_addr); + + if (ret > 0 && sa) + { + sa->sin6_family = AF_INET6; + sa->sin6_port = htons((u_int16_t)port); + memcpy(&(sa->sin6_addr), &sin6_addr, sizeof(struct in6_addr)); + } + + return (ret > 0); +} + +struct sockaddr_storage *CNetwork::ConvIP(const std::string &address, unsigned short port) +{ + struct sockaddr_storage *sa = NULL; + + if (!address.empty()) + if (sa = (struct sockaddr_storage *) malloc(sizeof(struct sockaddr_storage))) + if (ConvIPv4(address, (struct sockaddr_in *) sa, port) + || ConvIPv6(address, (struct sockaddr_in6 *) sa, port)) + return sa; + + if (sa) + free(sa); + + return NULL; +} + bool CNetwork::GetHostName(std::string& hostname) { char hostName[128]; @@ -221,6 +307,63 @@ CNetworkInterface* CNetwork::GetFirstConnectedInterface() return NULL; } +bool CNetwork::AddrMatch(const std::string &addr, const std::string &match_ip, const std::string &match_mask) +{ + if (ConvIPv4(addr) && ConvIPv4(match_ip) && ConvIPv4(match_mask)) + { + unsigned long address = ntohl(inet_addr(addr.c_str())); + unsigned long subnet = ntohl(inet_addr(match_mask.c_str())); + unsigned long local = ntohl(inet_addr(match_ip.c_str())); + return ((address & subnet) == (local & subnet)); + } + else if (!g_application.getNetwork().SupportsIPv6()) + { + return false; + } + else + { + struct sockaddr_in6 address; + struct sockaddr_in6 local; + struct sockaddr_in6 subnet; + if (!ConvIPv6(addr, &address) || !ConvIPv6(match_ip, &local) + || !ConvIPv6(match_mask, &subnet)) + return false; + + // mask matching of IPv6 follows same rule as for IPv4, only + // difference is the storage object of IPv6 address what + // is 16 segments of 8bit information (16bytes => 128bits) + // lets assume we match fd::2 against fd::1/16. this means + // for illustration: + // 00fd:0000:0000:0000:0000:0000:0000:0002 + // to + // 00fd:0000:0000:0000:0000:0000:0000:0001 with mask + // ffff:0000:0000:0000:0000:0000:0000:0000 + // as with IPv4, addr1 & mask == addr2 & mask - for each segment + + // despite the comment explaining uint_8[16] structure + // (what at the time of writing this text was valid for OSX/Linux/BSD) + // rather let's use type independent construction. this is because (OSX????) + // .h files commented the internal s6_addr structure type inside + // sockaddr_in6 as not being mandatory specified by RFC - devil never sleeps. + unsigned int m; + for (m = 0; m < sizeof(address.sin6_addr.s6_addr); m++) + if ((address.sin6_addr.s6_addr[m] & subnet.sin6_addr.s6_addr[m]) != + ( local.sin6_addr.s6_addr[m] & subnet.sin6_addr.s6_addr[m])) + { + m = -1; + } + + // in case of matching addresses, we loop through each segment, + // leaving m with final value of 16. + // if we don't match, m is set to .max() and for() is ended. + // RESULT: any value of m smaller than .max() indicates success. + if (m < (unsigned int)~0) + return true; + } + + return false; +} + bool CNetwork::HasInterfaceForIP(unsigned long address) { unsigned long subnet; @@ -461,6 +604,54 @@ bool CNetwork::PingHost(unsigned long ipaddr, unsigned short port, unsigned int return err_msg == 0; } +std::string CNetwork::CanonizeIPv6(const std::string &address) +{ + std::string result = address; + + struct sockaddr_in6 addr; + if (!ConvIPv6(address, &addr)) + return result; + + result = GetIpStr((const sockaddr*)&addr); + return result; +} + +int CNetwork::PrefixLengthIPv6(const std::string &address) +{ + struct sockaddr_in6 mask; + if (!ConvIPv6(address, &mask)) + return -1; + + unsigned int m; + unsigned int segment_size = 128 / sizeof(mask.sin6_addr.s6_addr); + auto segment_tmax = mask.sin6_addr.s6_addr[0]; + segment_tmax = -1; + + // let's assume mask being ff80:: - in binary form: + // 11111111:10000000 + // as prefix-length is count of leftmost contiguous bits, + // we can simply check how many segments are full of bits (0xff). + // this * nr_bits in segment + individual bits from the first segment + // not full is our prefix-length. + for (m = 0; + m < sizeof(mask.sin6_addr.s6_addr) && (mask.sin6_addr.s6_addr[m] == segment_tmax); + m += 1); + + m *= segment_size; + // if we didn't match all segments (prefixlength not /128) + if (m < 128) + { + // we shift left until we get all bits zero, + // then we have final length (in this case it is /9) + auto leftover_bits = mask.sin6_addr.s6_addr[m / segment_size]; + do { + m++; + } while (leftover_bits <<= 1); + } + + return m; +} + //creates, binds and listens a tcp socket on the desired port. Set bindLocal to //true to bind to localhost only. The socket will listen over ipv6 if possible //and fall back to ipv4 if ipv6 is not available on the platform. diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index 0df104f..17e4e91 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -25,6 +25,7 @@ #include "system.h" #include "settings/lib/ISettingCallback.h" +#include enum EncMode { ENC_NONE = 0, ENC_WEP = 1, ENC_WPA = 2, ENC_WPA2 = 3 }; enum NetworkAssignment { NETWORK_DASH = 0, NETWORK_DHCP = 1, NETWORK_STATIC = 2, NETWORK_DISABLED = 3 }; @@ -95,6 +96,10 @@ public: virtual void GetSettings(NetworkAssignment& assignment, std::string& ipAddress, std::string& networkMask, std::string& defaultGateway, std::string& essId, std::string& key, EncMode& encryptionMode) = 0; virtual void SetSettings(NetworkAssignment& assignment, std::string& ipAddress, std::string& networkMask, std::string& defaultGateway, std::string& essId, std::string& key, EncMode& encryptionMode) = 0; + + // tells if interface itself is configured with IPv6 or IPv4 address + virtual bool isIPv6() { return false; } + virtual bool isIPv4() { return true; } }; class CNetwork @@ -119,6 +124,14 @@ public: // Return the first interface which is active virtual CNetworkInterface* GetFirstConnectedInterface(void); + // Return address family of GetFirstConnectedInterface() interface. With respect to above + // comment this means: + // - in case of returned AF_INET6 - host is configured with IPv6 stack only (we don't need + // iterate over interfaces list further, or trying socket() results to confirm this) + // - AF_INET - host is configured with IPv4 stack. IPv6 availability unknown, we would need + // to loop over the list. + int GetFirstConnectedFamily() { return (GetFirstConnectedInterface() && GetFirstConnectedInterface()->isIPv6() ? AF_INET6 : AF_INET); } + // Return true if there is a interface for the same network as address bool HasInterfaceForIP(unsigned long address); @@ -145,8 +158,116 @@ public: void StartServices(); void StopServices(bool bWait); + /*! + \brief Tests if parameter specifies valid IPv6 address (as specified by RFCs) + \param IP as std::string, struct sockaddr* (non mandatory), + port specification (non mandatory) + \return Function is dual purpose. With just one parameter (IP), + it return true if that IP represents IPv6 address. + If case of second / third supplied argument, it directly + converts parameters into binary struct pointed by 2nd param. + (structure needs to be pre-allocated) + + For direct conversion into (sockaddr*) see ConvIP() variants. + (it is universal wrapper to ConvIPv6/v4()) + */ + static bool ConvIPv6(const std::string &address, struct sockaddr_in6 *sa = NULL, unsigned short port = 0); + + /*! + \brief Tests if parameter specifies valid IPv4 address (as specified by RFCs) + \param IP as std::string, struct sockaddr* (non mandatory), + port specification (non mandatory) + \return Function is dual purpose. With just one parameter (IP), + it return true if that IP represents IPv4 address. + If case of second / third supplied argument, it directly + converts parameters into binary struct pointed by 2nd param. + (structure needs to be pre-allocated) + + For direct conversion into (sockaddr*) see ConvIP() variants. + (it is universal wrapper to ConvIPv6/v4()) + */ + static bool ConvIPv4(const std::string &address, struct sockaddr_in *sa = NULL, unsigned short port = 0); + + /*! + \brief Converts host IP address into binary sockaddr + (wrapper to ConvIP(std::string&, ushort)) + */ + static struct sockaddr_storage *ConvIP(unsigned long address, unsigned short port = 0) { return ConvIP(GetIpStr(address), port); } + + /*! + \brief Converts host IP address into binary sockaddr + \param IP address as std::string, port specification (optional) + \return Function converts host IP to structure directly used + in network API functions. It allocates sockaddr_storage + (via malloc) and returns pointer to it (on error NULL + is returned). af_family, s_addr, port are filled in. + Struct sockaddr_storage can be cast to needed structure + (sockaddr_in, sockaddr_in6, sockaddr, ...) + You have to relese memory with free(p) after use. + */ + static struct sockaddr_storage *ConvIP(const std::string &address, unsigned short port = 0); + static int ParseHex(char *str, unsigned char *addr); + /*! + \brief IPv6/IPv4 compatible conversion of host IP address + \param struct sockaddr + \return Function converts binary structure sockaddr to std::string. + It can read sockaddr_in and sockaddr_in6, cast as (sockaddr*). + IPv4 address is returned in the format x.x.x.x (where x is 0-255), + IPv6 address is returned in it's canonised form. + On error (or no IPv6/v4 valid input) empty string is returned. + */ + static std::string GetIpStr(const struct sockaddr *sa); + + /*! + \brief Converts IP(v4) from ulong to std::string + \param (unsigned long) IP address + \return Function converts from host byte order to network + byte order first. Result is returned as std::string. + */ + static std::string GetIpStr(unsigned long address); + + /*! + \brief Canonisation of IPv6 address + \param Any valid IPv6 address representation (std::string) + \return In respect to RFC 2373, provided string in any legal + representations will be canonised to it's shortest + possible form e.g. + 12AB:0000:0000:CD30:0000:0000:0000:0000 -> 12AB:0:0:CD30:: + */ + static std::string CanonizeIPv6(const std::string &address); + + // Networking API calls are providing IPv6 mask information + // in the same data structure as address itself (128bit information) + // e.g. FFFF:FFFF:FFFF:FFF0:0000:0000:0000:0000 + // This function returns decimal value specifying how many of the + // leftmost contiguous bits of the address comprise + // the prefix. This representation is called prefix-length. + // Above mask represents prefix of length 60 and formal (and canonised) + // address/mask specification would look like this: + // 12AB:0:0:CD30::/60 + // This is also the common preferred way of displaying IPv6 addresses + // return 0-128, -1 in case of error (for instance string's notation + // doesn't comply to standard) + static int PrefixLengthIPv6(const std::string &address); + + // fully IPv4/IPv6 compatible (IPv6 part is limited to addr/mask match only (IPv4 way)) + // TODO: beside addr/match matching IPv6 introduced NetworkDiscoveryProtocol(NDP) + // currently not implemented. + static bool AddrMatch(const std::string &addr, const std::string &match_ip, const std::string &match_mask); + + // Per platform implementation. CNetwork class has both IPv6/IPv4 support, + // but doesn't require each derived class to support IPv6 as well. + // By default we assume IPv6 support not existend (or IPv6 stack unconfigured). + // As the class functions do check that internally, it makes the calls safe + // with no prior checking for actual stack availability. + // In such situations, all calls with IPv6-like parameters will return + // false, -1, or std::string being empty. + // static functions providing only type<>type conversions or formal + // valididy check are unaffected. + virtual bool SupportsIPv6(void) { return false; } + // Return true if given name or ip address corresponds to localhost bool IsLocalHost(const std::string& hostname); }; diff --git a/xbmc/network/linux/NetworkLinux.h b/xbmc/network/linux/NetworkLinux.h index d8b65bc..b38366e 100644 --- a/xbmc/network/linux/NetworkLinux.h +++ b/xbmc/network/linux/NetworkLinux.h @@ -74,6 +74,8 @@ public: virtual std::vector& GetInterfaceList(void); virtual CNetworkInterface* GetFirstConnectedInterface(void); + virtual bool SupportsIPv6() { return true; } + // Ping remote host virtual bool PingHost(unsigned long host, unsigned int timeout_ms = 2000); -- 2.7.1 From 43580d1b6ec1ad4762bb220ef5a5f7ba82b56fa1 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 05:05:23 +0200 Subject: [PATCH 005/250] update to support IPv6 name resolution. --- xbmc/network/DNSNameCache.cpp | 65 ++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/xbmc/network/DNSNameCache.cpp b/xbmc/network/DNSNameCache.cpp index f12c782..8909af6 100644 --- a/xbmc/network/DNSNameCache.cpp +++ b/xbmc/network/DNSNameCache.cpp @@ -22,6 +22,8 @@ #include "threads/SingleLock.h" #include "utils/log.h" #include "utils/StringUtils.h" +#include "network/Network.h" +#include "Application.h" #include #include @@ -42,15 +44,18 @@ bool CDNSNameCache::Lookup(const std::string& strHostName, std::string& strIpAdd if (strHostName.empty() && strIpAddress.empty()) return false; - // first see if this is already an ip address - unsigned long address = inet_addr(strHostName.c_str()); strIpAddress.clear(); - - if (address != INADDR_NONE) + // first see if this is already an ip address { - strIpAddress = StringUtils::Format("%lu.%lu.%lu.%lu", (address & 0xFF), (address & 0xFF00) >> 8, (address & 0xFF0000) >> 16, (address & 0xFF000000) >> 24 ); - return true; + struct sockaddr_in sa; + + if (CNetwork::ConvIPv6(strHostName)) + strIpAddress = CNetwork::CanonizeIPv6(strHostName); + else if (CNetwork::ConvIPv4(strHostName, &sa)) + strIpAddress = inet_ntoa(sa.sin_addr); } + if (!strIpAddress.empty()) + return true; // check if there's a custom entry or if it's already cached if(g_DNSCache.GetCached(strHostName, strIpAddress)) @@ -84,20 +89,48 @@ bool CDNSNameCache::Lookup(const std::string& strHostName, std::string& strIpAdd #endif // perform dns lookup - struct hostent *host = gethostbyname(strHostName.c_str()); - if (host && host->h_addr_list[0]) + struct addrinfo hints; + struct addrinfo *result = NULL; + + memset(&hints, 0, sizeof(struct addrinfo)); + int err; + + // prefer DNS record type (A vs AAAA) be the same as active interface(address). + // otherwise (by default) system prefers A(IPv4) records. this can make + // troubles on dual stack configured hosts or even make network access completely + // unusable in case of pure IPv6 configuration because returning IPv4 record as first. + + // (NOTE/TODO: we might consider for future iterating via all returned results, + // while checking accessibiity and use record which we can access. For now we just grab + // first record from returned list). + do { - strIpAddress = StringUtils::Format("%d.%d.%d.%d", - (unsigned char)host->h_addr_list[0][0], - (unsigned char)host->h_addr_list[0][1], - (unsigned char)host->h_addr_list[0][2], - (unsigned char)host->h_addr_list[0][3]); + if (result) + freeaddrinfo(result); + hints.ai_family = hints.ai_family == 0 ? g_application.getNetwork().GetFirstConnectedFamily() : AF_UNSPEC; + err = getaddrinfo(strHostName.c_str(), NULL, &hints, &result); + } while ((err || !result) && hints.ai_family != AF_UNSPEC); + + std::string str_err; + if (err) + str_err = gai_strerror(err); + + bool bReturn; + if (result) + { + strIpAddress = CNetwork::GetIpStr(result->ai_addr); + freeaddrinfo(result); + CLog::Log(LOGDEBUG, "%s - %s", __FUNCTION__, strIpAddress.c_str()); g_DNSCache.Add(strHostName, strIpAddress); - return true; + bReturn = true; + } + else + { + CLog::Log(LOGERROR, "Unable to lookup host: '%s' (err detail: %s)", strHostName.c_str(), str_err.c_str()); + bReturn = false; } - CLog::Log(LOGERROR, "Unable to lookup host: '%s'", strHostName.c_str()); - return false; + return bReturn; } bool CDNSNameCache::GetCached(const std::string& strHostName, std::string& strIpAddress) -- 2.7.1 From 7f910c82dffe6951874566f893ab2cef56f2b0e4 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 08:50:43 +0200 Subject: [PATCH 006/250] Replace all existing loops over m_interfaces vector with C++11 very simple 'for(auto)' construction. --- xbmc/network/Network.cpp | 70 ++++++++++++++++++------------------------------ xbmc/network/Network.h | 2 ++ 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index ee88beb..811ebc2 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -278,15 +278,12 @@ bool CNetwork::IsLocalHost(const std::string& hostname) && StringUtils::EqualsNoCase(hostname, myhostname)) return true; - std::vector& ifaces = GetInterfaceList(); - std::vector::const_iterator iter = ifaces.begin(); - while (iter != ifaces.end()) + myhostname = CanonizeIPv6(hostname); + if (ConvIPv4(myhostname) || ConvIPv6(myhostname)) { - CNetworkInterface* iface = *iter; - if (iface && iface->GetCurrentIPAddress() == hostname) - return true; - - ++iter; + for (auto &&iface: GetInterfaceList()) + if (iface && iface->GetCurrentIPAddress() == myhostname) + return true; } return false; @@ -294,15 +291,9 @@ bool CNetwork::IsLocalHost(const std::string& hostname) CNetworkInterface* CNetwork::GetFirstConnectedInterface() { - std::vector& ifaces = GetInterfaceList(); - std::vector::const_iterator iter = ifaces.begin(); - while (iter != ifaces.end()) - { - CNetworkInterface* iface = *iter; - if (iface && iface->IsConnected()) - return iface; - ++iter; - } + for (auto &&iface: GetInterfaceList()) + if (iface && iface->IsConnected()) + return iface; return NULL; } @@ -364,26 +355,23 @@ bool CNetwork::AddrMatch(const std::string &addr, const std::string &match_ip, c return false; } -bool CNetwork::HasInterfaceForIP(unsigned long address) +bool CNetwork::HasInterfaceForIP(const std::string &address) { - unsigned long subnet; - unsigned long local; - std::vector& ifaces = GetInterfaceList(); - std::vector::const_iterator iter = ifaces.begin(); - while (iter != ifaces.end()) - { - CNetworkInterface* iface = *iter; - if (iface && iface->IsConnected()) - { - subnet = ntohl(inet_addr(iface->GetCurrentNetmask().c_str())); - local = ntohl(inet_addr(iface->GetCurrentIPAddress().c_str())); - if( (address & subnet) == (local & subnet) ) - return true; - } - ++iter; - } + if (address.empty()) + return false; + + for (auto &&iface: GetInterfaceList()) + if (iface && iface->IsConnected() && + AddrMatch(address, iface->GetCurrentIPAddress(), iface->GetCurrentNetmask())) + return true; + + return false; +} - return false; +bool CNetwork::HasInterfaceForIP(unsigned long address) +{ + std::string addr = GetIpStr(address); + return HasInterfaceForIP(addr); } bool CNetwork::IsAvailable(void) @@ -399,15 +387,9 @@ bool CNetwork::IsConnected() CNetworkInterface* CNetwork::GetInterfaceByName(const std::string& name) { - std::vector& ifaces = GetInterfaceList(); - std::vector::const_iterator iter = ifaces.begin(); - while (iter != ifaces.end()) - { - CNetworkInterface* iface = *iter; - if (iface && iface->GetName() == name) - return iface; - ++iter; - } + for (auto &&iface: GetInterfaceList()) + if (iface && iface->GetName() == name) + return iface; return NULL; } diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index 17e4e91..cf799e1 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -133,6 +133,8 @@ public: int GetFirstConnectedFamily() { return (GetFirstConnectedInterface() && GetFirstConnectedInterface()->isIPv6() ? AF_INET6 : AF_INET); } // Return true if there is a interface for the same network as address + bool HasInterfaceForIP(const std::string &address); + // Backward compatibility call. It wraps IPv6 compatible function above bool HasInterfaceForIP(unsigned long address); // Return true if there's at least one defined network interface -- 2.7.1 From 62970de6dac0ba33e0a290a731f165942915e646 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 10 Sep 2015 19:50:01 +0200 Subject: [PATCH 007/250] current WOL implementation can't be updated for IPv6 as it's working mechanism changed completely (IPv6 has no ARP). Comment accordingly in Network.h, make those calls safe by returning false immediatelly upon call when host has only IPv6 configuration. --- xbmc/network/Network.cpp | 3 +++ xbmc/network/Network.h | 5 +++++ xbmc/network/WakeOnAccess.cpp | 7 ++----- xbmc/network/linux/NetworkLinux.cpp | 6 ++++++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index 811ebc2..4d122b3 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -419,6 +419,9 @@ bool CNetwork::WakeOnLan(const char* mac) unsigned char buf [128]; unsigned char *ptr; + if (GetFirstConnectedFamily() == AF_INET6) + return false; + // Fetch the hardware address if (!in_ether(mac, ethaddr)) { diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index cf799e1..d2a0e3e 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -144,6 +144,11 @@ public: bool IsConnected(void); // Return true if the magic packet was send + // TODO: current implementation uses ARP for MAC resolution. + // as IPv6 has no ARP, it will provide expected result + // only if target host is accessible via IPv4. + // (anyhow it's use is safe regardless actual. + // configuration, returns false for IPv6 only stack) bool WakeOnLan(const char *mac); // Return true if host replies to ping diff --git a/xbmc/network/WakeOnAccess.cpp b/xbmc/network/WakeOnAccess.cpp index a6fd2af..a93f76c 100644 --- a/xbmc/network/WakeOnAccess.cpp +++ b/xbmc/network/WakeOnAccess.cpp @@ -106,12 +106,9 @@ bool CMACDiscoveryJob::DoWork() return false; } - std::vector& ifaces = g_application.getNetwork().GetInterfaceList(); - for (std::vector::const_iterator it = ifaces.begin(); it != ifaces.end(); ++it) - { - if ((*it)->GetHostMacAddress(ipAddress, m_macAddres)) + for (auto &&iface : g_application.getNetwork().GetInterfaceList()) + if (iface->GetHostMacAddress(ipAddress, m_macAddres)) return true; - } return false; } diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 1230c61..a5047e4 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -569,6 +569,9 @@ bool CNetworkLinux::PingHost(unsigned long remote_ip, unsigned int timeout_ms) #if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) bool CNetworkInterfaceLinux::GetHostMacAddress(unsigned long host_ip, std::string& mac) { + if (m_network->GetFirstConnectedFamily() == AF_INET6 || isIPv6()) + return false; + bool ret = false; size_t needed; char *buf, *next; @@ -619,6 +622,9 @@ bool CNetworkInterfaceLinux::GetHostMacAddress(unsigned long host_ip, std::strin #else bool CNetworkInterfaceLinux::GetHostMacAddress(unsigned long host_ip, std::string& mac) { + if (m_network->GetFirstConnectedFamily() == AF_INET6 || isIPv6()) + return false; + struct arpreq areq; struct sockaddr_in* sin; -- 2.7.1 From 992d8c3572f6939363c993f16900b15c54bcec18 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 10 Sep 2015 19:51:33 +0200 Subject: [PATCH 008/250] update PingHost() functions to IPv6 compatibility. - CNetwork::ConnectHostPort() and CNetwork::PingHost() were updated for full IPv6/IPv4 compatibility. IP host address parameter changed to std::string and created wrapper for old call via hostip as ulong. - Linux implementation for PingHost was updated to use ping/ping6 as needed - W32 impl was aligned to changed function template, on IPv6 host param returns false, no change otherwise. --- xbmc/network/Network.cpp | 19 ++++++++++--------- xbmc/network/Network.h | 20 +++++++++++++++++--- xbmc/network/linux/NetworkLinux.cpp | 16 +++++++++------- xbmc/network/linux/NetworkLinux.h | 2 +- xbmc/network/windows/NetworkWin32.cpp | 8 ++++++-- xbmc/network/windows/NetworkWin32.h | 2 +- 6 files changed, 44 insertions(+), 23 deletions(-) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index 4d122b3..0834206 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -550,17 +550,17 @@ static const char* ConnectHostPort(SOCKET soc, const struct sockaddr_in& addr, s return 0; // success } -bool CNetwork::PingHost(unsigned long ipaddr, unsigned short port, unsigned int timeOutMs, bool readability_check) +bool CNetwork::PingHost(const std::string &ipaddr, unsigned short port, unsigned int timeOutMs, bool readability_check) { if (port == 0) // use icmp ping - return PingHost (ipaddr, timeOutMs); + return PingHostImpl (ipaddr, timeOutMs); - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = ipaddr; + struct sockaddr_storage *addr = ConvIP(ipaddr, port); - SOCKET soc = socket(AF_INET, SOCK_STREAM, 0); + if (!addr) + return false; + + SOCKET soc = socket(addr->ss_family, SOCK_STREAM, 0); const char* err_msg = "invalid socket"; @@ -570,7 +570,7 @@ bool CNetwork::PingHost(unsigned long ipaddr, unsigned short port, unsigned int tmout.tv_sec = timeOutMs / 1000; tmout.tv_usec = (timeOutMs % 1000) * 1000; - err_msg = ConnectHostPort (soc, addr, tmout, readability_check); + err_msg = ConnectHostPort (soc, (const struct sockaddr_in&)addr, tmout, readability_check); (void) closesocket (soc); } @@ -583,9 +583,10 @@ bool CNetwork::PingHost(unsigned long ipaddr, unsigned short port, unsigned int std::string sock_err = strerror(errno); #endif - CLog::Log(LOGERROR, "%s(%s:%d) - %s (%s)", __FUNCTION__, inet_ntoa(addr.sin_addr), port, err_msg, sock_err.c_str()); + CLog::Log(LOGERROR, "%s(%s:%d) - %s (%s)", __FUNCTION__, ipaddr.c_str(), port, err_msg, sock_err.c_str()); } + free(addr); return err_msg == 0; } diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index d2a0e3e..e1652ba 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -151,9 +151,23 @@ public: // configuration, returns false for IPv6 only stack) bool WakeOnLan(const char *mac); - // Return true if host replies to ping - bool PingHost(unsigned long host, unsigned short port, unsigned int timeout_ms = 2000, bool readability_check = false); - virtual bool PingHost(unsigned long host, unsigned int timeout_ms = 2000) = 0; + /*! + \brief Ping remote host + \param IP host address, port (optional) + \return Return true if host replies to ping, false otherwise + Function is IPv6/v4 compatible + - If port is not specified, system cmd ping/ping6 is called + - If port is specified, host is contacted via sock connect() + */ + bool PingHost(const std::string &ipaddr, unsigned short port, unsigned int timeout_ms = 2000, bool readability_check = false); + + /*! + \brief Ping remote host (compatibility wrapper, see PingHost(std::string&...)) + */ + bool PingHost(unsigned long ipaddr, unsigned short port, unsigned int timeout_ms = 2000, bool readability_check = false) + { return PingHost(GetIpStr(ipaddr), port, timeout_ms, readability_check); } + + virtual bool PingHostImpl(const std::string &target, unsigned int timeout_ms = 2000) = 0; // Get/set the nameserver(s) virtual std::vector GetNameServers(void) = 0; diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index a5047e4..5a8a7e4 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -536,19 +536,21 @@ void CNetworkLinux::SetNameServers(const std::vector& nameServers) #endif } -bool CNetworkLinux::PingHost(unsigned long remote_ip, unsigned int timeout_ms) +bool CNetworkLinux::PingHostImpl(const std::string &target, unsigned int timeout_ms) { - char cmd_line [64]; + bool isIPv6 = CNetwork::ConvIPv6(target); + if (isIPv6 && !SupportsIPv6()) + return false; - struct in_addr host_ip; - host_ip.s_addr = remote_ip; + char cmd_line [64]; + std::string ping = isIPv6 ? "ping6" : "ping"; #if defined (TARGET_DARWIN_IOS) // no timeout option available - sprintf(cmd_line, "ping -c 1 %s", inet_ntoa(host_ip)); + sprintf(cmd_line, "%s -c 1 %s", ping.c_str(), target.c_str()); #elif defined (TARGET_DARWIN) || defined (TARGET_FREEBSD) - sprintf(cmd_line, "ping -c 1 -t %d %s", timeout_ms / 1000 + (timeout_ms % 1000) != 0, inet_ntoa(host_ip)); + sprintf(cmd_line, "%s -c 1 -%s %d %s", ping.c_str(), isIPv6 ? "i" : "t", timeout_ms / 1000 + (timeout_ms % 1000) != 0, target.c_str()); #else - sprintf(cmd_line, "ping -c 1 -w %d %s", timeout_ms / 1000 + (timeout_ms % 1000) != 0, inet_ntoa(host_ip)); + sprintf(cmd_line, "%s -c 1 -w %d %s", ping.c_str(), timeout_ms / 1000 + (timeout_ms % 1000) != 0, target.c_str()); #endif int status = system (cmd_line); diff --git a/xbmc/network/linux/NetworkLinux.h b/xbmc/network/linux/NetworkLinux.h index b38366e..8534bc1 100644 --- a/xbmc/network/linux/NetworkLinux.h +++ b/xbmc/network/linux/NetworkLinux.h @@ -77,7 +77,7 @@ public: virtual bool SupportsIPv6() { return true; } // Ping remote host - virtual bool PingHost(unsigned long host, unsigned int timeout_ms = 2000); + virtual bool PingHostImpl(const std::string &target, unsigned int timeout_ms = 2000); // Get/set the nameserver(s) virtual std::vector GetNameServers(void); diff --git a/xbmc/network/windows/NetworkWin32.cpp b/xbmc/network/windows/NetworkWin32.cpp index c7a406f..95198a8 100644 --- a/xbmc/network/windows/NetworkWin32.cpp +++ b/xbmc/network/windows/NetworkWin32.cpp @@ -254,15 +254,19 @@ void CNetworkWin32::SetNameServers(const std::vector& nameServers) return; } -bool CNetworkWin32::PingHost(unsigned long host, unsigned int timeout_ms /* = 2000 */) +bool CNetworkWin32::PingHostImpl(const std::string &target, unsigned int timeout_ms /* = 2000 */) { + struct sockaddr_in sa; + if (!CNetwork::ConvIPv4(target, &sa)) + return false; + char SendData[] = "poke"; HANDLE hIcmpFile = IcmpCreateFile(); BYTE ReplyBuffer [sizeof(ICMP_ECHO_REPLY) + sizeof(SendData)]; SetLastError(ERROR_SUCCESS); - DWORD dwRetVal = IcmpSendEcho(hIcmpFile, host, SendData, sizeof(SendData), + DWORD dwRetVal = IcmpSendEcho(hIcmpFile, ntohl(sa.sin_addr), SendData, sizeof(SendData), NULL, ReplyBuffer, sizeof(ReplyBuffer), timeout_ms); DWORD lastErr = GetLastError(); diff --git a/xbmc/network/windows/NetworkWin32.h b/xbmc/network/windows/NetworkWin32.h index 71019f0..d52d13d 100644 --- a/xbmc/network/windows/NetworkWin32.h +++ b/xbmc/network/windows/NetworkWin32.h @@ -74,7 +74,7 @@ public: virtual std::vector& GetInterfaceList(void); // Ping remote host - virtual bool PingHost(unsigned long host, unsigned int timeout_ms = 2000); + virtual bool PingHostImpl(const std::string &target, unsigned int timeout_ms = 2000); // Get/set the nameserver(s) virtual std::vector GetNameServers(void); -- 2.7.1 From b8259391459c9bc93a6cfae312e3550ba83d7220 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 09:28:31 +0200 Subject: [PATCH 009/250] Provide more detailed debugging info inside CreateTCPServerSocket() function - include port and text of current error. --- xbmc/network/Network.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index 0834206..c7ea610 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -684,7 +684,8 @@ int CreateTCPServerSocket(const int port, const bool bindLocal, const int backlo { closesocket(sock); sock = -1; - CLog::Log(LOGDEBUG, "%s Server: Failed to bind ipv6 serversocket, trying ipv4", callerName); + CLog::Log(LOGDEBUG, "%s Server: Failed to bind ipv6 serversocket on port %d, trying ipv4 (error was %s (%d))", + callerName, port, strerror(errno), errno); } } @@ -706,7 +707,8 @@ int CreateTCPServerSocket(const int port, const bool bindLocal, const int backlo if (bind( sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) < 0) { closesocket(sock); - CLog::Log(LOGERROR, "%s Server: Failed to bind ipv4 serversocket", callerName); + CLog::Log(LOGERROR, "%s Server: Failed to bind ipv4 serversocket on port %d, trying ipv4 (error was %s (%d))", + callerName, port, strerror(errno), errno); return INVALID_SOCKET; } } -- 2.7.1 From 0d81afbd69652f74df94b8099f616bbd48fb1a4c Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 09:35:19 +0200 Subject: [PATCH 010/250] create new announcer Network and emessage [CNetwork] NETWORK_CHANGED. if triggered, all Services are asked to restart to rebind onto new network configuration. "OnInterfacesChange" from "Network" is announced globally. --- xbmc/interfaces/IAnnouncer.h | 7 +++++-- xbmc/network/Network.cpp | 8 ++++++++ xbmc/network/Network.h | 3 ++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/xbmc/interfaces/IAnnouncer.h b/xbmc/interfaces/IAnnouncer.h index e3dfdd1..3284590 100644 --- a/xbmc/interfaces/IAnnouncer.h +++ b/xbmc/interfaces/IAnnouncer.h @@ -33,10 +33,11 @@ namespace ANNOUNCEMENT Application = 0x040, Input = 0x080, PVR = 0x100, - Other = 0x200 + Other = 0x200, + Network = 0x400 }; - #define ANNOUNCE_ALL (Player | Playlist | GUI | System | VideoLibrary | AudioLibrary | Application | Input | ANNOUNCEMENT::PVR | Other) + #define ANNOUNCE_ALL (Player | Playlist | GUI | System | VideoLibrary | AudioLibrary | Application | Input | ANNOUNCEMENT::PVR | Other | Network) /*! \brief Returns a string representation for the @@ -68,6 +69,8 @@ namespace ANNOUNCEMENT return "PVR"; case Other: return "Other"; + case Network: + return "Network"; default: return "Unknown"; } diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index c7ea610..b20eae5 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -35,6 +35,7 @@ #include // for malloc() and free() #endif #include "utils/StringUtils.h" +#include "xbmc/interfaces/AnnouncementManager.h" using namespace KODI::MESSAGING; @@ -409,6 +410,13 @@ void CNetwork::NetworkMessage(EMESSAGE message, int param) CLog::Log(LOGDEBUG, "%s - Waiting for network services to stop",__FUNCTION__); CNetworkServices::GetInstance().Stop(true); // wait for network services to stop break; + + case NETWORK_CHANGED: + CLog::Log(LOGDEBUG, "%s - Network setup changed. Will restart network services",__FUNCTION__); + ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::Network, "network", "OnInterfacesChange"); + NetworkMessage(SERVICES_DOWN, 0); + NetworkMessage(SERVICES_UP, 0); + break; } } diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index e1652ba..62ca461 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -108,7 +108,8 @@ public: enum EMESSAGE { SERVICES_UP, - SERVICES_DOWN + SERVICES_DOWN, + NETWORK_CHANGED }; CNetwork(); -- 2.7.1 From 06579ee7ab98bc4171cdb6b1bae3382c83440da7 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 13:00:16 +0200 Subject: [PATCH 011/250] Let's provide Network stack monitoring via NETLINK interface. Currently reported events are changes in link status and interface is being added or removed. On event we requery interfaces list and IF informations. Announcement from "Network" is sent with event data "OnNetworkChange". --- xbmc/network/Network.cpp | 19 ++++++++++-- xbmc/network/Network.h | 5 ++++ xbmc/network/linux/NetworkLinux.cpp | 60 +++++++++++++++++++++++++++++++++++++ xbmc/network/linux/NetworkLinux.h | 22 ++++++++++++-- 4 files changed, 101 insertions(+), 5 deletions(-) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index b20eae5..31d324a 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -136,13 +136,17 @@ int NetworkAccessPoint::FreqToChannel(float frequency) } -CNetwork::CNetwork() +CNetwork::CNetwork() : + m_bStop(false) { CApplicationMessenger::GetInstance().PostMsg(TMSG_NETWORKMESSAGE, SERVICES_UP, 0); + m_signalNetworkChange.Reset(); } CNetwork::~CNetwork() { + m_bStop = true; + m_signalNetworkChange.Set(); CApplicationMessenger::GetInstance().PostMsg(TMSG_NETWORKMESSAGE, SERVICES_DOWN, 0); } @@ -377,8 +381,16 @@ bool CNetwork::HasInterfaceForIP(unsigned long address) bool CNetwork::IsAvailable(void) { - std::vector& ifaces = GetInterfaceList(); - return (ifaces.size() != 0); + std::forward_list& ifaces = GetInterfaceList(); + + while (!m_bStop && wait && ifaces.empty()) + { + m_signalNetworkChange.WaitMSec(5000); + ifaces = GetInterfaceList(); + m_signalNetworkChange.Reset(); + } + + return (!ifaces.empty()); } bool CNetwork::IsConnected() @@ -412,6 +424,7 @@ void CNetwork::NetworkMessage(EMESSAGE message, int param) break; case NETWORK_CHANGED: + m_signalNetworkChange.Set(); CLog::Log(LOGDEBUG, "%s - Network setup changed. Will restart network services",__FUNCTION__); ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::Network, "network", "OnInterfacesChange"); NetworkMessage(SERVICES_DOWN, 0); diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index 62ca461..661f137 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -23,6 +23,7 @@ #include #include "system.h" +#include "threads/Event.h" #include "settings/lib/ISettingCallback.h" #include @@ -292,6 +293,10 @@ public: // Return true if given name or ip address corresponds to localhost bool IsLocalHost(const std::string& hostname); + +private: + CEvent m_signalNetworkChange; + bool m_bStop; }; #ifdef HAS_LINUX_NETWORK diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 5a8a7e4..a53c582 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -20,7 +20,10 @@ #include +#include "xbmc/messaging/ApplicationMessenger.h" +#include #include +#include #include #include #include @@ -28,6 +31,8 @@ #include #include #include +#else + #include "network/osx/priv_netlink.h" #endif #ifdef TARGET_ANDROID #include "android/bionic_supplement/bionic_supplement.h" @@ -67,6 +72,8 @@ #include "utils/log.h" #include "utils/StringUtils.h" +using namespace KODI::MESSAGING; + CNetworkInterfaceLinux::CNetworkInterfaceLinux(CNetworkLinux* network, std::string interfaceName, char interfaceMacAddrRaw[6]): m_interfaceName(interfaceName), m_interfaceMacAdr(StringUtils::Format("%02X:%02X:%02X:%02X:%02X:%02X", @@ -312,6 +319,8 @@ CNetworkLinux::CNetworkLinux(void) { m_sock = socket(AF_INET, SOCK_DGRAM, 0); queryInterfaceList(); + m_updThread = new CNetworkLinuxUpdateThread(this); + m_updThread->Create(false); } CNetworkLinux::~CNetworkLinux(void) @@ -319,6 +328,15 @@ CNetworkLinux::~CNetworkLinux(void) if (m_sock != -1) close(CNetworkLinux::m_sock); + m_updThread->StopThread(false); + CSingleLock lock(m_lock); + InterfacesClear(); + DeleteRemoved(); + m_updThread->StopThread(true); +} + +void CNetworkLinux::DeleteRemoved(void) +{ std::vector::iterator it = m_interfaces.begin(); while(it != m_interfaces.end()) { @@ -1125,4 +1143,46 @@ void CNetworkInterfaceLinux::WriteSettings(FILE* fw, NetworkAssignment assignmen fprintf(fw, "auto %s\n\n", GetName().c_str()); } +CNetworkLinuxUpdateThread::CNetworkLinuxUpdateThread(CNetworkLinux *owner) + : CThread("NetConfUpdater") + , m_owner(owner) +{ +} +void CNetworkLinuxUpdateThread::Process(void) +{ + struct sockaddr_nl addr; + int fds = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + struct pollfd m_fds = { fds, POLLIN, 0 }; + char msg[4096]; + + memset (&addr, 0, sizeof(struct sockaddr_nl)); + addr.nl_family = AF_NETLINK; + addr.nl_pid = getpid (); +#if defined(TARGET_LINUX) + addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR; + /* RTMGRP_IPV4_IFADDR | RTMGRP_TC | RTMGRP_IPV4_MROUTE | + RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_RULE | + RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_MROUTE | + RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFINFO | + RTMGRP_IPV6_PREFIX */ +#else + addr.nl_groups = RTMGRP_LINK; +#endif + + if (-1 == bind(fds, (const struct sockaddr *) &addr, sizeof(struct sockaddr))) + return; + + fcntl(fds, F_SETFL, O_NONBLOCK); + + while(!m_bStop) + if (poll(&m_fds, 1, 1000) > 0) + { + while (!m_bStop && recv(fds, &msg, sizeof(msg), 0) > 0); + if (m_bStop) + continue; + CLog::Log(LOGINFO, "Interfaces change %s", __FUNCTION__); + m_owner->queryInterfaceList(); + CApplicationMessenger::GetInstance().PostMsg(TMSG_NETWORKMESSAGE, m_owner->NETWORK_CHANGED, 0); + } +} diff --git a/xbmc/network/linux/NetworkLinux.h b/xbmc/network/linux/NetworkLinux.h index 8534bc1..eb6abb2 100644 --- a/xbmc/network/linux/NetworkLinux.h +++ b/xbmc/network/linux/NetworkLinux.h @@ -25,8 +25,11 @@ #include #include #include "network/Network.h" +#include "threads/CriticalSection.h" +#include "threads/Thread.h" class CNetworkLinux; +class CNetworkLinuxUpdateThread; class CNetworkInterfaceLinux : public CNetworkInterface { @@ -66,6 +69,9 @@ private: class CNetworkLinux : public CNetwork { + friend class CNetworkLinuxUpdateThread; + friend class CNetworkInterfaceLinux; + public: CNetworkLinux(void); virtual ~CNetworkLinux(void); @@ -83,14 +89,26 @@ public: virtual std::vector GetNameServers(void); virtual void SetNameServers(const std::vector& nameServers); - friend class CNetworkInterfaceLinux; - private: int GetSocket() { return m_sock; } void GetMacAddress(const std::string& interfaceName, char macAddrRaw[6]); void queryInterfaceList(); std::vector m_interfaces; int m_sock; + + CNetworkLinuxUpdateThread *m_updThread; + CCriticalSection m_lock; +}; + +class CNetworkLinuxUpdateThread : public CThread +{ +public: + CNetworkLinuxUpdateThread(CNetworkLinux *owner); + virtual ~CNetworkLinuxUpdateThread(void) {}; + +protected: + void Process(void); + CNetworkLinux *m_owner; }; #endif -- 2.7.1 From c5cb829630e7b9b4d3e071ef4227ffe7bf154b5f Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 10:00:32 +0200 Subject: [PATCH 012/250] Flush all cached hostnames on Network change --- xbmc/network/DNSNameCache.cpp | 23 +++++++++++++++++++++-- xbmc/network/DNSNameCache.h | 6 +++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/xbmc/network/DNSNameCache.cpp b/xbmc/network/DNSNameCache.cpp index 8909af6..7d79bd6 100644 --- a/xbmc/network/DNSNameCache.cpp +++ b/xbmc/network/DNSNameCache.cpp @@ -29,15 +29,34 @@ #include #include +using namespace ANNOUNCEMENT; + CDNSNameCache g_DNSCache; CCriticalSection CDNSNameCache::m_critical; CDNSNameCache::CDNSNameCache(void) -{} +{ + CAnnouncementManager::GetInstance().AddAnnouncer(this); +} CDNSNameCache::~CDNSNameCache(void) -{} +{ + CAnnouncementManager::GetInstance().RemoveAnnouncer(this); +} + +void CDNSNameCache::Flush() +{ + CSingleLock lock(m_critical); + CLog::Log(LOGINFO, "%s - DNS cache flushed (%u records)", __FUNCTION__, g_DNSCache.m_vecDNSNames.size()); + g_DNSCache.m_vecDNSNames.clear(); +} + +void CDNSNameCache::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) +{ + if (!strcmp(sender, "network") && !strcmp(message, "OnInterfacesChange")) + Flush(); +} bool CDNSNameCache::Lookup(const std::string& strHostName, std::string& strIpAddress) { diff --git a/xbmc/network/DNSNameCache.h b/xbmc/network/DNSNameCache.h index 97bb20b..86afcfd 100644 --- a/xbmc/network/DNSNameCache.h +++ b/xbmc/network/DNSNameCache.h @@ -22,10 +22,11 @@ #include #include +#include "interfaces/AnnouncementManager.h" class CCriticalSection; -class CDNSNameCache +class CDNSNameCache : public ANNOUNCEMENT::IAnnouncer { public: class CDNSName @@ -39,8 +40,11 @@ public: static bool Lookup(const std::string& strHostName, std::string& strIpAddress); static void Add(const std::string& strHostName, const std::string& strIpAddress); + void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data); + protected: static bool GetCached(const std::string& strHostName, std::string& strIpAddress); + void Flush(); static CCriticalSection m_critical; std::vector m_vecDNSNames; }; -- 2.7.1 From a2edb2d5fa9516a0ebe0a85fb192a203f51042cd Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 10:08:55 +0200 Subject: [PATCH 013/250] Add IPv6 destinations to Internet reachability test. Those will be used only in case host has IPv6 only configuration. Without this change, pure IPv6 connectivity would be checked with trying to access IPv4 resolved addresses. --- xbmc/filesystem/CurlFile.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/xbmc/filesystem/CurlFile.cpp b/xbmc/filesystem/CurlFile.cpp index 06dd230..ccbc2e2 100644 --- a/xbmc/filesystem/CurlFile.cpp +++ b/xbmc/filesystem/CurlFile.cpp @@ -18,6 +18,8 @@ * */ +#include "network/Network.h" +#include "Application.h" #include "CurlFile.h" #include "utils/URIUtils.h" #include "Util.h" @@ -912,13 +914,13 @@ bool CCurlFile::Download(const std::string& strURL, const std::string& strFileNa // Detect whether we are "online" or not! Very simple and dirty! bool CCurlFile::IsInternet() { - CURL url("http://www.msftncsi.com/ncsi.txt"); + CURL url(StringUtils::Format("http://%s.msftncsi.com/ncsi.txt", g_application.getNetwork().GetFirstConnectedFamily() == AF_INET6 ? "ipv6" : "www")); bool found = Exists(url); if (!found) { // fallback Close(); - url.Parse("http://www.w3.org/"); + url.Parse(StringUtils::Format("http://%s.w3.org/", g_application.getNetwork().GetFirstConnectedFamily() == AF_INET6 ? "ipv6" : "www")); found = Exists(url); } Close(); -- 2.7.1 From 5edf6900427929c1c857d64ad43d858fbd2dcdf0 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 10:15:25 +0200 Subject: [PATCH 014/250] Provide new IPv6/IPv4 compatible test and manipulation methods of CNetwork via those wrappers: - on many places through whole Kodi code there is use of IPv6 incompatible API calls like inet_ntoa(), inet_aton(), inet_addr() (Not only are those known not to work for IPv6 queries, in some cases it's behaviour is undefined and it's use is discouraged. TODO: all such calls should be eventually changed to use this new API and direct use of system level network calls should not be allowed anymore) --- xbmc/utils/URIUtils.cpp | 15 +++++++++++++++ xbmc/utils/URIUtils.h | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp index 592dfed..5b7d884 100644 --- a/xbmc/utils/URIUtils.cpp +++ b/xbmc/utils/URIUtils.cpp @@ -1360,3 +1360,18 @@ bool URIUtils::IsUsingFastSwitch(const std::string& strFile) { return IsUDP(strFile) || IsTCP(strFile) || IsPVRChannel(strFile); } + +bool URIUtils::ConvIPv6(const std::string &address, struct sockaddr_in6 *sa) +{ + return CNetwork::ConvIPv6(address, sa); +} + +bool URIUtils::ConvIPv4(const std::string &address, struct sockaddr_in *sa) +{ + return CNetwork::ConvIPv4(address, sa); +} + +std::string URIUtils::CanonizeIPv6(const std::string &address) +{ + return CNetwork::CanonizeIPv6(address); +} diff --git a/xbmc/utils/URIUtils.h b/xbmc/utils/URIUtils.h index 01323d7..257b8e2 100644 --- a/xbmc/utils/URIUtils.h +++ b/xbmc/utils/URIUtils.h @@ -221,6 +221,10 @@ public: */ static bool UpdateUrlEncoding(std::string &strFilename); + static bool ConvIPv6(const std::string &address, struct sockaddr_in6 *sa = NULL); + static bool ConvIPv4(const std::string &address, struct sockaddr_in *sa = NULL); + static std::string CanonizeIPv6(const std::string &address); + private: static std::string resolvePath(const std::string &path); }; -- 2.7.1 From d4724b89f472aa6a3a8cec6b8f95ef6f66880d36 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 10:36:48 +0200 Subject: [PATCH 015/250] Update internals according to commit previous commit 03081378a259f1c32f3411c474b6ec2aabfec29e --- xbmc/network/Network.cpp | 5 +- xbmc/network/Network.h | 8 ++- xbmc/network/linux/NetworkLinux.cpp | 135 +++++++++++++++++++++--------------- xbmc/network/linux/NetworkLinux.h | 39 ++++++++--- xbmc/utils/URIUtils.cpp | 41 ++++------- 5 files changed, 132 insertions(+), 96 deletions(-) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index 31d324a..a5bbe7e 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -18,6 +18,8 @@ * */ +#include + #include #include #include @@ -31,9 +33,6 @@ #include "win32/WIN32Util.h" #include "utils/CharsetConverter.h" #endif -#ifdef TARGET_DARWIN -#include // for malloc() and free() -#endif #include "utils/StringUtils.h" #include "xbmc/interfaces/AnnouncementManager.h" diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index 661f137..a1da8a6 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -21,9 +21,11 @@ #include #include +#include #include "system.h" #include "threads/Event.h" +#include "threads/CriticalSection.h" #include "settings/lib/ISettingCallback.h" #include @@ -120,7 +122,8 @@ public: virtual bool GetHostName(std::string& hostname); // Return the list of interfaces - virtual std::vector& GetInterfaceList(void) = 0; + virtual std::forward_list& GetInterfaceList(void) = 0; + CNetworkInterface* GetInterfaceByName(const std::string& name); // Return the first interface which is active @@ -294,6 +297,9 @@ public: // Return true if given name or ip address corresponds to localhost bool IsLocalHost(const std::string& hostname); +protected: + CCriticalSection m_lock; + private: CEvent m_signalNetworkChange; bool m_bStop; diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index a53c582..71f5404 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -27,10 +27,18 @@ #include #include #include +#ifdef TARGET_ANDROID + #include "network/linux/android-ifaddrs/ifaddrs.h" +#endif #if defined(TARGET_LINUX) #include #include #include + #include + #include +#ifndef _IFADDRS_H_ + #include +#endif #else #include "network/osx/priv_netlink.h" #endif @@ -74,7 +82,14 @@ using namespace KODI::MESSAGING; -CNetworkInterfaceLinux::CNetworkInterfaceLinux(CNetworkLinux* network, std::string interfaceName, char interfaceMacAddrRaw[6]): +CNetworkInterfaceLinux::CNetworkInterfaceLinux(CNetworkLinux* network, bool sa_ipv6, unsigned int ifa_flags, + std::string ifa_addr, std::string ifa_netmask, std::string interfaceName, + char interfaceMacAddrRaw[6]) : + m_interfaceIpv6(sa_ipv6), + m_interfaceFlags(ifa_flags), + m_interfaceAddr(ifa_addr), + m_interfaceNetmask(ifa_netmask), + m_removed(false), m_interfaceName(interfaceName), m_interfaceMacAdr(StringUtils::Format("%02X:%02X:%02X:%02X:%02X:%02X", (uint8_t)interfaceMacAddrRaw[0], @@ -337,16 +352,16 @@ CNetworkLinux::~CNetworkLinux(void) void CNetworkLinux::DeleteRemoved(void) { - std::vector::iterator it = m_interfaces.begin(); - while(it != m_interfaces.end()) - { - CNetworkInterface* nInt = *it; - delete nInt; - it = m_interfaces.erase(it); - } + m_interfaces.remove_if(IsRemoved); } -std::vector& CNetworkLinux::GetInterfaceList(void) +void CNetworkLinux::InterfacesClear(void) +{ + for (auto &&iface: m_interfaces) + ((CNetworkInterfaceLinux*)iface)->SetRemoved(); +} + +std::forward_list& CNetworkLinux::GetInterfaceList(void) { return m_interfaces; } @@ -422,67 +437,70 @@ void CNetworkLinux::GetMacAddress(const std::string& interfaceName, char rawMac[ #endif } -void CNetworkLinux::queryInterfaceList() +CNetworkInterfaceLinux *CNetworkLinux::Exists(const std::string &addr, const std::string &mask, const std::string &name) { - char macAddrRaw[6]; - m_interfaces.clear(); + for (auto &&iface: m_interfaces) + if (((CNetworkInterfaceLinux*)iface)->Exists(addr, mask, name)) + return (CNetworkInterfaceLinux*)iface; -#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) + return NULL; +} - // Query the list of interfaces. - struct ifaddrs *list; - if (getifaddrs(&list) < 0) - return; +bool CNetworkLinux::queryInterfaceList() +{ + // Query the list of interfaces. + struct ifaddrs *list; + if (getifaddrs(&list) < 0) + return false; + + CSingleLock lock(m_lock); + InterfacesClear(); + bool change = false; + + // find last IPv4 record, we will add new interfaces + // right after this one (to keep IPv4 in front). + auto pos = m_interfaces.before_begin(); + for (auto &&iface : m_interfaces) + { + if (iface && iface->isIPv6()) + break; + ++pos; + } struct ifaddrs *cur; for(cur = list; cur != NULL; cur = cur->ifa_next) { - if(cur->ifa_addr->sa_family != AF_INET) + if(cur->ifa_addr->sa_family != AF_INET + && cur->ifa_addr->sa_family != AF_INET6) continue; - GetMacAddress(cur->ifa_name, macAddrRaw); // Add the interface. - m_interfaces.push_back(new CNetworkInterfaceLinux(this, cur->ifa_name, macAddrRaw)); - } - - freeifaddrs(list); - -#else - FILE* fp = fopen("/proc/net/dev", "r"); - if (!fp) - { - // TBD: Error - return; - } - - char* line = NULL; - size_t linel = 0; - int n; - char* p; - int linenum = 0; - while (getdelim(&line, &linel, '\n', fp) > 0) - { - // skip first two lines - if (linenum++ < 2) - continue; + std::string addr = CNetwork::GetIpStr(cur->ifa_addr); + std::string mask = CNetwork::GetIpStr(cur->ifa_netmask); + std::string name = cur->ifa_name; + + CNetworkInterfaceLinux *iface = Exists(addr, mask, name); + if (iface) + { + iface->SetRemoved(false); + iface->m_interfaceFlags = cur->ifa_flags; + continue; + } - // search where the word begins - p = line; - while (isspace(*p)) - ++p; + char macAddrRaw[6] = {0}; + GetMacAddress(cur, macAddrRaw); - // read word until : - n = strcspn(p, ": \t"); - p[n] = 0; + CNetworkInterfaceLinux *i = new CNetworkInterfaceLinux(this, cur->ifa_addr->sa_family == AF_INET6, + cur->ifa_flags, addr, mask, name, macAddrRaw); - // save the result - std::string interfaceName = p; - GetMacAddress(interfaceName, macAddrRaw); - m_interfaces.push_back(new CNetworkInterfaceLinux(this, interfaceName, macAddrRaw)); + m_interfaces.insert_after(pos, i); + if (i->isIPv4()) + pos++; + change = true; } - free(line); - fclose(fp); -#endif + + freeifaddrs(list); + return change; } std::vector CNetworkLinux::GetNameServers(void) @@ -1181,8 +1199,11 @@ void CNetworkLinuxUpdateThread::Process(void) while (!m_bStop && recv(fds, &msg, sizeof(msg), 0) > 0); if (m_bStop) continue; + + if (!m_owner->queryInterfaceList()) + continue; + CLog::Log(LOGINFO, "Interfaces change %s", __FUNCTION__); - m_owner->queryInterfaceList(); CApplicationMessenger::GetInstance().PostMsg(TMSG_NETWORKMESSAGE, m_owner->NETWORK_CHANGED, 0); } } diff --git a/xbmc/network/linux/NetworkLinux.h b/xbmc/network/linux/NetworkLinux.h index eb6abb2..1579657 100644 --- a/xbmc/network/linux/NetworkLinux.h +++ b/xbmc/network/linux/NetworkLinux.h @@ -23,9 +23,9 @@ #include #include +#include #include #include "network/Network.h" -#include "threads/CriticalSection.h" #include "threads/Thread.h" class CNetworkLinux; @@ -33,8 +33,12 @@ class CNetworkLinuxUpdateThread; class CNetworkInterfaceLinux : public CNetworkInterface { + friend class CNetworkLinux; + public: - CNetworkInterfaceLinux(CNetworkLinux* network, std::string interfaceName, char interfaceMacAddrRaw[6]); + CNetworkInterfaceLinux(CNetworkLinux* network, bool sa_ipv6, + unsigned int ifa_flags, std::string ifa_addr, std::string ifa_netmask, + std::string interfaceName, char interfaceMacAddrRaw[6]); ~CNetworkInterfaceLinux(void); virtual std::string& GetName(void); @@ -58,9 +62,23 @@ public: // Returns the list of access points in the area virtual std::vector GetAccessPoints(void); - + + bool Exists(const std::string &addr, const std::string &mask, const std::string &name) + { + return (addr == m_interfaceAddr && mask == m_interfaceNetmask && name == m_interfaceName); + } + +protected: + void SetRemoved(bool removed = true) { m_removed = removed; } + bool IsRemoved(void) { return m_removed; } + private: void WriteSettings(FILE* fw, NetworkAssignment assignment, std::string& ipAddress, std::string& networkMask, std::string& defaultGateway, std::string& essId, std::string& key, EncMode& encryptionMode); + bool m_interfaceIpv6; + unsigned int m_interfaceFlags; /* Flags from SIOCGIFFLAGS */ + std::string m_interfaceAddr; /* Address of interface */ + std::string m_interfaceNetmask; /* Netmask of interface */ + bool m_removed; std::string m_interfaceName; std::string m_interfaceMacAdr; char m_interfaceMacAddrRaw[6]; @@ -77,7 +95,7 @@ public: virtual ~CNetworkLinux(void); // Return the list of interfaces - virtual std::vector& GetInterfaceList(void); + virtual std::forward_list& GetInterfaceList(void); virtual CNetworkInterface* GetFirstConnectedInterface(void); virtual bool SupportsIPv6() { return true; } @@ -90,14 +108,19 @@ public: virtual void SetNameServers(const std::vector& nameServers); private: + CNetworkInterfaceLinux *Exists(const std::string &addr, const std::string &mask, const std::string &name); + void InterfacesClear(void); + void DeleteRemoved(void); + int GetSocket() { return m_sock; } - void GetMacAddress(const std::string& interfaceName, char macAddrRaw[6]); - void queryInterfaceList(); - std::vector m_interfaces; + void GetMacAddress(const std::string& interfaceName, char rawMac[6]); + bool queryInterfaceList(); + std::forward_list m_interfaces; int m_sock; CNetworkLinuxUpdateThread *m_updThread; - CCriticalSection m_lock; + + static bool IsRemoved(CNetworkInterface *i) { if (((CNetworkInterfaceLinux*)i)->IsRemoved()) { delete i; return true; } return false; } }; class CNetworkLinuxUpdateThread : public CThread diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp index 5b7d884..16a846a 100644 --- a/xbmc/utils/URIUtils.cpp +++ b/xbmc/utils/URIUtils.cpp @@ -630,9 +630,9 @@ bool URIUtils::IsOnLAN(const std::string& strPath) static bool addr_match(uint32_t addr, const char* target, const char* submask) { - uint32_t addr2 = ntohl(inet_addr(target)); - uint32_t mask = ntohl(inet_addr(submask)); - return (addr & mask) == (addr2 & mask); + struct in_addr in = { htonl(addr) }; + std::string address = inet_ntoa(in); + return CNetwork::AddrMatch(address, target, submask); } bool URIUtils::IsHostOnLAN(const std::string& host, bool offLineCheck) @@ -645,32 +645,19 @@ bool URIUtils::IsHostOnLAN(const std::string& host, bool offLineCheck) if(host.find('.') == std::string::npos) return true; - uint32_t address = ntohl(inet_addr(host.c_str())); - if(address == INADDR_NONE) - { - std::string ip; - if(CDNSNameCache::Lookup(host, ip)) - address = ntohl(inet_addr(ip.c_str())); - } + std::string address; + if (!CDNSNameCache::Lookup(host, address)) + return false; - if(address != INADDR_NONE) - { - if (offLineCheck) // check if in private range, ref https://en.wikipedia.org/wiki/Private_network - { - if ( - addr_match(address, "192.168.0.0", "255.255.0.0") || - addr_match(address, "10.0.0.0", "255.0.0.0") || - addr_match(address, "172.16.0.0", "255.240.0.0") - ) - return true; - } - // check if we are on the local subnet - if (!g_application.getNetwork().GetFirstConnectedInterface()) - return false; + if (offLineCheck && /* check if in private range, ref https://en.wikipedia.org/wiki/Private_network */ + (CNetwork::AddrMatch(address, "192.168.0.0", "255.255.0.0") || + CNetwork::AddrMatch(address, "10.0.0.0", "255.0.0.0") || + CNetwork::AddrMatch(address, "172.16.0.0", "255.240.0.0")) + ) + return true; - if (g_application.getNetwork().HasInterfaceForIP(address)) - return true; - } + if (g_application.getNetwork().HasInterfaceForIP(address)) + return true; return false; } -- 2.7.1 From 4d684ca7d660c6533fb5d719e40543b1c5db21fa Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 12:21:29 +0200 Subject: [PATCH 016/250] ioctl() calls using SIOCGIFADDR do not support IPv6 on Linux. --- xbmc/network/linux/NetworkLinux.cpp | 44 ++++++++++--------------------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 71f5404..da36f59 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -128,31 +128,20 @@ bool CNetworkInterfaceLinux::IsWireless() bool CNetworkInterfaceLinux::IsEnabled() { - struct ifreq ifr; - strcpy(ifr.ifr_name, m_interfaceName.c_str()); - if (ioctl(m_network->GetSocket(), SIOCGIFFLAGS, &ifr) < 0) - return false; - - return ((ifr.ifr_flags & IFF_UP) == IFF_UP); + return (!IsRemoved() && m_interfaceFlags & IFF_UP); } bool CNetworkInterfaceLinux::IsConnected() { - struct ifreq ifr; - int zero = 0; - memset(&ifr,0,sizeof(struct ifreq)); - strcpy(ifr.ifr_name, m_interfaceName.c_str()); - if (ioctl(m_network->GetSocket(), SIOCGIFFLAGS, &ifr) < 0) - return false; - // ignore loopback - int iRunning = ( (ifr.ifr_flags & IFF_RUNNING) && (!(ifr.ifr_flags & IFF_LOOPBACK))); + if (IsRemoved() || m_interfaceFlags & IFF_LOOPBACK) + return false; - if (ioctl(m_network->GetSocket(), SIOCGIFADDR, &ifr) < 0) - return false; + unsigned int needFlags = IFF_RUNNING | IFF_LOWER_UP; + bool iRunning = (m_interfaceFlags & needFlags) == needFlags; // return only interfaces which has ip address - return iRunning && (0 != memcmp(ifr.ifr_addr.sa_data+sizeof(short), &zero, sizeof(int))); + return iRunning && !m_interfaceAddr.empty(); } std::string CNetworkInterfaceLinux::GetMacAddress() @@ -169,14 +158,7 @@ std::string CNetworkInterfaceLinux::GetCurrentIPAddress(void) { std::string result; - struct ifreq ifr; - strcpy(ifr.ifr_name, m_interfaceName.c_str()); - ifr.ifr_addr.sa_family = AF_INET; - if (ioctl(m_network->GetSocket(), SIOCGIFADDR, &ifr) >= 0) - { - result = inet_ntoa((*((struct sockaddr_in *)&ifr.ifr_addr)).sin_addr); - } - + result = m_interfaceAddr; return result; } @@ -184,14 +166,10 @@ std::string CNetworkInterfaceLinux::GetCurrentNetmask(void) { std::string result; - struct ifreq ifr; - strcpy(ifr.ifr_name, m_interfaceName.c_str()); - ifr.ifr_addr.sa_family = AF_INET; - if (ioctl(m_network->GetSocket(), SIOCGIFNETMASK, &ifr) >= 0) - { - result = inet_ntoa((*((struct sockaddr_in*)&ifr.ifr_addr)).sin_addr); - } - + if (isIPv4()) + result = m_interfaceNetmask; + else + result = StringUtils::Format("%d", CNetwork::PrefixLengthIPv6(m_interfaceNetmask)); return result; } -- 2.7.1 From 81b0aeb0bf72d7388458c94ab62be7c77d342ab1 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 12:26:45 +0200 Subject: [PATCH 017/250] Add IPv6 support to GetCurrentDefaultGateway(). Neighbor Discovery protocol nor receiving of Router Solicitation messages not implemented. --- xbmc/network/linux/NetworkLinux.cpp | 38 +++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index da36f59..914ee2d 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -258,7 +258,7 @@ std::string CNetworkInterfaceLinux::GetCurrentDefaultGateway(void) } free(buf); #else - FILE* fp = fopen("/proc/net/route", "r"); + FILE* fp = isIPv4() ? fopen("/proc/net/route", "r") : fopen("/proc/net/ipv6_route", "r"); if (!fp) { // TBD: Error @@ -269,35 +269,45 @@ std::string CNetworkInterfaceLinux::GetCurrentDefaultGateway(void) char iface[16]; char dst[128]; char gateway[128]; + unsigned int metric; + unsigned int metric_prev = -1; size_t linel = 0; int n; int linenum = 0; while (getdelim(&line, &linel, '\n', fp) > 0) { // skip first two lines - if (linenum++ < 1) + if (isIPv4() && linenum++ < 1) continue; // search where the word begins - n = sscanf(line, "%16s %128s %128s", - iface, dst, gateway); + if (isIPv4()) + n = sscanf(line, "%16s %128s %128s", + iface, dst, gateway); + else + n = sscanf(line, "%*32s %*2s %32s %*2s %32s %8x %*8s %*8s %*8s %8s", + dst, gateway, &metric, iface); if (n < 3) continue; if (strcmp(iface, m_interfaceName.c_str()) == 0 && - strcmp(dst, "00000000") == 0 && - strcmp(gateway, "00000000") != 0) + (strcmp(dst, "00000000") == 0 || strcmp(dst, "00000000000000000000000000000000") == 0) && + strcmp(gateway, "00000000") != 0 && strcmp(gateway, "00000000000000000000000000000000") != 0) { - unsigned char gatewayAddr[4]; - int len = CNetwork::ParseHex(gateway, gatewayAddr); - if (len == 4) + if (isIPv4()) { - struct in_addr in; - in.s_addr = (gatewayAddr[0] << 24) | (gatewayAddr[1] << 16) | - (gatewayAddr[2] << 8) | (gatewayAddr[3]); - result = inet_ntoa(in); - break; + struct in_addr in; + sscanf(gateway, "%8x", &in.s_addr); + result = inet_ntoa(in); + } + else if (metric < metric_prev) + { + metric_prev = metric; + std::string tstr = gateway; + for(int i = 7; i > 0; i--) + tstr.insert(tstr.begin() + i*4, ':'); + result = CNetwork::CanonizeIPv6(tstr); } } } -- 2.7.1 From 7907047569cf7e2279d9e6740a515987a662c577 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 12:36:03 +0200 Subject: [PATCH 018/250] Align with CNetwork in regards to IPv6, update to IPv4/v6 compatible calls. --- xbmc/network/linux/NetworkLinux.cpp | 69 ++++++++++--------------------------- xbmc/network/linux/NetworkLinux.h | 18 ++++++++-- 2 files changed, 35 insertions(+), 52 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 914ee2d..2c4213b 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -374,54 +374,25 @@ CNetworkInterface* CNetworkLinux::GetFirstConnectedInterface(void) return pNetIf; } - -void CNetworkLinux::GetMacAddress(const std::string& interfaceName, char rawMac[6]) +void CNetworkLinux::GetMacAddress(struct ifaddrs *tif, char *mac) { - memset(rawMac, 0, 6); -#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) - +#if !defined(TARGET_LINUX) #if !defined(IFT_ETHER) #define IFT_ETHER 0x6/* Ethernet CSMACD */ #endif - const struct sockaddr_dl* dlAddr = NULL; - const uint8_t * base = NULL; - // Query the list of interfaces. - struct ifaddrs *list; - struct ifaddrs *interface; - - if( getifaddrs(&list) < 0 ) + if (((const struct sockaddr_dl*) tif->ifa_addr)->sdl_type == IFT_ETHER) { - return; - } + const struct sockaddr_dl *dlAddr = (const struct sockaddr_dl *) tif->ifa_addr; + const uint8_t *base = (const uint8_t*) &dlAddr->sdl_data[dlAddr->sdl_nlen]; - for(interface = list; interface != NULL; interface = interface->ifa_next) - { - if(interfaceName == interface->ifa_name) - { - if ( (interface->ifa_addr->sa_family == AF_LINK) && (((const struct sockaddr_dl *) interface->ifa_addr)->sdl_type == IFT_ETHER) ) - { - dlAddr = (const struct sockaddr_dl *) interface->ifa_addr; - base = (const uint8_t *) &dlAddr->sdl_data[dlAddr->sdl_nlen]; - - if( dlAddr->sdl_alen > 5 ) - { - memcpy(rawMac, base, 6); - } - } - break; - } + if( dlAddr->sdl_alen > 5 ) + memcpy(mac, base, 6); } - - freeifaddrs(list); - #else - - struct ifreq ifr; - strcpy(ifr.ifr_name, interfaceName.c_str()); - if (ioctl(GetSocket(), SIOCGIFHWADDR, &ifr) >= 0) - { - memcpy(rawMac, ifr.ifr_hwaddr.sa_data, 6); - } + struct ifreq ifr; + strcpy(ifr.ifr_name, tif->ifa_name); + if (ioctl(GetSocket(), SIOCGIFHWADDR, &ifr) >= 0) + memcpy(mac, ifr.ifr_hwaddr.sa_data, 6); #endif } @@ -515,8 +486,6 @@ std::vector CNetworkLinux::GetNameServers(void) } pclose(pipe); } - if (result.empty()) - CLog::Log(LOGWARNING, "Unable to determine nameserver"); #elif defined(TARGET_ANDROID) char nameserver[PROP_VALUE_MAX]; @@ -526,19 +495,19 @@ std::vector CNetworkLinux::GetNameServers(void) result.push_back(nameserver); if (__system_property_get("net.dns3",nameserver)) result.push_back(nameserver); - - if (!result.size()) - CLog::Log(LOGWARNING, "Unable to determine nameserver"); #else - res_init(); + int res = res_init(); - for (int i = 0; i < _res.nscount; i ++) + for (int i = 0; i < _res.nscount && !res; i ++) { - std::string ns = inet_ntoa(((struct sockaddr_in *)&_res.nsaddr_list[i])->sin_addr); - result.push_back(ns); + std::string strIp = CNetwork::GetIpStr((struct sockaddr *)&_res.nsaddr_list[i]); + result.push_back(strIp); } #endif - return result; + if (result.empty()) + CLog::Log(LOGWARNING, "Unable to determine nameserver"); + + return result; } void CNetworkLinux::SetNameServers(const std::vector& nameServers) diff --git a/xbmc/network/linux/NetworkLinux.h b/xbmc/network/linux/NetworkLinux.h index 1579657..3d1539b 100644 --- a/xbmc/network/linux/NetworkLinux.h +++ b/xbmc/network/linux/NetworkLinux.h @@ -60,6 +60,9 @@ public: virtual void GetSettings(NetworkAssignment& assignment, std::string& ipAddress, std::string& networkMask, std::string& defaultGateway, std::string& essId, std::string& key, EncMode& encryptionMode); virtual void SetSettings(NetworkAssignment& assignment, std::string& ipAddress, std::string& networkMask, std::string& defaultGateway, std::string& essId, std::string& key, EncMode& encryptionMode); + bool isIPv6() { return m_interfaceIpv6; } + bool isIPv4() { return !m_interfaceIpv6; } + // Returns the list of access points in the area virtual std::vector GetAccessPoints(void); @@ -96,14 +99,25 @@ public: // Return the list of interfaces virtual std::forward_list& GetInterfaceList(void); + // list of available interfaces is always sorted: by AF_FAMILY, dependence of their type + // on other types and alphabetically at last. + // AF_PACKET comes first, then AF_INET, AF_INET6. physical interfaces (eg network cards) + // come first. bridges later before virtual itnerfaces, then tunnels ... + // this assures that ppp0 won't be picked up (presented as GetFirstConnectedInterface()) + // at the expense of eth0 for instance / thus providing nonsense info to services expecting + // interface with MAC address. virtual CNetworkInterface* GetFirstConnectedInterface(void); - + virtual bool SupportsIPv6() { return true; } // Ping remote host virtual bool PingHostImpl(const std::string &target, unsigned int timeout_ms = 2000); // Get/set the nameserver(s) + // Current code is safe for any stack configuration, but APi + // used provides IPv4 nameservers only (those specified in system + // via IPv4 address). empty otherwise. + // TODO: find a method to get list of all defined nameservers virtual std::vector GetNameServers(void); virtual void SetNameServers(const std::vector& nameServers); @@ -113,7 +127,7 @@ private: void DeleteRemoved(void); int GetSocket() { return m_sock; } - void GetMacAddress(const std::string& interfaceName, char rawMac[6]); + void GetMacAddress(struct ifaddrs *tif, char *mac); bool queryInterfaceList(); std::forward_list m_interfaces; int m_sock; -- 2.7.1 From c9777e5f74703dadf1521626ccb1aeddd0d2ff9c Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 13:43:59 +0200 Subject: [PATCH 019/250] Canonize IPv6 address as part of parsing and store it in this form. (update tests in test/TestURL.cpp) --- xbmc/URL.cpp | 2 ++ xbmc/test/TestURL.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/xbmc/URL.cpp b/xbmc/URL.cpp index f353a34..6081892 100644 --- a/xbmc/URL.cpp +++ b/xbmc/URL.cpp @@ -292,6 +292,8 @@ void CURL::Parse(const std::string& strURL1) if (m_strHostName.empty()) m_strHostName = strHostNameAndPort; + m_strHostName = URIUtils::CanonizeIPv6(m_strHostName); + if (iSlash != std::string::npos) { iPos = iSlash + 1; diff --git a/xbmc/test/TestURL.cpp b/xbmc/test/TestURL.cpp index cd2fda4..bf5c8c9 100644 --- a/xbmc/test/TestURL.cpp +++ b/xbmc/test/TestURL.cpp @@ -68,11 +68,11 @@ const TestURLGetWithoutUserDetailsData values[] = { { std::string("smb://god@[fd00::1]:8080/example"), std::string("smb://USERNAME@[fd00::1]:8080/example"), true }, { std::string("smb://god:universe@fd00::1/example"), std::string("smb://USERNAME:PASSWORD@fd00::1/example"), true }, { std::string("http://god:universe@[fd00::1]:8448/example|auth=digest"), std::string("http://USERNAME:PASSWORD@[fd00::1]:8448/example|auth=digest"), true }, - { std::string("smb://00ff:1:0000:abde::/example"), std::string("smb://00ff:1:0000:abde::/example"), true }, - { std::string("smb://god:universe@[00ff:1:0000:abde::]:8080/example"), std::string("smb://[00ff:1:0000:abde::]:8080/example"), false }, - { std::string("smb://god@[00ff:1:0000:abde::]:8080/example"), std::string("smb://USERNAME@[00ff:1:0000:abde::]:8080/example"), true }, - { std::string("smb://god:universe@00ff:1:0000:abde::/example"), std::string("smb://USERNAME:PASSWORD@00ff:1:0000:abde::/example"), true }, - { std::string("http://god:universe@[00ff:1:0000:abde::]:8448/example|auth=digest"), std::string("http://USERNAME:PASSWORD@[00ff:1:0000:abde::]:8448/example|auth=digest"), true } + { std::string("smb://00ff:1:0000:abde::/example"), std::string("smb://ff:1:0:abde::/example"), true }, + { std::string("smb://god:universe@[00ff:1:0000:abde::]:8080/example"), std::string("smb://[ff:1:0:abde::]:8080/example"), false }, + { std::string("smb://god@[00ff:1:0000:abde::]:8080/example"), std::string("smb://USERNAME@[ff:1:0:abde::]:8080/example"), true }, + { std::string("smb://god:universe@00ff:1:0000:abde::/example"), std::string("smb://USERNAME:PASSWORD@ff:1:0:abde::/example"), true }, + { std::string("http://god:universe@[00ff:1:0000:abde::]:8448/example|auth=digest"), std::string("http://USERNAME:PASSWORD@[ff:1:0:abde::]:8448/example|auth=digest"), true } }; INSTANTIATE_TEST_CASE_P(URL, TestURLGetWithoutUserDetails, ValuesIn(values)); -- 2.7.1 From d20969fb3dd5fe5a7c592f2c4b2c0e98e00fe499 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 11 Sep 2015 22:29:18 +0200 Subject: [PATCH 020/250] Updated function descriptions to doxygen format --- xbmc/network/Network.h | 134 +++++++++++++++++++++++++++----------- xbmc/network/linux/NetworkLinux.h | 11 +--- 2 files changed, 97 insertions(+), 48 deletions(-) diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index a1da8a6..95ccffa 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -118,28 +118,59 @@ public: CNetwork(); virtual ~CNetwork(); - // Return our hostname + /*! + \brief Returns local hostname + */ virtual bool GetHostName(std::string& hostname); - // Return the list of interfaces + /*! + \brief Return the list of interfaces + */ virtual std::forward_list& GetInterfaceList(void) = 0; + /*! + \brief Returns interface with specific name + - in the current implementation, interface as the basic configutation item + represents specific IP configuration + - this means InterfaceName is not unique key. IP address is + + \return With respect above comment, it returns first valid configuration on interface + holding searched interface name. + */ CNetworkInterface* GetInterfaceByName(const std::string& name); - // Return the first interface which is active + /*! + \brief Return the first interface which is active + - list of available interfaces is always sorted: by AF_FAMILY, dependence of their type + on other types and alphabetically at last. AF_PACKET comes first, then AF_INET, AF_INET6. + physical interfaces (eg network cards) come first. Bridges later before virtual + itnerfaces, then tunnels... + - This assures that ppp0 won't be picked up (presented as + GetFirstConnectedInterface()) at the expense of eth0 for instance / thus providing + non-sense info to services expecting interface with MAC address. + */ virtual CNetworkInterface* GetFirstConnectedInterface(void); - // Return address family of GetFirstConnectedInterface() interface. With respect to above - // comment this means: - // - in case of returned AF_INET6 - host is configured with IPv6 stack only (we don't need - // iterate over interfaces list further, or trying socket() results to confirm this) - // - AF_INET - host is configured with IPv4 stack. IPv6 availability unknown, we would need - // to loop over the list. + /*! + \brief Address family of GetFirstConnectedInterface() interface + \sa GetFirstConnectedInterface() + \return with respect to comment in GetFirstConnectedInterface() + - in case of returned AF_INET6 - host is configured with IPv6 stack only (we don't need + iterate over interfaces list further, or trying socket() results to confirm this) + - AF_INET - host is configured with IPv4 stack. IPv6 availability unknown, we would need + to loop over the list. + */ int GetFirstConnectedFamily() { return (GetFirstConnectedInterface() && GetFirstConnectedInterface()->isIPv6() ? AF_INET6 : AF_INET); } - // Return true if there is a interface for the same network as address + /*! + \brief Return true if there is a interface for the same network as address + */ bool HasInterfaceForIP(const std::string &address); - // Backward compatibility call. It wraps IPv6 compatible function above + + /*! + \brief Compat wrapper to + \sa HasInterfaceForIP(const std::string &address) + */ bool HasInterfaceForIP(unsigned long address); // Return true if there's at least one defined network interface @@ -148,12 +179,15 @@ public: // Return true if there's at least one interface which is connected bool IsConnected(void); - // Return true if the magic packet was send - // TODO: current implementation uses ARP for MAC resolution. - // as IPv6 has no ARP, it will provide expected result - // only if target host is accessible via IPv4. - // (anyhow it's use is safe regardless actual. - // configuration, returns false for IPv6 only stack) + /*! + \return Return true if the magic packet was send + + TODO: current implementation uses ARP for MAC resolution. + as IPv6 has no ARP, it will provide expected result + only if target host is accessible via IPv4. + (anyhow it's use is safe regardless actual. + configuration, returns false for IPv6 only stack) + */ bool WakeOnLan(const char *mac); /*! @@ -186,14 +220,16 @@ public: /*! \brief Tests if parameter specifies valid IPv6 address (as specified by RFCs) - \param IP as std::string, struct sockaddr* (non mandatory), - port specification (non mandatory) + \param ipaddress to convert/test + \param *sockaddr non mandatory destination for conversion + \param port non mandatory port specification to connect to \return Function is dual purpose. With just one parameter (IP), it return true if that IP represents IPv6 address. If case of second / third supplied argument, it directly converts parameters into binary struct pointed by 2nd param. (structure needs to be pre-allocated) + \sa ConvIP For direct conversion into (sockaddr*) see ConvIP() variants. (it is universal wrapper to ConvIPv6/v4()) */ @@ -201,14 +237,16 @@ public: /*! \brief Tests if parameter specifies valid IPv4 address (as specified by RFCs) - \param IP as std::string, struct sockaddr* (non mandatory), - port specification (non mandatory) + \param ipaddress stored as std::string + \param sockaddr* non mandatory + \param port non mandatory \return Function is dual purpose. With just one parameter (IP), it return true if that IP represents IPv4 address. If case of second / third supplied argument, it directly converts parameters into binary struct pointed by 2nd param. (structure needs to be pre-allocated) + \sa ConvIP For direct conversion into (sockaddr*) see ConvIP() variants. (it is universal wrapper to ConvIPv6/v4()) */ @@ -247,10 +285,11 @@ public: static std::string GetIpStr(const struct sockaddr *sa); /*! - \brief Converts IP(v4) from ulong to std::string - \param (unsigned long) IP address - \return Function converts from host byte order to network - byte order first. Result is returned as std::string. + \brief Converts IPv4 address stored in unsigned long to std::string + Function converts from host byte order to network + byte order first + \param IPaddress unsigned long + \return Result is returned as std::string */ static std::string GetIpStr(unsigned long address); @@ -278,23 +317,42 @@ public: // doesn't comply to standard) static int PrefixLengthIPv6(const std::string &address); - // fully IPv4/IPv6 compatible (IPv6 part is limited to addr/mask match only (IPv4 way)) - // TODO: beside addr/match matching IPv6 introduced NetworkDiscoveryProtocol(NDP) - // currently not implemented. + /*! + \brief fully IPv4/IPv6 compatible + - IPv6 part is limited to addr/mask match only (IPv4 way) + + \param ipaddr1 to match + \param ipaddr2 to match agains + \param mask2 to match agains + + \return TRUE if: ipaddr1 & mask2 == ipaddr2 & mask2 , FALSE otherwise + + TODO: beside addr/match matching IPv6 introduced NetworkDiscoveryProtocol(NDP) + currently not implemented. + */ static bool AddrMatch(const std::string &addr, const std::string &match_ip, const std::string &match_mask); - // Per platform implementation. CNetwork class has both IPv6/IPv4 support, - // but doesn't require each derived class to support IPv6 as well. - // By default we assume IPv6 support not existend (or IPv6 stack unconfigured). - // As the class functions do check that internally, it makes the calls safe - // with no prior checking for actual stack availability. - // In such situations, all calls with IPv6-like parameters will return - // false, -1, or std::string being empty. - // static functions providing only type<>type conversions or formal - // valididy check are unaffected. + /*! + \brief Per platform implementation. + - CNetwork class has both IPv6/IPv4 support, but doesn't require each derived + class to support IPv6 as well + - By default we assume IPv6 support not existend (or IPv6 stack unconfigured) + - CNetwork class functions check IPv6 support automatically based on this call + and avoid IPv6 depending code automatically. + This makes the calls safe for the caller without prior checks or deep knowledge + of CNetwork internals + + - for calls dealing with IPv6 stack - and no IPv6 available - calls return safely + returning string.empty() / FALSE / -1 or NULL + + \return Static functions providing only type<>type conversions or formal valididy checking + are independent on actual IPv6 stack availability + */ virtual bool SupportsIPv6(void) { return false; } - // Return true if given name or ip address corresponds to localhost + /*! + \brief Return true if given name or ip address corresponds to localhost + */ bool IsLocalHost(const std::string& hostname); protected: diff --git a/xbmc/network/linux/NetworkLinux.h b/xbmc/network/linux/NetworkLinux.h index 3d1539b..528247f 100644 --- a/xbmc/network/linux/NetworkLinux.h +++ b/xbmc/network/linux/NetworkLinux.h @@ -97,20 +97,11 @@ public: CNetworkLinux(void); virtual ~CNetworkLinux(void); - // Return the list of interfaces virtual std::forward_list& GetInterfaceList(void); - // list of available interfaces is always sorted: by AF_FAMILY, dependence of their type - // on other types and alphabetically at last. - // AF_PACKET comes first, then AF_INET, AF_INET6. physical interfaces (eg network cards) - // come first. bridges later before virtual itnerfaces, then tunnels ... - // this assures that ppp0 won't be picked up (presented as GetFirstConnectedInterface()) - // at the expense of eth0 for instance / thus providing nonsense info to services expecting - // interface with MAC address. - virtual CNetworkInterface* GetFirstConnectedInterface(void); + virtual CNetworkInterface* GetFirstConnectedInterface(void); virtual bool SupportsIPv6() { return true; } - // Ping remote host virtual bool PingHostImpl(const std::string &target, unsigned int timeout_ms = 2000); // Get/set the nameserver(s) -- 2.7.1 From 1ad32bb0a523968154cce88a5b2f945951dd1a56 Mon Sep 17 00:00:00 2001 From: mkreisl Date: Mon, 2 Nov 2015 22:36:07 +0100 Subject: [PATCH 021/250] handle NULL derererencing --- xbmc/network/linux/NetworkLinux.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 2c4213b..dab8f0a 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -429,8 +429,9 @@ bool CNetworkLinux::queryInterfaceList() struct ifaddrs *cur; for(cur = list; cur != NULL; cur = cur->ifa_next) { - if(cur->ifa_addr->sa_family != AF_INET - && cur->ifa_addr->sa_family != AF_INET6) + if(!cur->ifa_addr || + (cur->ifa_addr->sa_family != AF_INET && + cur->ifa_addr->sa_family != AF_INET6)) continue; // Add the interface. @@ -438,6 +439,9 @@ bool CNetworkLinux::queryInterfaceList() std::string mask = CNetwork::GetIpStr(cur->ifa_netmask); std::string name = cur->ifa_name; + if(addr.empty() || mask.empty()) + continue; + CNetworkInterfaceLinux *iface = Exists(addr, mask, name); if (iface) { -- 2.7.1 From 9fb0b05c7e11a8b66e893a77817f97a68b11a5b5 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 15 Nov 2015 00:58:57 +0100 Subject: [PATCH 022/250] - align the behaviour with W32 implementation and load only interfaces with flag IFF_UP (interface has (some) configuration and is UP - bind() will not fail) (this means non empty interfaces list is sufficient prerequisite to start network services without errors) --- xbmc/network/linux/NetworkLinux.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index dab8f0a..6a94294 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -128,7 +128,7 @@ bool CNetworkInterfaceLinux::IsWireless() bool CNetworkInterfaceLinux::IsEnabled() { - return (!IsRemoved() && m_interfaceFlags & IFF_UP); + return true; } bool CNetworkInterfaceLinux::IsConnected() @@ -434,6 +434,9 @@ bool CNetworkLinux::queryInterfaceList() cur->ifa_addr->sa_family != AF_INET6)) continue; + if(!(cur->ifa_flags & IFF_UP)) + continue; + // Add the interface. std::string addr = CNetwork::GetIpStr(cur->ifa_addr); std::string mask = CNetwork::GetIpStr(cur->ifa_netmask); -- 2.7.1 From 5062039f2538708e3839dfebf81e3bd475364d6c Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 14 Nov 2015 22:34:17 +0100 Subject: [PATCH 023/250] - remove IsAvailable() completely - fix calls to it from other layers either by calling IsConnected() instead, or remove the call completely if had no practical meaning - don't call services start() if we have no interfaces configured at all (at least loopback is needed) --- xbmc/Util.cpp | 2 +- xbmc/filesystem/DirectoryFactory.cpp | 2 +- xbmc/filesystem/FileFactory.cpp | 2 +- xbmc/music/MusicDatabase.cpp | 2 +- xbmc/network/Network.cpp | 21 ++++++--------------- xbmc/network/Network.h | 3 --- xbmc/network/NetworkServices.cpp | 7 ++----- xbmc/utils/RssReader.cpp | 2 +- xbmc/utils/Weather.cpp | 2 +- xbmc/windows/GUIMediaWindow.cpp | 4 ++-- 10 files changed, 16 insertions(+), 31 deletions(-) diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp index c96b774..13a5f18 100644 --- a/xbmc/Util.cpp +++ b/xbmc/Util.cpp @@ -1895,7 +1895,7 @@ void CUtil::ScanForExternalSubtitles(const std::string& strMovie, std::vector& ifaces = GetInterfaceList(); - - while (!m_bStop && wait && ifaces.empty()) - { - m_signalNetworkChange.WaitMSec(5000); - ifaces = GetInterfaceList(); - m_signalNetworkChange.Reset(); - } - - return (!ifaces.empty()); -} - bool CNetwork::IsConnected() { return GetFirstConnectedInterface() != NULL; @@ -411,6 +396,12 @@ void CNetwork::NetworkMessage(EMESSAGE message, int param) switch( message ) { case SERVICES_UP: + if (GetInterfaceList().empty()) + { + CLog::Log(LOGDEBUG, "%s - There is no configured network interface. Not starting network services",__FUNCTION__); + break; + } + CLog::Log(LOGDEBUG, "%s - Starting network services",__FUNCTION__); CNetworkServices::GetInstance().Start(); break; diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index 95ccffa..5672888 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -173,9 +173,6 @@ public: */ bool HasInterfaceForIP(unsigned long address); - // Return true if there's at least one defined network interface - bool IsAvailable(void); - // Return true if there's at least one interface which is connected bool IsConnected(void); diff --git a/xbmc/network/NetworkServices.cpp b/xbmc/network/NetworkServices.cpp index 3dc2c7f..8d311f4 100644 --- a/xbmc/network/NetworkServices.cpp +++ b/xbmc/network/NetworkServices.cpp @@ -503,9 +503,6 @@ void CNetworkServices::Stop(bool bWait) bool CNetworkServices::StartWebserver() { #ifdef HAS_WEB_SERVER - if (!g_application.getNetwork().IsAvailable()) - return false; - if (!CSettings::GetInstance().GetBool(CSettings::SETTING_SERVICES_WEBSERVER)) return false; @@ -578,7 +575,7 @@ bool CNetworkServices::StartAirPlayServer() return true; #ifdef HAS_AIRPLAY - if (!g_application.getNetwork().IsAvailable() || !CSettings::GetInstance().GetBool(CSettings::SETTING_SERVICES_AIRPLAY)) + if (!g_application.getNetwork().IsConnected() || !CSettings::GetInstance().GetBool(CSettings::SETTING_SERVICES_AIRPLAY)) return false; if (IsAirPlayServerRunning()) @@ -640,7 +637,7 @@ bool CNetworkServices::StopAirPlayServer(bool bWait) bool CNetworkServices::StartAirTunesServer() { #ifdef HAS_AIRTUNES - if (!g_application.getNetwork().IsAvailable() || !CSettings::GetInstance().GetBool(CSettings::SETTING_SERVICES_AIRPLAY)) + if (!g_application.getNetwork().IsConnected() || !CSettings::GetInstance().GetBool(CSettings::SETTING_SERVICES_AIRPLAY)) return false; if (IsAirTunesServerRunning()) diff --git a/xbmc/utils/RssReader.cpp b/xbmc/utils/RssReader.cpp index e1dddbe..ed686ea 100644 --- a/xbmc/utils/RssReader.cpp +++ b/xbmc/utils/RssReader.cpp @@ -143,7 +143,7 @@ void CRssReader::Process() // we wait for the network to come up if ((url.IsProtocol("http") || url.IsProtocol("https")) && - !g_application.getNetwork().IsAvailable()) + !g_application.getNetwork().IsConnected()) { CLog::Log(LOGWARNING, "RSS: No network connection"); strXML = ""+g_localizeStrings.Get(15301)+""; diff --git a/xbmc/utils/Weather.cpp b/xbmc/utils/Weather.cpp index 4378c37..6a90b62 100644 --- a/xbmc/utils/Weather.cpp +++ b/xbmc/utils/Weather.cpp @@ -75,7 +75,7 @@ CWeatherJob::CWeatherJob(int location) bool CWeatherJob::DoWork() { // wait for the network - if (!g_application.getNetwork().IsAvailable()) + if (!g_application.getNetwork().IsConnected()) return false; AddonPtr addon; diff --git a/xbmc/windows/GUIMediaWindow.cpp b/xbmc/windows/GUIMediaWindow.cpp index 08aa7a8..e3f05cd 100644 --- a/xbmc/windows/GUIMediaWindow.cpp +++ b/xbmc/windows/GUIMediaWindow.cpp @@ -1630,7 +1630,7 @@ const CFileItemList& CGUIMediaWindow::CurrentDirectory() const bool CGUIMediaWindow::WaitForNetwork() const { - if (g_application.getNetwork().IsAvailable()) + if (g_application.getNetwork().IsConnected()) return true; CGUIDialogProgress *progress = (CGUIDialogProgress *)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS); @@ -1642,7 +1642,7 @@ bool CGUIMediaWindow::WaitForNetwork() const progress->SetLine(1, CVariant{url.GetWithoutUserDetails()}); progress->ShowProgressBar(false); progress->Open(); - while (!g_application.getNetwork().IsAvailable()) + while (!g_application.getNetwork().IsConnected()) { progress->Progress(); if (progress->IsCanceled()) -- 2.7.1 From fa6f0cf93437d3e7161b5cd5c2b042877cff0092 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 15 Nov 2015 01:45:55 +0100 Subject: [PATCH 024/250] - move the core code into CNetwork, keep only NetLink specific handler in LinuxNetwork code. Prepare for easy w32 watcher integration. --- xbmc/network/Network.cpp | 3 ++- xbmc/network/Network.h | 25 +++++++++++++++++++++++++ xbmc/network/linux/NetworkLinux.cpp | 26 ++++++++++---------------- xbmc/network/linux/NetworkLinux.h | 17 ++--------------- xbmc/network/windows/NetworkWin32.cpp | 1 + xbmc/network/windows/NetworkWin32.h | 1 + 6 files changed, 41 insertions(+), 32 deletions(-) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index 8e123b1..79a9037 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -144,8 +144,10 @@ CNetwork::CNetwork() : CNetwork::~CNetwork() { m_bStop = true; + m_updThread->StopThread(false); m_signalNetworkChange.Set(); CApplicationMessenger::GetInstance().PostMsg(TMSG_NETWORKMESSAGE, SERVICES_DOWN, 0); + m_updThread->StopThread(true); } std::string CNetwork::GetIpStr(const struct sockaddr *sa) @@ -738,4 +740,3 @@ int CreateTCPServerSocket(const int port, const bool bindLocal, const int backlo return sock; } - diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index 5672888..470c78f 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -26,6 +26,8 @@ #include "system.h" #include "threads/Event.h" #include "threads/CriticalSection.h" +#include "threads/Thread.h" +#include "Application.h" #include "settings/lib/ISettingCallback.h" #include @@ -107,6 +109,19 @@ public: class CNetwork { + class CNetworkUpdater : public CThread + { + public: + CNetworkUpdater(void (*watcher)()) : CThread("NetConfUpdater"), m_watcher(watcher) {} + virtual ~CNetworkUpdater(void) {}; + + bool Stopping() { return m_bStop; } + protected: + void Process() { m_watcher(); } + private: + void (*m_watcher)(); + }; + public: enum EMESSAGE { @@ -352,6 +367,15 @@ public: */ bool IsLocalHost(const std::string& hostname); + /*! + \brief Registers function as platform. network settings change watcher. Changes on net ifaces + should be reported by sending message TMSG_NETWORKMESSAGE (CNetwork::NETWORK_CHANGED). + */ + void RegisterWatcher(void (*watcher)()) { m_updThread = new CNetworkUpdater(watcher); m_updThread->Create(false); } + CNetworkUpdater *m_updThread; + + virtual bool ForceRereadInterfaces() = 0; + protected: CCriticalSection m_lock; @@ -360,6 +384,7 @@ private: bool m_bStop; }; + #ifdef HAS_LINUX_NETWORK #include "linux/NetworkLinux.h" #else diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 6a94294..cf21a77 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -322,8 +322,9 @@ CNetworkLinux::CNetworkLinux(void) { m_sock = socket(AF_INET, SOCK_DGRAM, 0); queryInterfaceList(); - m_updThread = new CNetworkLinuxUpdateThread(this); - m_updThread->Create(false); + NetworkMessage(NETWORK_CHANGED, 0); + RegisterWatcher(WatcherProcess); + CApplicationMessenger::GetInstance().PostMsg(TMSG_NETWORKMESSAGE, CNetwork::SERVICES_UP, 0); } CNetworkLinux::~CNetworkLinux(void) @@ -331,11 +332,9 @@ CNetworkLinux::~CNetworkLinux(void) if (m_sock != -1) close(CNetworkLinux::m_sock); - m_updThread->StopThread(false); CSingleLock lock(m_lock); InterfacesClear(); DeleteRemoved(); - m_updThread->StopThread(true); } void CNetworkLinux::DeleteRemoved(void) @@ -1125,18 +1124,13 @@ void CNetworkInterfaceLinux::WriteSettings(FILE* fw, NetworkAssignment assignmen fprintf(fw, "auto %s\n\n", GetName().c_str()); } -CNetworkLinuxUpdateThread::CNetworkLinuxUpdateThread(CNetworkLinux *owner) - : CThread("NetConfUpdater") - , m_owner(owner) -{ -} - -void CNetworkLinuxUpdateThread::Process(void) +void WatcherProcess() { struct sockaddr_nl addr; int fds = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); struct pollfd m_fds = { fds, POLLIN, 0 }; char msg[4096]; +#define stopping ( g_application.getNetwork().m_updThread->Stopping() ) memset (&addr, 0, sizeof(struct sockaddr_nl)); addr.nl_family = AF_NETLINK; @@ -1157,17 +1151,17 @@ void CNetworkLinuxUpdateThread::Process(void) fcntl(fds, F_SETFL, O_NONBLOCK); - while(!m_bStop) + while(!stopping) if (poll(&m_fds, 1, 1000) > 0) { - while (!m_bStop && recv(fds, &msg, sizeof(msg), 0) > 0); - if (m_bStop) + while (!stopping && recv(fds, &msg, sizeof(msg), 0) > 0); + if (stopping) continue; - if (!m_owner->queryInterfaceList()) + if (!g_application.getNetwork().ForceRereadInterfaces()) continue; CLog::Log(LOGINFO, "Interfaces change %s", __FUNCTION__); - CApplicationMessenger::GetInstance().PostMsg(TMSG_NETWORKMESSAGE, m_owner->NETWORK_CHANGED, 0); + CApplicationMessenger::GetInstance().PostMsg(TMSG_NETWORKMESSAGE, CNetwork::NETWORK_CHANGED, 0); } } diff --git a/xbmc/network/linux/NetworkLinux.h b/xbmc/network/linux/NetworkLinux.h index 528247f..a80cf88 100644 --- a/xbmc/network/linux/NetworkLinux.h +++ b/xbmc/network/linux/NetworkLinux.h @@ -26,7 +26,6 @@ #include #include #include "network/Network.h" -#include "threads/Thread.h" class CNetworkLinux; class CNetworkLinuxUpdateThread; @@ -90,7 +89,6 @@ private: class CNetworkLinux : public CNetwork { - friend class CNetworkLinuxUpdateThread; friend class CNetworkInterfaceLinux; public: @@ -112,6 +110,7 @@ public: virtual std::vector GetNameServers(void); virtual void SetNameServers(const std::vector& nameServers); + bool ForceRereadInterfaces() { return queryInterfaceList(); } private: CNetworkInterfaceLinux *Exists(const std::string &addr, const std::string &mask, const std::string &name); void InterfacesClear(void); @@ -123,21 +122,9 @@ private: std::forward_list m_interfaces; int m_sock; - CNetworkLinuxUpdateThread *m_updThread; - static bool IsRemoved(CNetworkInterface *i) { if (((CNetworkInterfaceLinux*)i)->IsRemoved()) { delete i; return true; } return false; } }; -class CNetworkLinuxUpdateThread : public CThread -{ -public: - CNetworkLinuxUpdateThread(CNetworkLinux *owner); - virtual ~CNetworkLinuxUpdateThread(void) {}; - -protected: - void Process(void); - CNetworkLinux *m_owner; -}; - #endif +void WatcherProcess(); diff --git a/xbmc/network/windows/NetworkWin32.cpp b/xbmc/network/windows/NetworkWin32.cpp index 95198a8..b731eb9 100644 --- a/xbmc/network/windows/NetworkWin32.cpp +++ b/xbmc/network/windows/NetworkWin32.cpp @@ -150,6 +150,7 @@ std::string CNetworkInterfaceWin32::GetCurrentDefaultGateway(void) CNetworkWin32::CNetworkWin32(void) { queryInterfaceList(); + CApplicationMessenger::GetInstance().PostMsg(TMSG_NETWORKMESSAGE, CNetwork::SERVICES_UP, 0); } CNetworkWin32::~CNetworkWin32(void) diff --git a/xbmc/network/windows/NetworkWin32.h b/xbmc/network/windows/NetworkWin32.h index d52d13d..8477156 100644 --- a/xbmc/network/windows/NetworkWin32.h +++ b/xbmc/network/windows/NetworkWin32.h @@ -82,6 +82,7 @@ public: friend class CNetworkInterfaceWin32; + bool ForceRereadInterfaces() { queryInterfaceList(); return true; } private: int GetSocket() { return m_sock; } void queryInterfaceList(); -- 2.7.1 From 45076bbaea35492409459305dac2ef9edb686984 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 15 Nov 2015 13:33:05 +0100 Subject: [PATCH 025/250] Removed interface - count as change too. --- xbmc/network/linux/NetworkLinux.cpp | 10 +++++++--- xbmc/network/linux/NetworkLinux.h | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index cf21a77..16d1302 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -19,6 +19,7 @@ */ #include +#include #include "xbmc/messaging/ApplicationMessenger.h" #include @@ -406,14 +407,17 @@ CNetworkInterfaceLinux *CNetworkLinux::Exists(const std::string &addr, const std bool CNetworkLinux::queryInterfaceList() { + bool change = false; + + CSingleLock lock(m_lock); + // Query the list of interfaces. struct ifaddrs *list; if (getifaddrs(&list) < 0) return false; - CSingleLock lock(m_lock); + DeleteRemoved(); InterfacesClear(); - bool change = false; // find last IPv4 record, we will add new interfaces // right after this one (to keep IPv4 in front). @@ -465,7 +469,7 @@ bool CNetworkLinux::queryInterfaceList() } freeifaddrs(list); - return change; + return change | std::count_if(m_interfaces.begin(), m_interfaces.end(), IsRemoved); } std::vector CNetworkLinux::GetNameServers(void) diff --git a/xbmc/network/linux/NetworkLinux.h b/xbmc/network/linux/NetworkLinux.h index a80cf88..1b71e6f 100644 --- a/xbmc/network/linux/NetworkLinux.h +++ b/xbmc/network/linux/NetworkLinux.h @@ -122,7 +122,7 @@ private: std::forward_list m_interfaces; int m_sock; - static bool IsRemoved(CNetworkInterface *i) { if (((CNetworkInterfaceLinux*)i)->IsRemoved()) { delete i; return true; } return false; } + static bool IsRemoved(const CNetworkInterface *i) { return ((CNetworkInterfaceLinux*)i)->IsRemoved(); } }; #endif -- 2.7.1 From 7aa67cf2aefd8729524afd9d26754ee537b491a2 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 8 Jun 2015 11:10:00 +0200 Subject: [PATCH 026/250] XBMC activation problem fix Upstream-commit: e70bc3009b4b83ccd4accd8f75b0fcbeb74f7a5a [CEC] having addresses set in order TV,AVR will never return AVR on expression (x) ? TV : address.primary [CEC] if AVR is set for poweron on start, power it on correponding actions from Announcer() too. --- xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 52 +++++++++++++++-------- xbmc/peripherals/devices/PeripheralCecAdapter.h | 5 ++- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index e0d8dae..9a82fa1 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -169,6 +169,9 @@ void CPeripheralCecAdapter::Announce(AnnouncementFlag flag, const char *sender, m_configuration.bActivateSource == 1) { ActivateSource(); + if (!m_configuration.wakeDevices.IsEmpty() && m_configuration.wakeDevices.primary == CECDEVICE_AUDIOSYSTEM && + GetAudioSystemConnected()) + m_cecAdapter->PowerOnDevices(CECDEVICE_AUDIOSYSTEM); } } else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && m_bIsReady) @@ -333,8 +336,6 @@ bool CPeripheralCecAdapter::OpenConnection(void) if (!bConnectionFailedDisplayed) CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(36000), g_localizeStrings.Get(36012)); bConnectionFailedDisplayed = true; - - Sleep(10000); } } @@ -448,6 +449,12 @@ void CPeripheralCecAdapter::SetAudioSystemConnected(bool bSetTo) m_bHasConnectedAudioSystem = bSetTo; } +bool CPeripheralCecAdapter::GetAudioSystemConnected() +{ + CSingleLock lock(m_critSection); + return m_bHasConnectedAudioSystem; +} + void CPeripheralCecAdapter::ProcessVolumeChange(void) { bool bSendRelease(false); @@ -1417,8 +1424,8 @@ void CPeripheralCecAdapter::ReadLogicalAddresses(int iLocalisedId, cec_logical_a addresses.Set(CECDEVICE_AUDIOSYSTEM); break; case LOCALISED_ID_TV_AVR: - addresses.Set(CECDEVICE_TV); addresses.Set(CECDEVICE_AUDIOSYSTEM); + addresses.Set(CECDEVICE_TV); break; case LOCALISED_ID_NONE: default: @@ -1499,9 +1506,12 @@ bool CPeripheralCecAdapterUpdateThread::WaitReady(void) if (m_configuration.wakeDevices.IsEmpty() && m_configuration.bActivateSource == 0) return true; + CTimer m_timer(this); + m_timer.Start(30000); + // wait for the TV if we're configured to become the active source. // wait for the first device in the wake list otherwise. - cec_logical_address waitFor = (m_configuration.bActivateSource == 1) ? + cec_logical_address waitFor = (m_configuration.bActivateSource == 1 && m_adapter->m_bActiveSourcePending) ? CECDEVICE_TV : m_configuration.wakeDevices.primary; @@ -1565,33 +1575,39 @@ std::string CPeripheralCecAdapterUpdateThread::UpdateAudioSystemStatus(void) bool CPeripheralCecAdapterUpdateThread::SetInitialConfiguration(void) { + // devices to wake are set + if (!m_configuration.wakeDevices.IsEmpty() && (m_configuration.wakeDevices.primary != CECDEVICE_TV || m_configuration.bActivateSource == 0)) + { + m_adapter->m_cecAdapter->PowerOnDevices(m_configuration.wakeDevices.primary); + } + // the option to make XBMC the active source is set if (m_configuration.bActivateSource == 1) - m_adapter->m_cecAdapter->SetActiveSource(); + m_adapter->ActivateSource(); - // devices to wake are set - cec_logical_addresses tvOnly; - tvOnly.Clear(); tvOnly.Set(CECDEVICE_TV); - if (!m_configuration.wakeDevices.IsEmpty() && (m_configuration.wakeDevices != tvOnly || m_configuration.bActivateSource == 0)) - m_adapter->m_cecAdapter->PowerOnDevices(CECDEVICE_BROADCAST); + std::string strNotification; + std::string strAmpName = UpdateAudioSystemStatus(); + if (!strAmpName.empty()) + strNotification += StringUtils::Format("- %s", strAmpName.c_str()); - // wait until devices are powered up + // wait until power up if (!WaitReady()) return false; + m_adapter->m_bIsReady = true; UpdateMenuLanguage(); + CTimer m_timer(this); + m_timer.Start(10000); + // wait until we get active source + bool bContinue(true); + while (!m_adapter->m_cecAdapter->IsLibCECActiveSource() && + bContinue) + bContinue = !m_event.WaitMSec(1000); // request the OSD name of the TV - std::string strNotification; cec_osd_name tvName = m_adapter->m_cecAdapter->GetDeviceOSDName(CECDEVICE_TV); strNotification = StringUtils::Format("%s: %s", g_localizeStrings.Get(36016).c_str(), tvName.name); - std::string strAmpName = UpdateAudioSystemStatus(); - if (!strAmpName.empty()) - strNotification += StringUtils::Format("- %s", strAmpName.c_str()); - - m_adapter->m_bIsReady = true; - // and let the gui know that we're done CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(36000), strNotification); diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.h b/xbmc/peripherals/devices/PeripheralCecAdapter.h index a5d80cb..8e21ccc 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.h +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.h @@ -48,6 +48,7 @@ namespace PERIPHERALS #include "PeripheralHID.h" #include "interfaces/AnnouncementManager.h" #include "threads/Thread.h" +#include "threads/Timer.h" #include "threads/CriticalSection.h" #include @@ -140,6 +141,7 @@ namespace PERIPHERALS void GetNextKey(void); void SetAudioSystemConnected(bool bSetTo); + bool GetAudioSystemConnected(); void SetMenuLanguage(const char *strLanguage); // callbacks from libCEC @@ -181,7 +183,7 @@ namespace PERIPHERALS std::string m_strComPort; }; - class CPeripheralCecAdapterUpdateThread : public CThread + class CPeripheralCecAdapterUpdateThread : public CThread, ITimerCallback { public: CPeripheralCecAdapterUpdateThread(CPeripheralCecAdapter *adapter, CEC::libcec_configuration *configuration); @@ -196,6 +198,7 @@ namespace PERIPHERALS bool WaitReady(void); bool SetInitialConfiguration(void); void Process(void); + void OnTimeout() { m_event.Set(); }; CPeripheralCecAdapter * m_adapter; CEvent m_event; -- 2.7.1 From aefa78d541c91b1a8e8a3c294a4ded571e847db5 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 8 Jun 2015 11:12:40 +0200 Subject: [PATCH 027/250] quick hack to avoid too long double_tap setting (which was set to 2000ms automatically on libCEC to 2.2.0 upgrade. Upstream-commit: 5fc3336e308136551b4b83a2371845a8a3793650 --- xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index 9a82fa1..2c3689b 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -1384,7 +1384,7 @@ void CPeripheralCecAdapter::SetConfigurationFromSettings(void) #if defined(CEC_DOUBLE_TAP_TIMEOUT_MS_OLD) // double tap prevention timeout in ms. libCEC uses 50ms units for this in 2.2.0, so divide by 50 - m_configuration.iDoubleTapTimeout50Ms = GetSettingInt("double_tap_timeout_ms") / 50; + m_configuration.iDoubleTapTimeout50Ms = (GetSettingInt("double_tap_timeout_ms") / 50 > 10) ? 4 : GetSettingInt("double_tap_timeout_ms") / 50; #else // backwards compatibility. will be removed once the next major release of libCEC is out m_configuration.iDoubleTapTimeoutMs = GetSettingInt("double_tap_timeout_ms"); -- 2.7.1 From 7fecfd2f03b3785bc4f1f39ec7ec13cc28217551 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 15:54:37 +0100 Subject: [PATCH 028/250] Stopping XBMC from rendering the screen if not needed (TV off, or XBMC not selected as root). On reactivation, it also updates monitor/TV resolutions and adapts screen output if needed. Upstream-commit: 0bf5cbfc52c0ac503d4f6cab2e9a6d709fca740f --- xbmc/Application.cpp | 28 +++++++++++++++++++++ xbmc/Application.h | 9 +++++++ xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 8 ++++++ xbmc/settings/Settings.cpp | 1 + xbmc/windowing/egl/WinSystemEGL.cpp | 30 ++++++++++++++--------- 5 files changed, 64 insertions(+), 12 deletions(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index ac0ed74..e4a4999 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -283,6 +283,8 @@ CApplication::CApplication(void) m_bPlaybackStarting = false; m_ePlayState = PLAY_STATE_NONE; m_skinReverting = false; + m_cecStandby = false; + m_res.strMode = ""; #ifdef HAS_GLX XInitThreads(); @@ -337,7 +339,10 @@ bool CApplication::OnEvent(XBMC_Event& newEvent) { case XBMC_QUIT: if (!g_application.m_bStop) + { CApplicationMessenger::GetInstance().PostMsg(TMSG_QUIT); + g_application.SetCecStandby(false); + } break; case XBMC_VIDEORESIZE: if (g_windowManager.Initialized() && @@ -811,6 +816,8 @@ bool CApplication::CreateGUI() info.iHeight, info.strMode.c_str()); + m_res = info; + CLog::Log(LOGDEBUG, "%s: -- base resolution changed to '%s'", __func__, m_res.strMode.c_str()); g_windowManager.Initialize(); return true; @@ -1448,6 +1455,11 @@ void CApplication::OnSettingChanged(const CSetting *setting) m_replayGainSettings.iNoGainPreAmp = ((CSettingInt*)setting)->GetValue(); else if (StringUtils::EqualsNoCase(settingId, CSettings::SETTING_MUSICPLAYER_REPLAYGAINAVOIDCLIPPING)) m_replayGainSettings.bAvoidClipping = ((CSettingBool*)setting)->GetValue(); + + if (StringUtils::EqualsNoCase(settingId, "videoscreen.screenmode") || StringUtils::EqualsNoCase(settingId, "videoscreen.resolution")) { + m_res = CDisplaySettings::Get().GetResolutionInfo(CDisplaySettings::Get().GetDisplayResolution()); + CLog::Log(LOGDEBUG, "%s: -- base resolution changed to '%s'", __func__, m_res.strMode.c_str()); + } } void CApplication::OnSettingAction(const CSetting *setting) @@ -1890,6 +1902,20 @@ float CApplication::GetDimScreenSaverLevel() const return 100.0f; } +void CApplication::SetCecStandby(bool status) +{ + if (status == m_cecStandby) + return; + + CLog::Log(LOGDEBUG, "%s is %x, se %d, sa %d", __FUNCTION__, (int)status, m_screenSaver ? 1:0, m_bScreenSave); + + m_cecStandby = status; + if (g_application.m_bStop) + return; + + SetRenderGUI(!status); +} + void CApplication::Render() { // do not render if we are stopped or in background @@ -2022,6 +2048,8 @@ void CApplication::Render() else flip = true; + flip &= !m_cecStandby; + //fps limiter, make sure each frame lasts at least singleFrameTime milliseconds if (limitFrames || !(flip || m_bPresentFrame)) { diff --git a/xbmc/Application.h b/xbmc/Application.h index b9fe604..6b8f253 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h @@ -72,6 +72,8 @@ namespace MEDIA_DETECT #include "ApplicationPlayer.h" #include "interfaces/IActionListener.h" +#include "guilib/Resolution.h" + class CSeekHandler; class CInertialScrollingHandler; class DPMSSupport; @@ -306,6 +308,7 @@ public: inline bool IsInScreenSaver() { return m_bScreenSave; }; inline bool IsDPMSActive() { return m_dpmsIsActive; }; int m_iScreenSaveLock; // spiff: are we checking for a lock? if so, ignore the screensaver state, if -1 we have failed to input locks + RESOLUTION_INFO m_res; bool m_bPlaybackStarting; typedef enum @@ -391,6 +394,10 @@ public: */ void UnregisterActionListener(IActionListener *listener); + bool ScreenSaverDisablesAutoScrolling(); + void SetCecStandby(bool status); + bool GetCecStandby() { return m_cecStandby; } + protected: virtual bool OnSettingsSaving() const override; @@ -417,6 +424,8 @@ protected: bool m_saveSkinOnUnloading; bool m_autoExecScriptExecuted; + bool m_cecStandby; + #if defined(TARGET_DARWIN_IOS) friend class CWinEventsIOS; #endif diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index 2c3689b..1200ca7 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -173,6 +173,9 @@ void CPeripheralCecAdapter::Announce(AnnouncementFlag flag, const char *sender, GetAudioSystemConnected()) m_cecAdapter->PowerOnDevices(CECDEVICE_AUDIOSYSTEM); } + // if we disable render on TV power on/off events, we have to enable it again screensaver off + // to get screen updates for VNC sessions + g_application.SetCecStandby(false); } else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && m_bIsReady) { @@ -640,6 +643,8 @@ int CPeripheralCecAdapter::CecCommand(void *cbParam, const cec_command command) else if (adapter->m_configuration.bShutdownOnStandby == 1) g_application.ExecuteXBMCAction("Shutdown"); } + if (command.initiator == CECDEVICE_TV) + g_application.SetCecStandby(true); break; case CEC_OPCODE_SET_MENU_LANGUAGE: if (adapter->m_configuration.bUseTVMenuLanguage == 1 && command.initiator == CECDEVICE_TV && command.parameters.size == 3) @@ -1192,6 +1197,9 @@ void CPeripheralCecAdapter::CecSourceActivated(void *cbParam, const CEC::cec_log CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_STOP); } } + + if (activated != 1) + g_application.SetCecStandby(true); } int CPeripheralCecAdapter::CecLogMessage(void *cbParam, const cec_log_message message) diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp index f50355b..def16e0 100644 --- a/xbmc/settings/Settings.cpp +++ b/xbmc/settings/Settings.cpp @@ -1034,6 +1034,7 @@ void CSettings::InitializeISettingCallbacks() settingSet.insert(CSettings::SETTING_VIDEOSCREEN_MONITOR); settingSet.insert(CSettings::SETTING_VIDEOSCREEN_PREFEREDSTEREOSCOPICMODE); m_settingsManager->RegisterCallback(&CDisplaySettings::GetInstance(), settingSet); + m_settingsManager->RegisterCallback(&g_application, settingSet); settingSet.clear(); settingSet.insert(CSettings::SETTING_VIDEOPLAYER_SEEKDELAY); diff --git a/xbmc/windowing/egl/WinSystemEGL.cpp b/xbmc/windowing/egl/WinSystemEGL.cpp index 696ded1..e42b3cd 100644 --- a/xbmc/windowing/egl/WinSystemEGL.cpp +++ b/xbmc/windowing/egl/WinSystemEGL.cpp @@ -18,6 +18,7 @@ * */ #include "system.h" +#include "Application.h" #ifdef HAS_EGL @@ -373,14 +374,6 @@ void CWinSystemEGL::UpdateResolutions() } } - /* ProbeResolutions includes already all resolutions. - * Only get desktop resolution so we can replace xbmc's desktop res - */ - if (m_egl->GetNativeResolution(&curDisplay)) - resDesktop = curDisplay; - - - RESOLUTION ResDesktop = RES_INVALID; RESOLUTION res_index = RES_DESKTOP; for (size_t i = 0; i < resolutions.size(); i++) @@ -405,6 +398,22 @@ void CWinSystemEGL::UpdateResolutions() resolutions[i].dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "", resolutions[i].fRefreshRate); + res_index = (RESOLUTION)((int)res_index + 1); + } + + /* ProbeResolutions includes already all resolutions. + * Only get desktop resolution so we can replace xbmc's desktop res + */ + if (!g_application.m_res.strMode.empty()) + resDesktop = g_application.m_res; + else if (CDisplaySettings::Get().GetDisplayResolution() != RES_DESKTOP) + resDesktop = CDisplaySettings::Get().GetResolutionInfo(CDisplaySettings::Get().GetDisplayResolution()); + else if (m_egl->GetNativeResolution(&curDisplay)) + resDesktop = curDisplay; + + RESOLUTION ResDesktop = RES_INVALID; + + for (size_t i = 0; i < resolutions.size(); i++) if(resDesktop.iWidth == resolutions[i].iWidth && resDesktop.iHeight == resolutions[i].iHeight && resDesktop.iScreenWidth == resolutions[i].iScreenWidth && @@ -412,12 +421,9 @@ void CWinSystemEGL::UpdateResolutions() (resDesktop.dwFlags & D3DPRESENTFLAG_MODEMASK) == (resolutions[i].dwFlags & D3DPRESENTFLAG_MODEMASK) && fabs(resDesktop.fRefreshRate - resolutions[i].fRefreshRate) < FLT_EPSILON) { - ResDesktop = res_index; + ResDesktop = (RESOLUTION)(i + (int)RES_DESKTOP); } - res_index = (RESOLUTION)((int)res_index + 1); - } - // swap desktop index for desktop res if available if (ResDesktop != RES_INVALID) { -- 2.7.1 From 165246aac006393f5edabccd9d4533f35f21cb1d Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 15:58:21 +0100 Subject: [PATCH 029/250] EGLRPI-nativeres.patch Upstream-commit: 32ff894501ac39fe634848991d88871a80729320 This makes RPI EGL implementation not faking "static" resolution (which was obtained on XBMC startup). It was helping go around XBMC's way of fullscreen implementation. (one static modelist, not handling FB res changes, replacing desktop res etc) --- xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 96 ++++++++++++------------- 1 file changed, 45 insertions(+), 51 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp index 5d5b74b..81417b6 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp @@ -175,7 +175,50 @@ bool CEGLNativeTypeRaspberryPI::DestroyNativeWindow() bool CEGLNativeTypeRaspberryPI::GetNativeResolution(RESOLUTION_INFO *res) const { #if defined(TARGET_RASPBERRY_PI) - *res = m_desktopRes; + TV_DISPLAY_STATE_T tv_state; + + // get current display settings state + memset(&tv_state, 0, sizeof(TV_DISPLAY_STATE_T)); + m_DllBcmHost->vc_tv_get_display_state(&tv_state); + + if ((tv_state.state & ( VC_HDMI_HDMI | VC_HDMI_DVI )) != 0) // hdtv + { + res->iScreen = 0; + res->bFullScreen = true; + res->iWidth = tv_state.display.hdmi.width; + res->iHeight = tv_state.display.hdmi.height; + res->iScreenWidth = tv_state.display.hdmi.width; + res->iScreenHeight= tv_state.display.hdmi.height; + res->dwFlags = MAKEFLAGS(tv_state.display.hdmi.group, tv_state.display.hdmi.mode, tv_state.display.hdmi.scan_mode); + res->fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)res->iScreenWidth / (float)res->iScreenHeight); + // Also add 3D flags + if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_SBS_HALF) + { + res->dwFlags |= D3DPRESENTFLAG_MODE3DSBS; + res->fPixelRatio *= 2.0; + } + else if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_TB_HALF) + { + res->dwFlags |= D3DPRESENTFLAG_MODE3DTB; + res->fPixelRatio *= 0.5; + } + HDMI_PROPERTY_PARAM_T property; + property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE; + vc_tv_hdmi_get_property(&property); + res->fRefreshRate = property.param1 == HDMI_PIXEL_CLOCK_TYPE_NTSC ? tv_state.display.hdmi.frame_rate * (1000.0f/1001.0f) : tv_state.display.hdmi.frame_rate; + } + else if ((tv_state.state & ( VC_SDTV_NTSC | VC_SDTV_PAL )) != 0) // sdtv + { + res->iScreen = 0; + res->bFullScreen = true; + res->iWidth = tv_state.display.sdtv.width; + res->iHeight = tv_state.display.sdtv.height; + res->iScreenWidth = tv_state.display.sdtv.width; + res->iScreenHeight= tv_state.display.sdtv.height; + res->dwFlags = MAKEFLAGS(HDMI_RES_GROUP_INVALID, tv_state.display.sdtv.mode, 1); + res->fRefreshRate = (float)tv_state.display.sdtv.frame_rate; + res->fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)res->iScreenWidth / (float)res->iScreenHeight); + } DLOG("CEGLNativeTypeRaspberryPI::GetNativeResolution %s\n", res->strMode.c_str()); return true; @@ -478,57 +521,8 @@ bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &r if(m_initDesktopRes) { - TV_DISPLAY_STATE_T tv_state; - - // get current display settings state - memset(&tv_state, 0, sizeof(TV_DISPLAY_STATE_T)); - m_DllBcmHost->vc_tv_get_display_state(&tv_state); - - if ((tv_state.state & ( VC_HDMI_HDMI | VC_HDMI_DVI )) != 0) // hdtv - { - m_desktopRes.iScreen = 0; - m_desktopRes.bFullScreen = true; - m_desktopRes.iWidth = tv_state.display.hdmi.width; - m_desktopRes.iHeight = tv_state.display.hdmi.height; - m_desktopRes.iScreenWidth = tv_state.display.hdmi.width; - m_desktopRes.iScreenHeight= tv_state.display.hdmi.height; - m_desktopRes.dwFlags = MAKEFLAGS(tv_state.display.hdmi.group, tv_state.display.hdmi.mode, tv_state.display.hdmi.scan_mode); - m_desktopRes.fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); - // Also add 3D flags - if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_SBS_HALF) - { - m_desktopRes.dwFlags |= D3DPRESENTFLAG_MODE3DSBS; - m_desktopRes.fPixelRatio *= 2.0; - } - else if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_TB_HALF) - { - m_desktopRes.dwFlags |= D3DPRESENTFLAG_MODE3DTB; - m_desktopRes.fPixelRatio *= 0.5; - } - HDMI_PROPERTY_PARAM_T property; - property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE; - vc_tv_hdmi_get_property(&property); - m_desktopRes.fRefreshRate = property.param1 == HDMI_PIXEL_CLOCK_TYPE_NTSC ? tv_state.display.hdmi.frame_rate * (1000.0f/1001.0f) : tv_state.display.hdmi.frame_rate; - } - else if ((tv_state.state & ( VC_SDTV_NTSC | VC_SDTV_PAL )) != 0) // sdtv - { - m_desktopRes.iScreen = 0; - m_desktopRes.bFullScreen = true; - m_desktopRes.iWidth = tv_state.display.sdtv.width; - m_desktopRes.iHeight = tv_state.display.sdtv.height; - m_desktopRes.iScreenWidth = tv_state.display.sdtv.width; - m_desktopRes.iScreenHeight= tv_state.display.sdtv.height; - m_desktopRes.dwFlags = MAKEFLAGS(HDMI_RES_GROUP_INVALID, tv_state.display.sdtv.mode, 1); - m_desktopRes.fRefreshRate = (float)tv_state.display.sdtv.frame_rate; - m_desktopRes.fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight); - } - + m_initDesktopRes = !GetNativeResolution(&m_desktopRes); SetResolutionString(m_desktopRes); - - m_initDesktopRes = false; - - m_desktopRes.iSubtitles = (int)(0.965 * m_desktopRes.iHeight); - CLog::Log(LOGDEBUG, "EGL initial desktop resolution %s (%.2f)\n", m_desktopRes.strMode.c_str(), m_desktopRes.fPixelRatio); } -- 2.7.1 From 008d497f3c6344f2ce0b72930ee46ca592d53296 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 16:07:59 +0100 Subject: [PATCH 030/250] MediaLibrary13.patch Upstream-commit: bca274c35cd69728d9ae6f100ab00e640965bf81 --- addons/webinterface.default/js/MediaLibrary.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/webinterface.default/js/MediaLibrary.js b/addons/webinterface.default/js/MediaLibrary.js index a5bbe72..211460b 100755 --- a/addons/webinterface.default/js/MediaLibrary.js +++ b/addons/webinterface.default/js/MediaLibrary.js @@ -228,12 +228,12 @@ MediaLibrary.prototype = { {'playerid': player, 'to': 'previous'} ); case 'forward': - return this.rpcCall('Player.SetSpeed', - {'playerid': player, 'speed': 'increment'} + return this.rpcCall('Player.Seek', + {'playerid': player, 'speed': 'smallforward'} ); case 'rewind': - return this.rpcCall('Player.SetSpeed', - {'playerid': player, 'speed': 'decrement'} + return this.rpcCall('Player.Seek', + {'playerid': player, 'speed': 'smallbackward'} ); } } -- 2.7.1 From 336b0282d1f6220fd3228c561360f3490788c672 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 16:14:19 +0100 Subject: [PATCH 031/250] Splash.patch Upstream-commit: debbd46a2895b2db9e21a0d1499c9c16bc63740b XBian splash integration TODO: get rid of system() calls, do socket communication directly to splash-daemon --- xbmc/Application.cpp | 4 ++-- xbmc/Application.h | 2 +- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 1 + xbmc/windowing/egl/EGLWrapper.cpp | 1 + xbmc/xbmc.cpp | 12 +++++++++++- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index e4a4999..5c57820 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -706,7 +706,7 @@ bool CApplication::Create() return true; } -bool CApplication::CreateGUI() +bool CApplication::CreateGUI(bool showXBMCSplash) { m_renderGUI = true; #ifdef HAS_SDL @@ -802,7 +802,7 @@ bool CApplication::CreateGUI() if (sav_res) CDisplaySettings::GetInstance().SetCurrentResolution(RES_DESKTOP, true); - if (g_advancedSettings.m_splashImage) + if (g_advancedSettings.m_splashImage && showXBMCSplash) CSplash::GetInstance().Show(); // The key mappings may already have been loaded by a peripheral diff --git a/xbmc/Application.h b/xbmc/Application.h index 6b8f253..f5df4a3 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h @@ -145,7 +145,7 @@ public: virtual bool Create() override; virtual bool Cleanup() override; - bool CreateGUI(); + bool CreateGUI(bool showXBMCSplash); bool InitWindow(RESOLUTION res = RES_INVALID); bool DestroyWindow(); void StartServices(); diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 9b35512..3182f58 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -163,6 +163,7 @@ void CEGLNativeTypeIMX::Destroy() close(fd); + system("/usr/bin/splash --force -i -m 'stopping xbmc...'"); return; } diff --git a/xbmc/windowing/egl/EGLWrapper.cpp b/xbmc/windowing/egl/EGLWrapper.cpp index 036d4b9..e38aa03 100644 --- a/xbmc/windowing/egl/EGLWrapper.cpp +++ b/xbmc/windowing/egl/EGLWrapper.cpp @@ -88,6 +88,7 @@ bool CEGLWrapper::Initialize(const std::string &implementation) { CEGLNativeType *nativeGuess = NULL; + system("/usr/bin/splash --force -b"); // Try to create each backend in sequence and go with the first one // that we know will work if ( diff --git a/xbmc/xbmc.cpp b/xbmc/xbmc.cpp index 366e4b5..b916339 100644 --- a/xbmc/xbmc.cpp +++ b/xbmc/xbmc.cpp @@ -20,6 +20,8 @@ #include "Application.h" #include "settings/AdvancedSettings.h" +#include "stdlib.h" +#include #ifdef TARGET_RASPBERRY_PI #include "linux/RBP.h" @@ -43,6 +45,14 @@ extern "C" int XBMC_Run(bool renderGUI) { int status = -1; + bool showXBMCSplash = true; + std::string filename = "/usr/bin/splash"; + struct stat buf; + if (stat(filename.c_str(), &buf) != -1) + { + system("/usr/bin/splash --force -i -m 'starting xbmc...'"); + showXBMCSplash = false; + } if (!g_advancedSettings.Initialized()) { @@ -80,7 +90,7 @@ extern "C" int XBMC_Run(bool renderGUI) g_RBP.LogFirmwareVerison(); #endif - if (renderGUI && !g_application.CreateGUI()) + if (renderGUI && !g_application.CreateGUI(showXBMCSplash)) { CMessagePrinter::DisplayError("ERROR: Unable to create GUI. Exiting"); return status; -- 2.7.1 From 006b66e2fce9684a66ad5c51f9aab31b78a7b8db Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 16:15:25 +0100 Subject: [PATCH 032/250] Wiimote.patch Upstream-commit: b16a2af30b2ac673e4aabe09d6d0272ea4ad8d72 --- tools/EventClients/Clients/WiiRemote/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/EventClients/Clients/WiiRemote/Makefile b/tools/EventClients/Clients/WiiRemote/Makefile index eba0f1e..8bb41a5 100644 --- a/tools/EventClients/Clients/WiiRemote/Makefile +++ b/tools/EventClients/Clients/WiiRemote/Makefile @@ -7,7 +7,7 @@ VERSION = v0.12 all: @$(MAKE) -C wiiuse_$(VERSION)/src $@ - $(CXX) $(CFLAGS) -I./wiiuse_$(VERSION)/src WiiUse_WiiRemote.cpp $(OBJS) -o $(BIN) + $(CXX) $(CFLAGS) -I./wiiuse_$(VERSION)/src WiiUse_WiiRemote.cpp $(OBJS) -o $(BIN) -l bluetooth wiiuse: @$(MAKE) -C wiiuse_$(VERSION)/src clean: -- 2.7.1 From 6c5621cb6f02538af18a3d8c6cd3d55f610023f1 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 16:20:32 +0100 Subject: [PATCH 033/250] configure-in-no-java.patch Upstream-commit: fd21a162be3a3958b2b0d9d853a6a6aaa92238e1 skip all JAVA processing on compilation. this doesn't work on qemu started environments. we handle all java related tasks via small hook script in pre-make.d --- codegenerator.mk | 5 ----- configure.ac | 7 ++----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/codegenerator.mk b/codegenerator.mk index 2af2128..c790e74 100644 --- a/codegenerator.mk +++ b/codegenerator.mk @@ -62,11 +62,6 @@ $(DOXYGEN): @echo "Warning: No doxygen installed. The Api will not have any docstrings." mkdir -p $(GENDIR)/doxygenxml -$(JAVA): - @echo Java not found, it will be used if found after configure. - @echo This is not necessarily an error. - @false - $(SWIG): @echo Swig not found, it will be used if found after configure. @echo This is not necessarily an error. diff --git a/configure.ac b/configure.ac index deccef2..1b155fc 100644 --- a/configure.ac +++ b/configure.ac @@ -248,9 +248,9 @@ AC_ARG_WITH([platform], AC_ARG_ENABLE([optimizations], [AS_HELP_STRING([--enable-optimizations], - [enable optimization (default is yes)])], + [enable optimization (default is no)])], [use_optimizations=$enableval], - [use_optimizations=yes]) + [use_optimizations=no]) AC_ARG_ENABLE([gl], [AS_HELP_STRING([--enable-gl], @@ -1755,9 +1755,6 @@ final_message="$final_message\n SWIG Available:\tYes" echo "Checking for a jre installation" AC_PATH_PROG(JAVA_EXE, java, "none") -if test "$JAVA_EXE" = "none"; then - AC_MSG_ERROR($missing_program) -fi final_message="$final_message\n JRE Available:\tYes" echo "Checking for doxygen installation" -- 2.7.1 From 0bed2298c0950df7df42a60ce39b41835f532021 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 16:24:07 +0100 Subject: [PATCH 034/250] cpuinfo.patch Upstream-commit: ac17dc0e8f15fed47e8ff6ea91e6bd6878d05017 --- xbmc/utils/CPUInfo.cpp | 32 ++++++-------------------------- xbmc/utils/CPUInfo.h | 1 + 2 files changed, 7 insertions(+), 26 deletions(-) diff --git a/xbmc/utils/CPUInfo.cpp b/xbmc/utils/CPUInfo.cpp index c70cd04..b8cfefd 100644 --- a/xbmc/utils/CPUInfo.cpp +++ b/xbmc/utils/CPUInfo.cpp @@ -377,7 +377,7 @@ CCPUInfo::CCPUInfo(void) StringUtils::Trim(m_cores[nCurrId].m_strModel); } } - else if (strncmp(buffer, "flags", 5) == 0) + else if (strncmp(buffer, "flags", 5) == 0 || strncmp(buffer, "Features", 8) == 0) { char* needle = strchr(buffer, ':'); if (needle) @@ -408,6 +408,10 @@ CCPUInfo::CCPUInfo(void) m_cpuFeatures |= CPU_FEATURE_3DNOW; else if (0 == strcmp(tok, "3dnowext")) m_cpuFeatures |= CPU_FEATURE_3DNOWEXT; + else if (0 == strcmp(tok, "neon")) + m_cpuFeatures |= CPU_FEATURE_NEON; + else if (0 == strcmp(tok, "thumb")) + m_cpuFeatures |= CPU_FEATURE_THUMB; tok = strtok_r(NULL, " ", &save); } } @@ -453,10 +457,6 @@ CCPUInfo::CCPUInfo(void) // Set MMX2 when SSE is present as SSE is a superset of MMX2 and Intel doesn't set the MMX2 cap if (m_cpuFeatures & CPU_FEATURE_SSE) m_cpuFeatures |= CPU_FEATURE_MMX2; - - if (HasNeon()) - m_cpuFeatures |= CPU_FEATURE_NEON; - } CCPUInfo::~CCPUInfo() @@ -940,27 +940,7 @@ bool CCPUInfo::HasNeon() has_neon = 1; #elif defined(TARGET_LINUX) && defined(__ARM_NEON__) - if (has_neon == -1) - { - has_neon = 0; - // why are we not looking at the Features in - // /proc/cpuinfo for neon ? - int fd = open("/proc/self/auxv", O_RDONLY); - if (fd >= 0) - { - Elf32_auxv_t auxv; - while (read(fd, &auxv, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t)) - { - if (auxv.a_type == AT_HWCAP) - { - has_neon = (auxv.a_un.a_val & HWCAP_NEON) ? 1 : 0; - break; - } - } - close(fd); - } - } - + has_neon = ((g_cpuInfo.GetCPUFeatures() & CPU_FEATURE_NEON) == CPU_FEATURE_NEON) ? 1 : 0; #endif return has_neon == 1; diff --git a/xbmc/utils/CPUInfo.h b/xbmc/utils/CPUInfo.h index 1c5e5ba..5f3e2f9 100644 --- a/xbmc/utils/CPUInfo.h +++ b/xbmc/utils/CPUInfo.h @@ -47,6 +47,7 @@ class CTemperature; #define CPU_FEATURE_3DNOWEXT 1 << 9 #define CPU_FEATURE_ALTIVEC 1 << 10 #define CPU_FEATURE_NEON 1 << 11 +#define CPU_FEATURE_THUMB 1 << 12 struct CoreInfo { -- 2.7.1 From 7cda86fead91fc2545f7309f791afe5b1dd2d3b2 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 2 Jul 2014 23:57:23 +0200 Subject: [PATCH 035/250] keyboard: disable backslash (ToggleFullScreen). Upstream-commit: 6899af49d8203da71884ef8d92764ef4ff45990e Signed-off-by: Roberto Leandrini Signed-off-by: Matus Kral --- system/keymaps/keyboard.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/keymaps/keyboard.xml b/system/keymaps/keyboard.xml index 4bcc1ce..ab1453f 100644 --- a/system/keymaps/keyboard.xml +++ b/system/keymaps/keyboard.xml @@ -88,7 +88,7 @@ Number7 Number8 Number9 - ToggleFullScreen + FirstPage LastPage ActivateWindow(shutdownmenu) -- 2.7.1 From 313033ddd6d909ed05bba745cbd82b66bc32ed13 Mon Sep 17 00:00:00 2001 From: anaconda Date: Fri, 24 Oct 2014 04:12:39 +0200 Subject: [PATCH 036/250] mediamanager: ignore btrfs-auto-snapshot snapshot directory (/{tmp,run}/btrfs-snap). Upstream-commit: 4b9d685df69e5ec5f85f26d3d526a91f04dfbae4 Signed-off-by: Matus Kral --- xbmc/storage/MediaManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xbmc/storage/MediaManager.cpp b/xbmc/storage/MediaManager.cpp index fe24924..0444985 100644 --- a/xbmc/storage/MediaManager.cpp +++ b/xbmc/storage/MediaManager.cpp @@ -680,6 +680,9 @@ std::vector CMediaManager::GetDiskUsage() void CMediaManager::OnStorageAdded(const std::string &label, const std::string &path) { #ifdef HAS_DVD_DRIVE + if (path == "/run/btrfs-snap" || path == "/tmp/btrfs-snap") + return; + if (CSettings::GetInstance().GetInt(CSettings::SETTING_AUDIOCDS_AUTOACTION) != AUTOCD_NONE || CSettings::GetInstance().GetBool(CSettings::SETTING_DVDS_AUTORUN)) if (CSettings::GetInstance().GetInt(CSettings::SETTING_AUDIOCDS_AUTOACTION) == AUTOCD_RIP) CJobManager::GetInstance().AddJob(new CAutorunMediaJob(label, path), this, CJob::PRIORITY_LOW); -- 2.7.1 From e832934820ba0deac769d76d9af9522ac32662a5 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 30 Jul 2014 00:35:47 +0200 Subject: [PATCH 037/250] adjust resolution on play. Upstream-commit: 51f2d3b09318b36d5e731aeb52229ee02f86d563 Extend re-matching resolution with a way to find closest resolution to previous one if new modelist doesn't provide exactly same resolution as is(was) set before. --- .../resource.language.en_gb/resources/strings.po | 13 +++++- system/settings/imx6.xml | 12 ++++++ system/settings/settings.xml | 18 +++++++++ xbmc/cores/VideoRenderers/BaseRenderer.cpp | 46 ++++++++++++++++++++++ xbmc/cores/VideoRenderers/BaseRenderer.h | 1 + xbmc/windowing/egl/WinSystemEGL.cpp | 17 +++++++- 6 files changed, 104 insertions(+), 3 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index a697a61..ff65ede 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -6709,7 +6709,12 @@ msgctxt "#13557" msgid "Skip delay" msgstr "" -#empty strings from id 13558 to 13599 +#: system/settings/settings.xml +msgctxt "#13558" +msgid "Adjust display resolution" +msgstr "" + +#empty strings from id 13559 to 13599 #: system/settings/darwin.xml msgctxt "#13600" @@ -15937,7 +15942,11 @@ msgctxt "#36171" msgid "Select the zoom level that 4:3 videos are shown on widescreen displays." msgstr "" -#empty string with id 36172 +#. Description of setting "Videos -> Playback -> Adjust display resolution" with label #13558 +#: system/settings/settings.xml +msgctxt "#36172" +msgid "Allow the resolution of the display to be changed so that it best matches the video resolution." +msgstr "" #. Description of setting "Appearance -> International -> Short date format" with label #14109 #: system/settings/settings.xml diff --git a/system/settings/imx6.xml b/system/settings/imx6.xml index d8b17c3..3ee2ed5 100644 --- a/system/settings/imx6.xml +++ b/system/settings/imx6.xml @@ -1,5 +1,17 @@ +
+ + + + true + + + false + + + +
diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 76c9a33..62a4f68 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -585,6 +585,24 @@ + + 2 + false + true + + 0 + + + + + 2 + false + true + + true + + + 2 false diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp index 7889cf8..66fe584 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp @@ -35,6 +35,7 @@ #include "settings/AdvancedSettings.h" #include "cores/VideoRenderers/RenderFlags.h" +#include "Application.h" CBaseRenderer::CBaseRenderer() { @@ -237,6 +238,51 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES int curr_diff = std::abs((int) m_sourceWidth - curr.iScreenWidth); int loop_diff = 0; + // CHANGERESOLUTION + if (CSettings::Get().GetBool("videoplayer.adjustresolution") || bRelaxPixelRatio) + { + bool i_found = false; + + if (!bRelaxPixelRatio && !i_found && fRefreshRate != trunc(fRefreshRate)) + for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) + { + const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); + + if ((fabs(info.fRefreshRate - fRefreshRate) > 0.001 && fabs(info.fRefreshRate - 2*fRefreshRate) > 0.001) + || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.001) + continue; + + current = (RESOLUTION)i; + curr = info; + i_found = true; + + if (info.iScreenWidth == m_sourceWidth && info.iScreenHeight == m_sourceHeight) + break; + } + + for (size_t i = (int)RES_DESKTOP; !i_found && i < CDisplaySettings::Get().ResolutionInfoSize(); i++) + { + const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); + + if (m_sourceWidth > info.iScreenWidth || m_sourceHeight > info.iScreenHeight + || pow(info.iScreenWidth*info.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) > + pow(curr.iScreenWidth*curr.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) + || info.iScreen != curr.iScreen + || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK) + || (!bRelaxPixelRatio && fabs(info.fPixelRatio - curr.fPixelRatio) > 0.001)) + { + /* CLog::Log(LOGDEBUG, "curr %.2f, trying %.2f, mode nr. %d, %dx%d msk %d, m_msk %d", info.fPixelRatio, curr.fPixelRatio, i, + info.iScreenWidth, info.iScreenHeight, info.dwFlags & D3DPRESENTFLAG_MODEMASK, + m_iFlags & D3DPRESENTFLAG_MODEMASK); */ + continue; + } + + current = (RESOLUTION)i; + curr = info; + } + } +>>>>>>> adjust resolution on play. + // Find closest refresh rate for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::GetInstance().ResolutionInfoSize(); i++) { diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h index d6a7140..a01449a 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.h +++ b/xbmc/cores/VideoRenderers/BaseRenderer.h @@ -109,6 +109,7 @@ public: virtual void RegisterRenderFeaturesCallBack(const void *ctx, RenderFeaturesCallBackFn fn); static void SettingOptionsRenderMethodsFiller(const CSetting *setting, std::vector< std::pair > &list, int ¤t, void *data); + static RESOLUTION FindClosestResolution(float fps, float multiplier, RESOLUTION current, float& weight, unsigned int m_sourceWidth, unsigned int m_sourceHeight, unsigned m_iFlags, bool bRelaxPixelRatio = false); protected: void ChooseBestResolution(float fps); diff --git a/xbmc/windowing/egl/WinSystemEGL.cpp b/xbmc/windowing/egl/WinSystemEGL.cpp index e42b3cd..848e394 100644 --- a/xbmc/windowing/egl/WinSystemEGL.cpp +++ b/xbmc/windowing/egl/WinSystemEGL.cpp @@ -30,6 +30,7 @@ #include "settings/AdvancedSettings.h" #include "settings/Settings.h" #include "settings/DisplaySettings.h" +#include "cores/VideoRenderers/RenderManager.h" #include "guilib/DispResource.h" #include "threads/SingleLock.h" #ifdef HAS_IMXVPU @@ -419,7 +420,8 @@ void CWinSystemEGL::UpdateResolutions() resDesktop.iScreenWidth == resolutions[i].iScreenWidth && resDesktop.iScreenHeight == resolutions[i].iScreenHeight && (resDesktop.dwFlags & D3DPRESENTFLAG_MODEMASK) == (resolutions[i].dwFlags & D3DPRESENTFLAG_MODEMASK) && - fabs(resDesktop.fRefreshRate - resolutions[i].fRefreshRate) < FLT_EPSILON) + fabs(resDesktop.fRefreshRate - resolutions[i].fRefreshRate) < FLT_EPSILON && + fabs(resDesktop.fPixelRatio - resolutions[i].fPixelRatio) < FLT_EPSILON) { ResDesktop = (RESOLUTION)(i + (int)RES_DESKTOP); } @@ -436,6 +438,19 @@ void CWinSystemEGL::UpdateResolutions() RESOLUTION_INFO desktop = CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP); CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP) = CDisplaySettings::GetInstance().GetResolutionInfo(ResDesktop); CDisplaySettings::GetInstance().GetResolutionInfo(ResDesktop) = desktop; + return; + } + + // if new screen doesn't provide resolution we need, we try to find closest to previous + float weight; + ResDesktop = CBaseRenderer::FindClosestResolution(g_application.m_res.fRefreshRate, 1.0f, (RESOLUTION)0, weight, + g_application.m_res.iWidth, g_application.m_res.iHeight, g_application.m_res.dwFlags, true); + + if (ResDesktop != RES_INVALID) + { + CLog::Log(LOGNOTICE, "New screen doesn't provide previous resolution. Will change to %d", ResDesktop); + CDisplaySettings::GetInstance().SetCurrentResolution(ResDesktop, true); + g_application.m_res = CDisplaySettings::GetInstance().GetResolutionInfo(CDisplaySettings::GetInstance().GetDisplayResolution()); } } -- 2.7.1 From e703d79eea32b7722cdba6b0f381e7e6a0959543 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 16:59:20 +0100 Subject: [PATCH 038/250] add pvr submodule Upstream-commit: f30406b718d9604728d9670c698fb039be1ec404 --- .gitmodules | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitmodules b/.gitmodules index c1fe578..bf5b7c7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "addons/skin.re-touched"] path = addons/skin.re-touched url = git://github.com/xbmc/skin.re-touched.git +[submodule "pvr-addons"] + path = pvr-addons + url = https://github.com/opdenkamp/xbmc-pvr-addons.git + branch = helix -- 2.7.1 From 0177bdc72af433b79b1e9b3c3ec23d85c155debf Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 16:59:34 +0100 Subject: [PATCH 039/250] shutdown-reboot-available.patch Upstream-commit: 3cf63ef2149a6eed6c0ec996882971fab4aadf56 --- xbmc/powermanagement/linux/LogindUPowerSyscall.cpp | 10 +++++++--- xbmc/powermanagement/linux/UPowerSyscall.cpp | 11 ++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/xbmc/powermanagement/linux/LogindUPowerSyscall.cpp b/xbmc/powermanagement/linux/LogindUPowerSyscall.cpp index 4e5bcc6..0212306 100644 --- a/xbmc/powermanagement/linux/LogindUPowerSyscall.cpp +++ b/xbmc/powermanagement/linux/LogindUPowerSyscall.cpp @@ -50,11 +50,15 @@ CLogindUPowerSyscall::CLogindUPowerSyscall() if (!m_hasUPower) CLog::Log(LOGINFO, "LogindUPowerSyscall - UPower not found, battery information will not be available"); - m_canPowerdown = LogindCheckCapability("CanPowerOff"); - m_canReboot = LogindCheckCapability("CanReboot"); + m_canPowerdown = true; + m_canReboot = true; +#if defined(HAS_IMXVPU) || defined(TARGET_RASPBERRY_PI) + m_canHibernate = false; + m_canSuspend = false; +#else m_canHibernate = LogindCheckCapability("CanHibernate"); m_canSuspend = LogindCheckCapability("CanSuspend"); - +#endif InhibitDelayLock(); m_batteryLevel = 0; diff --git a/xbmc/powermanagement/linux/UPowerSyscall.cpp b/xbmc/powermanagement/linux/UPowerSyscall.cpp index 28ce475..20175e7 100644 --- a/xbmc/powermanagement/linux/UPowerSyscall.cpp +++ b/xbmc/powermanagement/linux/UPowerSyscall.cpp @@ -62,6 +62,9 @@ CUPowerSyscall::CUPowerSyscall() m_lowBattery = false; + m_CanPowerdown = true; + m_CanReboot = true; + dbus_error_init (&m_error); // TODO: do not use dbus_connection_pop_message() that requires the use of a // private connection @@ -83,9 +86,6 @@ CUPowerSyscall::CUPowerSyscall() m_connection = NULL; } - m_CanPowerdown = false; - m_CanReboot = false; - UpdateCapabilities(); EnumeratePowerSources(); @@ -262,8 +262,13 @@ bool CUPowerSyscall::PumpPowerEvents(IPowerEventsCallback *callback) void CUPowerSyscall::UpdateCapabilities() { +#if defined(HAS_IMXVPU) || defined(TARGET_RASPBERRY_PI) + m_CanSuspend = false; + m_CanHibernate = false; +#else m_CanSuspend = CDBusUtil::GetVariant("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "CanSuspend").asBoolean(false); m_CanHibernate = CDBusUtil::GetVariant("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "CanHibernate").asBoolean(false); +#endif } #endif -- 2.7.1 From 57d4722609d2de9d40a69d90826120b7051befd1 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 22 Jun 2014 03:24:14 +0200 Subject: [PATCH 040/250] pthreads: disable SetPriority. Upstream-commit: 952b030e1f490e7b1d8fca1bddbc53deb8003121 On XBian we dynamically renice the xbmc.bin process. Signed-off-by: Roberto Leandrini Signed-off-by: Matus Kral --- xbmc/threads/platform/pthreads/ThreadImpl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xbmc/threads/platform/pthreads/ThreadImpl.cpp b/xbmc/threads/platform/pthreads/ThreadImpl.cpp index 70b6ac0..6730523 100644 --- a/xbmc/threads/platform/pthreads/ThreadImpl.cpp +++ b/xbmc/threads/platform/pthreads/ThreadImpl.cpp @@ -142,6 +142,9 @@ int CThread::GetNormalPriority(void) bool CThread::SetPriority(const int iPriority) { +#if 1 + bool bReturn = true; +#else bool bReturn = false; // wait until thread is running, it needs to get its lwp id @@ -193,6 +196,7 @@ bool CThread::SetPriority(const int iPriority) if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno)); } #endif +#endif return bReturn; } -- 2.7.1 From 056b0917d3a70e4a2ffb0e8c5be710e6daa195f6 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 17:01:05 +0100 Subject: [PATCH 041/250] xbmc-loaded.notify.patch Upstream-commit: 9d1605fd260aaf3c5bd6c9608837f65938c27df7 --- xbmc/xbmc.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xbmc/xbmc.cpp b/xbmc/xbmc.cpp index b916339..18c8e0e 100644 --- a/xbmc/xbmc.cpp +++ b/xbmc/xbmc.cpp @@ -22,6 +22,7 @@ #include "settings/AdvancedSettings.h" #include "stdlib.h" #include +#include "utils/log.h" #ifdef TARGET_RASPBERRY_PI #include "linux/RBP.h" @@ -113,6 +114,9 @@ extern "C" int XBMC_Run(bool renderGUI) } #endif + CLog::Log(LOGNOTICE, "XBian: notifying Upstart that i'm well"); + system("sudo /sbin/start -n -q xbmc-loaded"); + try { status = g_application.Run(); -- 2.7.1 From dc9513062898d6282cfd03e7200472391fe7f6e7 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 21:35:52 +0100 Subject: [PATCH 042/250] add pvraddons Upstream-commit: add92bffc02597aa0722167e1b1516418ecee082 --- pvr-addons | 1 + 1 file changed, 1 insertion(+) create mode 160000 pvr-addons diff --git a/pvr-addons b/pvr-addons new file mode 160000 index 0000000..d950c38 --- /dev/null +++ b/pvr-addons @@ -0,0 +1 @@ +Subproject commit d950c38277571c626d82c3da2d17f0c4e70eea9b -- 2.7.1 From a974ce527ebf5531454bfc529a21289ca53b7c33 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 21:51:33 +0100 Subject: [PATCH 043/250] configure-in-rpi-optimization.patch Upstream-commit: ee15e5d92f0f904fc922c498cc67eb42342f5f1b --- configure.ac | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure.ac b/configure.ac index 1b155fc..22cb60c 100644 --- a/configure.ac +++ b/configure.ac @@ -819,6 +819,9 @@ if test "$host_vendor" = "apple" ; then elif test "$target_platform" = "target_raspberry_pi"; then ARCH="arm" use_arch="arm" + CFLAGS="$CFLAGS -pipe -O3 -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " + CXXFLAGS="$CXXFLAGS -pipe -O3 -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " + FFMPEG_EXTRACFLAGS="$FFMPEG_EXTRACFLAGS -pipe -O3 -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " elif test "$use_arch" = "arm"; then CFLAGS="$CFLAGS -mno-apcs-stack-check" CXXFLAGS="$CXXFLAGS -mno-apcs-stack-check" -- 2.7.1 From 5e4d0490c5b62414251228bd18274e516c7ab5c1 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 22:33:32 +0100 Subject: [PATCH 044/250] RPI: libjpeg-alpha.patch - there is no turbo-jpeg lib for wheezy, add ALPHA_EXTENSIONS pieces Upstream-commit: 02a332e20955efeeec3ecb72e4dddd74d93bfcbc --- xbmc/guilib/JpegIO.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/xbmc/guilib/JpegIO.cpp b/xbmc/guilib/JpegIO.cpp index 8ea5286..454117f 100644 --- a/xbmc/guilib/JpegIO.cpp +++ b/xbmc/guilib/JpegIO.cpp @@ -369,6 +369,14 @@ bool CJpegIO::Decode(unsigned char* const pixels, unsigned int width, unsigned i } else if (format == XB_FMT_A8R8G8B8) { +#ifdef JCS_ALPHA_EXTENSIONS + m_cinfo.out_color_space = JCS_EXT_BGRA; + while (m_cinfo.output_scanline < m_height) + { + jpeg_read_scanlines(&m_cinfo, &dst, 1); + dst += pitch; + } +#else unsigned char* row = new unsigned char[m_width * 3]; while (m_cinfo.output_scanline < copyHeight) { @@ -385,6 +393,7 @@ bool CJpegIO::Decode(unsigned char* const pixels, unsigned int width, unsigned i dst += pitch; } delete[] row; +#endif } else { @@ -440,8 +449,13 @@ bool CJpegIO::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int wid JSAMPROW row_pointer[1]; long unsigned int outBufSize = width * height; unsigned char* result; +#ifdef JCS_ALPHA_EXTENSIONS + J_COLOR_SPACE color_space = JCS_RGB; + int components = 3; +#else unsigned char* src = buffer; unsigned char* rgbbuf; +#endif if(buffer == NULL) { @@ -456,6 +470,19 @@ bool CJpegIO::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int wid return false; } +#ifdef JCS_ALPHA_EXTENSIONS + if (format == XB_FMT_A8R8G8B8) + { + color_space = JCS_EXT_BGRA; + components = 4; + } + else if (format != XB_FMT_RGB8) + { + CLog::Log(LOGWARNING, "JpegIO::CreateThumbnailFromSurface Unsupported format"); + free(result); + return false; + } +#else if(format == XB_FMT_RGB8) { rgbbuf = buffer; @@ -485,6 +512,7 @@ bool CJpegIO::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int wid free(result); return false; } +#endif cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = jpeg_error_exit; @@ -494,8 +522,10 @@ bool CJpegIO::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int wid { jpeg_destroy_compress(&cinfo); free(result); +#ifndef JCS_ALPHA_EXTENSIONS if(format != XB_FMT_RGB8) delete [] rgbbuf; +#endif return false; } else @@ -507,23 +537,34 @@ bool CJpegIO::CreateThumbnailFromSurface(unsigned char* buffer, unsigned int wid #endif cinfo.image_width = width; cinfo.image_height = height; +#ifdef JCS_ALPHA_EXTENSIONS + cinfo.input_components = components; + cinfo.in_color_space = color_space; +#else cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; +#endif jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, 90, TRUE); jpeg_start_compress(&cinfo, TRUE); while (cinfo.next_scanline < cinfo.image_height) { +#ifdef JCS_ALPHA_EXTENSIONS + row_pointer[0] = &buffer[cinfo.next_scanline * pitch]; +#else row_pointer[0] = &rgbbuf[cinfo.next_scanline * width * 3]; +#endif jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); } +#ifndef JCS_ALPHA_EXTENSIONS if(format != XB_FMT_RGB8) delete [] rgbbuf; +#endif XFILE::CFile file; const bool ret = file.OpenForWrite(destFile, true) && file.Write(result, outBufSize) == static_cast(outBufSize); @@ -683,8 +724,13 @@ bool CJpegIO::CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int w struct my_error_mgr jerr; JSAMPROW row_pointer[1]; long unsigned int outBufSize = width * height; +#ifdef JCS_ALPHA_EXTENSIONS + J_COLOR_SPACE color_space = JCS_RGB; + int components = 3; +#else unsigned char* src = bufferin; unsigned char* rgbbuf; +#endif if(bufferin == NULL) { @@ -699,6 +745,20 @@ bool CJpegIO::CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int w return false; } +#ifdef JCS_ALPHA_EXTENSIONS + if (format == XB_FMT_A8R8G8B8) + { + color_space = JCS_EXT_BGRA; + components = 4; + } + else if (format != XB_FMT_RGB8) + { + CLog::Log(LOGWARNING, "JpegIO::CreateThumbnailFromSurface Unsupported format"); + free(m_thumbnailbuffer); + m_thumbnailbuffer = NULL; + return false; + } +#else if(format == XB_FMT_RGB8) { rgbbuf = bufferin; @@ -727,8 +787,10 @@ bool CJpegIO::CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int w { CLog::Log(LOGWARNING, "JpegIO::CreateThumbnailFromSurface Unsupported format"); free(m_thumbnailbuffer); + m_thumbnailbuffer = NULL; return false; } +#endif cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = jpeg_error_exit; @@ -738,8 +800,11 @@ bool CJpegIO::CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int w { jpeg_destroy_compress(&cinfo); free(m_thumbnailbuffer); + m_thumbnailbuffer = NULL; +#ifndef JCS_ALPHA_EXTENSIONS if(format != XB_FMT_RGB8) delete [] rgbbuf; +#endif return false; } else @@ -751,23 +816,34 @@ bool CJpegIO::CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int w #endif cinfo.image_width = width; cinfo.image_height = height; +#ifdef JCS_ALPHA_EXTENSIONS + cinfo.input_components = components; + cinfo.in_color_space = color_space; +#else cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; +#endif jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, 90, TRUE); jpeg_start_compress(&cinfo, TRUE); while (cinfo.next_scanline < cinfo.image_height) { +#ifdef JCS_ALPHA_EXTENSIONS + row_pointer[0] = &bufferin[cinfo.next_scanline * pitch]; +#else row_pointer[0] = &rgbbuf[cinfo.next_scanline * width * 3]; +#endif jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); } +#ifndef JCS_ALPHA_EXTENSIONS if(format != XB_FMT_RGB8) delete [] rgbbuf; +#endif bufferout = m_thumbnailbuffer; bufferoutSize = outBufSize; -- 2.7.1 From afa01e1d069eeb10544d5246cd9d9a61a9dd73c6 Mon Sep 17 00:00:00 2001 From: anaconda Date: Mon, 18 Aug 2014 03:30:09 +0200 Subject: [PATCH 045/250] RPI: Remove battery level indication from SystemInfo window. Upstream-commit: 82d0572a2ae22aa366b50fa29ab91dbf2fd12c10 Lighter version of patches/rpi/XBianSysSum13.patch as Helix already exposes the OS version. Signed-off-by: Matus Kral --- xbmc/windows/GUIWindowSystemInfo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xbmc/windows/GUIWindowSystemInfo.cpp b/xbmc/windows/GUIWindowSystemInfo.cpp index 63a46ce..62bdec4 100644 --- a/xbmc/windows/GUIWindowSystemInfo.cpp +++ b/xbmc/windows/GUIWindowSystemInfo.cpp @@ -100,7 +100,9 @@ void CGUIWindowSystemInfo::FrameMove() SetControlLabel(i++, "%s %s", 13283, SYSTEM_OS_VERSION_INFO); SetControlLabel(i++, "%s: %s", 12390, SYSTEM_UPTIME); SetControlLabel(i++, "%s: %s", 12394, SYSTEM_TOTALUPTIME); +#if 0 SetControlLabel(i++, "%s: %s", 12395, SYSTEM_BATTERY_LEVEL); +#endif } else if (m_section == CONTROL_BT_STORAGE) -- 2.7.1 From 6d5d08543f9d1639c6e6c2a1f780b0d84f0e8ded Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 28 Feb 2015 00:37:23 +0100 Subject: [PATCH 046/250] see cb42b6feef470137974257e7950d88245c7aa17a Upstream-commit: 055654c65ebcc79781206c5752b3d1143f86be64 --- .gitmodules | 4 ---- pvr-addons | 1 - 2 files changed, 5 deletions(-) delete mode 160000 pvr-addons diff --git a/.gitmodules b/.gitmodules index bf5b7c7..c1fe578 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,3 @@ [submodule "addons/skin.re-touched"] path = addons/skin.re-touched url = git://github.com/xbmc/skin.re-touched.git -[submodule "pvr-addons"] - path = pvr-addons - url = https://github.com/opdenkamp/xbmc-pvr-addons.git - branch = helix diff --git a/pvr-addons b/pvr-addons deleted file mode 160000 index d950c38..0000000 --- a/pvr-addons +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d950c38277571c626d82c3da2d17f0c4e70eea9b -- 2.7.1 From be33047c6d82300e537b11645ae7266248ff44d2 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 17:04:13 +0100 Subject: [PATCH 047/250] addendum to 5fda65f6eb0190a0dd5a74cbd0842fe71d894429 (to distinguish U: and S: modes as the clks and timings are different) Upstream-commit: d23f6f3a7c9a460dcc66fdce75b28a94e2c1ee4b --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 3182f58..28ea85b 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -406,6 +406,9 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) std::string fromMode = StringUtils::Mid(mode, 2); StringUtils::Trim(fromMode); + if (StringUtils::StartsWith(mode, "U:")) + res->dwFlags = D3DPRESENTFLAG_WIDESCREEN; + CRegExp split(true); split.RegComp("([0-9]+)x([0-9]+)([pi])-([0-9]+)"); if (split.RegFind(fromMode) < 0) @@ -421,7 +424,7 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->iScreenWidth = w; res->iScreenHeight= h; res->fRefreshRate = r; - res->dwFlags = p[0] == 'p' ? D3DPRESENTFLAG_PROGRESSIVE : D3DPRESENTFLAG_INTERLACED; + res->dwFlags |= p[0] == 'p' ? D3DPRESENTFLAG_PROGRESSIVE : D3DPRESENTFLAG_INTERLACED; res->iScreen = 0; res->bFullScreen = true; -- 2.7.1 From 78720adb37dfca81c3494a24906fa0819fd06085 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 17:33:42 +0100 Subject: [PATCH 048/250] IMX6: 91-imx-repatch.patch Upstream-commit: 3e1b3f37848dafe3441c7b36f7c2bfc640e72f75 --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 91 +++++++++++++++++++++++---------- xbmc/windowing/egl/EGLNativeTypeIMX.h | 4 +- 2 files changed, 66 insertions(+), 29 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 28ea85b..36ea921 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -45,6 +45,8 @@ CEGLNativeTypeIMX::CEGLNativeTypeIMX() , m_display(NULL) , m_window(NULL) { + m_show = true; + m_readonly = true; } CEGLNativeTypeIMX::~CEGLNativeTypeIMX() @@ -129,14 +131,19 @@ void CEGLNativeTypeIMX::Initialize() CLog::Log(LOGERROR, "%s - Error while unblanking fb0.\n", __FUNCTION__); } - close(fd); - m_sar = GetMonitorSAR(); + + // Check if we can change the framebuffer resolution + if (!m_readonly) + GetNativeResolution(&m_init); + + close(fd); return; } void CEGLNativeTypeIMX::Destroy() { + CLog::Log(LOGDEBUG, "%s\n", __FUNCTION__); struct fb_fix_screeninfo fixed_info; void *fb_buffer; int fd; @@ -160,21 +167,26 @@ void CEGLNativeTypeIMX::Destroy() memset(fb_buffer, 0x0, fixed_info.smem_len); munmap(fb_buffer, fixed_info.smem_len); } - close(fd); + SetNativeResolution(m_init); + system("/usr/bin/splash --force -i -m 'stopping xbmc...'"); return; } bool CEGLNativeTypeIMX::CreateNativeDisplay() { + CLog::Log(LOGDEBUG,": %s", __FUNCTION__); +#ifdef HAS_IMXVPU + if (m_display) + return true; + // Force double-buffering CEnvironment::setenv("FB_MULTI_BUFFER", "2", 0); - -#ifdef HAS_IMXVPU // EGL will be rendered on fb0 - m_display = fbGetDisplayByIndex(0); + if (!(m_display = fbGetDisplayByIndex(0))) + return false; m_nativeDisplay = &m_display; return true; #else @@ -184,8 +196,14 @@ bool CEGLNativeTypeIMX::CreateNativeDisplay() bool CEGLNativeTypeIMX::CreateNativeWindow() { + CLog::Log(LOGDEBUG,": %s", __FUNCTION__); #ifdef HAS_IMXVPU - m_window = fbCreateWindow(m_display, 0, 0, 0, 0); + if (m_window) + return true; + + if (!(m_window = fbCreateWindow(m_display, 0, 0, 0, 0))) + return false; + m_nativeWindow = &m_window; return true; #else @@ -195,30 +213,31 @@ bool CEGLNativeTypeIMX::CreateNativeWindow() bool CEGLNativeTypeIMX::GetNativeDisplay(XBNativeDisplayType **nativeDisplay) const { - if (!nativeDisplay) - return false; if (!m_nativeDisplay) return false; + *nativeDisplay = (XBNativeDisplayType*)m_nativeDisplay; return true; } bool CEGLNativeTypeIMX::GetNativeWindow(XBNativeWindowType **nativeWindow) const { - if (!nativeWindow) - return false; - if (!m_nativeWindow || !m_window) + if (!m_nativeWindow) return false; + *nativeWindow = (XBNativeWindowType*)m_nativeWindow; return true; } bool CEGLNativeTypeIMX::DestroyNativeDisplay() { + CLog::Log(LOGDEBUG,": %s", __FUNCTION__); #ifdef HAS_IMXVPU if (m_display) fbDestroyDisplay(m_display); - m_display = NULL; + + m_display = NULL; + m_nativeDisplay = NULL; return true; #else return false; @@ -227,10 +246,13 @@ bool CEGLNativeTypeIMX::DestroyNativeDisplay() bool CEGLNativeTypeIMX::DestroyNativeWindow() { + CLog::Log(LOGDEBUG,": %s", __FUNCTION__); #ifdef HAS_IMXVPU if (m_window) fbDestroyWindow(m_window); - m_window = NULL; + + m_window = NULL; + m_nativeWindow = NULL; return true; #else return false; @@ -241,6 +263,8 @@ bool CEGLNativeTypeIMX::GetNativeResolution(RESOLUTION_INFO *res) const { std::string mode; SysfsUtils::GetString("/sys/class/graphics/fb0/mode", mode); + CLog::Log(LOGDEBUG,": %s, %s", __FUNCTION__, mode.c_str()); + return ModeToResolution(mode, res); } @@ -252,19 +276,20 @@ bool CEGLNativeTypeIMX::SetNativeResolution(const RESOLUTION_INFO &res) std::string mode; SysfsUtils::GetString("/sys/class/graphics/fb0/mode", mode); if (res.strId == mode) - return false; + { + CLog::Log(LOGDEBUG,": %s - not changing res (%s vs %s)", __FUNCTION__, res.strId.c_str(), mode.c_str()); + return true; + } DestroyNativeWindow(); DestroyNativeDisplay(); + ShowWindow(false); + CLog::Log(LOGDEBUG,": %s - changing resolution to %s", __FUNCTION__, res.strId.c_str()); SysfsUtils::SetString("/sys/class/graphics/fb0/mode", res.strId + "\n"); CreateNativeDisplay(); - - CLog::Log(LOGDEBUG, "%s: %s",__FUNCTION__, res.strId.c_str()); - - // Reset AE - CAEFactory::DeviceChange(); + CreateNativeWindow(); return true; } @@ -311,6 +336,7 @@ bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutio if(!FindMatchingResolution(res, resolutions)) resolutions.push_back(res); } + return resolutions.size() > 0; } @@ -321,13 +347,20 @@ bool CEGLNativeTypeIMX::GetPreferredResolution(RESOLUTION_INFO *res) const bool CEGLNativeTypeIMX::ShowWindow(bool show) { - // Force vsync by default - eglSwapInterval(g_Windowing.GetEGLDisplay(), 1); - EGLint result = eglGetError(); - if(result != EGL_SUCCESS) - CLog::Log(LOGERROR, "EGL error in %s: %x",__FUNCTION__, result); + if (m_show == show) + return true; - return false; + CLog::Log(LOGDEBUG, ": %s %s", __FUNCTION__, show?"show":"hide"); + int fd; + if (m_show && (fd = open("/dev/fb0", O_RDWR))) + { + ioctl(fd, FBIO_WAITFORVSYNC, 0); + close(fd); + } + set_sysfs_str("/sys/class/graphics/fb0/blank", show?"0":"1"); + + m_show = show; + return true; } float CEGLNativeTypeIMX::GetMonitorSAR() @@ -406,8 +439,11 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) std::string fromMode = StringUtils::Mid(mode, 2); StringUtils::Trim(fromMode); + res->dwFlags = 0; + res->fPixelRatio = 1.0f; + if (StringUtils::StartsWith(mode, "U:")) - res->dwFlags = D3DPRESENTFLAG_WIDESCREEN; + res->dwFlags |= D3DPRESENTFLAG_WIDESCREEN; CRegExp split(true); split.RegComp("([0-9]+)x([0-9]+)([pi])-([0-9]+)"); @@ -437,4 +473,3 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) return res->iWidth > 0 && res->iHeight> 0; } - diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.h b/xbmc/windowing/egl/EGLNativeTypeIMX.h index ca738e3..a7b018e 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.h +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.h @@ -50,14 +50,16 @@ public: virtual bool ProbeResolutions(std::vector &resolutions); virtual bool GetPreferredResolution(RESOLUTION_INFO *res) const; - virtual bool ShowWindow(bool show); + virtual bool ShowWindow(bool show = true); protected: bool m_readonly; + bool m_show; float m_sar; bool ModeToResolution(std::string mode, RESOLUTION_INFO *res) const; bool FindMatchingResolution(const RESOLUTION_INFO &res, const std::vector &resolutions); float GetMonitorSAR(); + RESOLUTION_INFO m_init; EGLNativeDisplayType m_display; EGLNativeWindowType m_window; -- 2.7.1 From 16689b8c3a304db6110a0480de6a2e31248c7520 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 17:43:09 +0100 Subject: [PATCH 049/250] IMX6: add 3D support (currently SBS and TaB) Upstream-commit: 37094835dbe14a2a5689c315d0018f9140f4b55e --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 36ea921..17d7aad 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -329,7 +329,7 @@ bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutio for (size_t i = 0; i < probe_str.size(); i++) { if(!StringUtils::StartsWith(probe_str[i], "S:") && !StringUtils::StartsWith(probe_str[i], "U:") && - !StringUtils::StartsWith(probe_str[i], "V:")) + !StringUtils::StartsWith(probe_str[i], "H:") && !StringUtils::StartsWith(probe_str[i], "T:")) continue; if(ModeToResolution(probe_str[i], &res)) @@ -442,8 +442,17 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->dwFlags = 0; res->fPixelRatio = 1.0f; - if (StringUtils::StartsWith(mode, "U:")) + if (StringUtils::StartsWith(mode, "U:")) { res->dwFlags |= D3DPRESENTFLAG_WIDESCREEN; + } else if (StringUtils::StartsWith(mode, "H:")) { + res->dwFlags |= D3DPRESENTFLAG_MODE3DSBS; + res->fPixelRatio = 2.0f; + } else if (StringUtils::StartsWith(mode, "T:")) { + res->dwFlags |= D3DPRESENTFLAG_MODE3DTB; + res->fPixelRatio = 0.5f; + } else if (StringUtils::StartsWith(mode, "F:")) { + return false; + } CRegExp split(true); split.RegComp("([0-9]+)x([0-9]+)([pi])-([0-9]+)"); @@ -466,9 +475,11 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->bFullScreen = true; res->iSubtitles = (int)(0.965 * res->iHeight); - res->fPixelRatio = !m_sar ? 1.0f : (float)m_sar / res->iScreenWidth * res->iScreenHeight; - res->strMode = StringUtils::Format("%dx%d @ %.2f%s - Full Screen", res->iScreenWidth, res->iScreenHeight, res->fRefreshRate, - res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : ""); + res->fPixelRatio *= !m_sar ? 1.0f : (float)m_sar / res->iScreenWidth * res->iScreenHeight; + res->strMode = StringUtils::Format("%4sx%4s @ %.2f%s - Full Screen (%.3f) %s", StringUtils::Format("%d", res->iScreenWidth).c_str(), + StringUtils::Format("%d", res->iScreenHeight).c_str(), res->fRefreshRate, + res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : " ", res->fPixelRatio, + res->dwFlags & D3DPRESENTFLAG_MODE3DSBS ? "- 3DSBS" : res->dwFlags & D3DPRESENTFLAG_MODE3DTB ? "- 3DTB" : ""); res->strId = mode; return res->iWidth > 0 && res->iHeight> 0; -- 2.7.1 From bcf90b14944fed60b375e1a9aa165069b2a71999 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 23:29:36 +0100 Subject: [PATCH 050/250] IMX6: Makes VT changing possible while XBMC running (even playing some content. Change of VT can be triggered by standard Ctrl+Alt+Fx combination. Upstream-commit: 67028fb49e057cbbefef27d3d6535e78612bacf6 Other VTs can be used freely, XWindow system can be started too. (Ctrl+Alt+Fx (or Alt+Fx on text consoles) can be used again to jump back and forth). --- xbmc/Application.cpp | 85 +++++++++++++++++++++++++++++ xbmc/Application.h | 5 ++ xbmc/input/linux/LinuxInputDevices.cpp | 11 ++++ xbmc/input/linux/LinuxInputDevices.h | 1 + xbmc/interfaces/builtins/SystemBuiltins.cpp | 10 +++- xbmc/messaging/ApplicationMessenger.h | 2 + xbmc/windowing/WinEvents.cpp | 19 +++++++ xbmc/windowing/WinEvents.h | 1 + xbmc/windowing/WinEventsLinux.cpp | 5 ++ xbmc/windowing/WinEventsLinux.h | 1 + xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 2 + 11 files changed, 141 insertions(+), 1 deletion(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 5c57820..845ba6d 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -29,6 +29,8 @@ #include "utils/Splash.h" #include "LangInfo.h" #include "utils/Screenshot.h" +#include +#include #include "Util.h" #include "URL.h" #include "guilib/TextureManager.h" @@ -95,6 +97,7 @@ #include "utils/CPUInfo.h" #include "utils/SeekHandler.h" +#include "video/VideoReferenceClock.h" #include "input/KeyboardLayoutManager.h" #if HAVE_SDL_VERSION == 1 @@ -220,6 +223,10 @@ #include "utils/AMLUtils.h" #endif +#ifdef HAS_IMXVPU +#include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h" +#endif + #include "cores/FFmpeg.h" #include "utils/CharsetConverter.h" #include "pictures/GUIWindowSlideShow.h" @@ -285,6 +292,7 @@ CApplication::CApplication(void) m_skinReverting = false; m_cecStandby = false; m_res.strMode = ""; + m_ourVT = -1; #ifdef HAS_GLX XInitThreads(); @@ -1220,6 +1228,7 @@ bool CApplication::Initialize() } m_slowTimer.StartZero(); + m_slowTimerVT.StartZero(); CAddonMgr::GetInstance().StartServices(true); @@ -2567,6 +2576,10 @@ void CApplication::OnApplicationMessage(ThreadMessage* pMsg) #endif break; + case TMSG_CHANGEVT: + g_application.ChangeVT((int)pMsg->param1); + break; + case TMSG_INHIBITIDLESHUTDOWN: InhibitIdleShutdown(pMsg->param1 != 0); break; @@ -4530,6 +4543,72 @@ void CApplication::ShowAppMigrationMessage() } } +void CApplication::ChangeVT(int newVT) +{ + std::string cmd = StringUtils::Format("sudo /sbin/start xbian-chvt TTYNR=%d", newVT); + CLog::Log(LOGINFO,"%s : activating tty%d", __FUNCTION__, newVT); + system(cmd.c_str()); +} + +void CApplication::checkVTchange() +{ + struct vt_stat vts; + static int last_active; + static bool bRestartClock; + + int cur_tty = open("/dev/tty0", O_RDONLY | O_NONBLOCK | O_NOCTTY); + if(cur_tty < 0 || ioctl(cur_tty, VT_GETSTATE, &vts) < 0) + goto out; + + if (last_active != vts.v_active && m_ourVT >= 0) + { + // We are back home + if (m_ourVT == vts.v_active) + { + CLog::Log(LOGDEBUG,"%s : our VT active again", __func__); + CWinEvents::Stop(false); +#ifdef HAS_IMXVPU + g_IMXContext.Unblank(); +#endif + SetRenderGUI(true); + g_graphicsContext.SetFullScreenVideo(g_graphicsContext.IsFullScreenVideo()); + if (bRestartClock) + { + bRestartClock = false; + g_VideoReferenceClock.Start(); + } + } + else + { + CLog::Log(LOGDEBUG,"%s : our VT being deactivated", __func__); + SetRenderGUI(false); +#ifdef HAS_IMXVPU + g_IMXContext.Blank(); +#endif + if (g_VideoReferenceClock.IsRunning()) + { + bRestartClock = true; + g_VideoReferenceClock.Stop(); + } + + { + CSingleLock lock(g_graphicsContext); + g_graphicsContext.Clear(0); + g_windowManager.Render(); + } + CWinEvents::Stop(true); + } + } + else if (m_ourVT < 0) + m_ourVT = vts.v_active; + + last_active = vts.v_active; + +out: + if (cur_tty > -1) + close(cur_tty); +} + void CApplication::Process() { MEASURE_FUNCTION; @@ -4568,6 +4647,12 @@ void CApplication::Process() // update sound m_pPlayer->DoAudioWork(); + if( m_slowTimerVT.GetElapsedMilliseconds() > 100) + { + m_slowTimerVT.Reset(); + checkVTchange(); + } + // do any processing that isn't needed on each run if( m_slowTimer.GetElapsedMilliseconds() > 500 ) { diff --git a/xbmc/Application.h b/xbmc/Application.h index f5df4a3..3e53b8d 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h @@ -397,6 +397,7 @@ public: bool ScreenSaverDisablesAutoScrolling(); void SetCecStandby(bool status); bool GetCecStandby() { return m_cecStandby; } + void ChangeVT(int newVT); protected: virtual bool OnSettingsSaving() const override; @@ -426,6 +427,9 @@ protected: bool m_cecStandby; + int m_ourVT; + void checkVTchange(); + #if defined(TARGET_DARWIN_IOS) friend class CWinEventsIOS; #endif @@ -448,6 +452,7 @@ protected: CStopWatch m_frameTime; CStopWatch m_navigationTimer; CStopWatch m_slowTimer; + CStopWatch m_slowTimerVT; CStopWatch m_shutdownTimer; bool m_bInhibitIdleShutdown; diff --git a/xbmc/input/linux/LinuxInputDevices.cpp b/xbmc/input/linux/LinuxInputDevices.cpp index 73f338f..0cbfa83 100644 --- a/xbmc/input/linux/LinuxInputDevices.cpp +++ b/xbmc/input/linux/LinuxInputDevices.cpp @@ -1142,6 +1142,17 @@ void CLinuxInputDevices::InitAvailable() } } +void CLinuxInputDevices::Close() +{ + CSingleLock lock(m_devicesListLock); + + for (size_t i = 0; i < m_devices.size(); i++) + { + delete m_devices[i]; + } + m_devices.clear(); +} + /* * Check for hot plugged devices. */ diff --git a/xbmc/input/linux/LinuxInputDevices.h b/xbmc/input/linux/LinuxInputDevices.h index 8c88a1d..d957956 100644 --- a/xbmc/input/linux/LinuxInputDevices.h +++ b/xbmc/input/linux/LinuxInputDevices.h @@ -95,6 +95,7 @@ class CLinuxInputDevices { public: void InitAvailable(); + void Close(); void CheckHotplugged(); XBMC_Event ReadEvent(); bool IsRemoteLowBattery(); diff --git a/xbmc/interfaces/builtins/SystemBuiltins.cpp b/xbmc/interfaces/builtins/SystemBuiltins.cpp index 961c6bb..7ebb67a 100644 --- a/xbmc/interfaces/builtins/SystemBuiltins.cpp +++ b/xbmc/interfaces/builtins/SystemBuiltins.cpp @@ -142,6 +142,13 @@ static int Suspend(const std::vector& params) return 0; } +static int ChangeVT(const std::vector& params) +{ + CApplicationMessenger::GetInstance().PostMsg(TMSG_CHANGEVT, atoi(params[0].c_str())); + + return 0; +} + CBuiltins::CommandMap CSystemBuiltins::GetOperations() const { return { @@ -158,6 +165,7 @@ CBuiltins::CommandMap CSystemBuiltins::GetOperations() const {"shutdown", {"Shutdown the system", 0, Shutdown}}, {"suspend", {"Suspends the system", 0, Suspend}}, {"system.exec", {"Execute shell commands", 1, Exec<0>}}, - {"system.execwait", {"Execute shell commands and freezes Kodi until shell is closed", 1, Exec<1>}} + {"system.execwait", {"Execute shell commands and freezes Kodi until shell is closed", 1, Exec<1>}}, + {"changevt", {"Change active VT", 1, ChangeVT}} }; } diff --git a/xbmc/messaging/ApplicationMessenger.h b/xbmc/messaging/ApplicationMessenger.h index b54b1c8..8fcb70d 100644 --- a/xbmc/messaging/ApplicationMessenger.h +++ b/xbmc/messaging/ApplicationMessenger.h @@ -90,6 +90,8 @@ #define TMSG_LOADPROFILE TMSG_MASK_APPLICATION + 27 #define TMSG_VIDEORESIZE TMSG_MASK_APPLICATION + 28 #define TMSG_SETAUDIODSPSTATE TMSG_MASK_APPLICATION + 29 +#define TMSG_CHANGEVT TMSG_MASK_APPLICATION + 30 + #define TMSG_GUI_INFOLABEL TMSG_MASK_GUIINFOMANAGER + 0 #define TMSG_GUI_INFOBOOL TMSG_MASK_GUIINFOMANAGER + 1 diff --git a/xbmc/windowing/WinEvents.cpp b/xbmc/windowing/WinEvents.cpp index 22fe2bc..9f9a561 100644 --- a/xbmc/windowing/WinEvents.cpp +++ b/xbmc/windowing/WinEvents.cpp @@ -58,6 +58,7 @@ static WinEventsType g_imp; static CCriticalSection g_lock; static bool g_init = false; +static bool g_suspend = false; void Init() { @@ -69,8 +70,23 @@ void Init() } } +void CWinEvents::Stop(bool suspend) +{ + CSingleLock lock(g_lock); + + if (suspend == g_suspend) + return; + + g_suspend = suspend; + if (suspend) + g_imp.CloseDevices(); +} + void CWinEvents::MessagePush(XBMC_Event* ev) { + if (g_suspend) + return; + if (!g_init) Init(); g_imp.MessagePush(ev); @@ -78,6 +94,9 @@ void CWinEvents::MessagePush(XBMC_Event* ev) bool CWinEvents::MessagePump() { + if (g_suspend) + return false; + if (!g_init) Init(); return g_imp.MessagePump(); diff --git a/xbmc/windowing/WinEvents.h b/xbmc/windowing/WinEvents.h index e04631f..0902183 100644 --- a/xbmc/windowing/WinEvents.h +++ b/xbmc/windowing/WinEvents.h @@ -43,6 +43,7 @@ class CWinEvents static void MessagePush(XBMC_Event* ev); static bool MessagePump(); static size_t GetQueueSize(); + static void Stop(bool suspend); }; #endif // WINDOW_EVENTS_H diff --git a/xbmc/windowing/WinEventsLinux.cpp b/xbmc/windowing/WinEventsLinux.cpp index aaba119..2c0bad2 100644 --- a/xbmc/windowing/WinEventsLinux.cpp +++ b/xbmc/windowing/WinEventsLinux.cpp @@ -42,6 +42,11 @@ void CWinEventsLinux::RefreshDevices() m_devices.InitAvailable(); } +void CWinEventsLinux::CloseDevices() +{ + m_devices.Close(); +} + bool CWinEventsLinux::IsRemoteLowBattery() { return m_devices.IsRemoteLowBattery(); diff --git a/xbmc/windowing/WinEventsLinux.h b/xbmc/windowing/WinEventsLinux.h index a17e987..012342e 100644 --- a/xbmc/windowing/WinEventsLinux.h +++ b/xbmc/windowing/WinEventsLinux.h @@ -33,6 +33,7 @@ public: size_t GetQueueSize(); void MessagePush(XBMC_Event *ev); void RefreshDevices(); + void CloseDevices(); void Notify(const Observable &obs, const ObservableMessage msg) { if (msg == ObservableMessagePeripheralsChanged) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 17d7aad..a0b1e62 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -23,6 +23,7 @@ #include "system.h" #include +#include "Application.h" #include "EGLNativeTypeIMX.h" #include #include @@ -270,6 +271,7 @@ bool CEGLNativeTypeIMX::GetNativeResolution(RESOLUTION_INFO *res) const bool CEGLNativeTypeIMX::SetNativeResolution(const RESOLUTION_INFO &res) { +#ifdef HAS_IMXVPU if (m_readonly) return false; -- 2.7.1 From 50d58c560fca42a036b125963c499f390b6cb1b2 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 28 Mar 2015 23:30:03 +0100 Subject: [PATCH 051/250] Add CEC IMX adapter as known type and set no polling. - that eliminates extensive periodic /sys walkthrough Upstream-commit: f7ba60b4e94091a007fd656bc0084b600a12eb17 --- xbmc/peripherals/PeripheralTypes.h | 5 +++++ xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/xbmc/peripherals/PeripheralTypes.h b/xbmc/peripherals/PeripheralTypes.h index 699e1b2..aa1f491 100644 --- a/xbmc/peripherals/PeripheralTypes.h +++ b/xbmc/peripherals/PeripheralTypes.h @@ -38,6 +38,7 @@ namespace PERIPHERALS PERIPHERAL_BUS_USB, PERIPHERAL_BUS_PCI, PERIPHERAL_BUS_RPI, + PERIPHERAL_BUS_IMX, PERIPHERAL_BUS_CEC }; @@ -152,6 +153,8 @@ namespace PERIPHERALS return "pci"; case PERIPHERAL_BUS_RPI: return "rpi"; + case PERIPHERAL_BUS_IMX: + return "imx"; case PERIPHERAL_BUS_CEC: return "cec"; default: @@ -170,6 +173,8 @@ namespace PERIPHERALS return PERIPHERAL_BUS_PCI; else if (strTypeLowerCase == "rpi") return PERIPHERAL_BUS_RPI; + else if (strTypeLowerCase == "imx") + return PERIPHERAL_BUS_IMX; else if (strTypeLowerCase == "cec") return PERIPHERAL_BUS_CEC; diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp index b04fe00..3dc3d0e 100644 --- a/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp +++ b/xbmc/peripherals/bus/virtual/PeripheralBusCEC.cpp @@ -102,6 +102,10 @@ bool CPeripheralBusCEC::PerformDeviceScan(PeripheralScanResults &results) /** the Pi's adapter cannot be removed, no need to rescan */ m_bNeedsPolling = false; break; + case ADAPTERTYPE_IMX: + result.m_mappedBusType = PERIPHERAL_BUS_IMX; + m_bNeedsPolling = false; + break; default: break; } -- 2.7.1 From f7b630cbefc0c5ffcb1b6ee99a47a0a826df9201 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 22 Apr 2015 10:23:40 +0200 Subject: [PATCH 052/250] Update to imx6 EGL - use EDID to get screen AR Upstream-commit: 242c009c884ed307cadf09f541d725fbc4783ba9 --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 11 ++--------- xbmc/windowing/egl/EGLNativeTypeIMX.h | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index a0b1e62..0ad9ff5 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -126,18 +126,11 @@ void CEGLNativeTypeIMX::Initialize() if (ioctl(fd, MXCFB_SET_CLR_KEY, &colorKey) < 0) CLog::Log(LOGERROR, "%s - Failed to setup color keying\n", __FUNCTION__); #endif - // Unblank the fb - if (ioctl(fd, FBIOBLANK, 0) < 0) - { - CLog::Log(LOGERROR, "%s - Error while unblanking fb0.\n", __FUNCTION__); - } - - m_sar = GetMonitorSAR(); - // Check if we can change the framebuffer resolution if (!m_readonly) GetNativeResolution(&m_init); + m_sar = GetMonitorSAR(); close(fd); return; } @@ -331,6 +324,7 @@ bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutio for (size_t i = 0; i < probe_str.size(); i++) { if(!StringUtils::StartsWith(probe_str[i], "S:") && !StringUtils::StartsWith(probe_str[i], "U:") && + !StringUtils::StartsWith(probe_str[i], "V:") && !StringUtils::StartsWith(probe_str[i], "H:") && !StringUtils::StartsWith(probe_str[i], "T:")) continue; @@ -338,7 +332,6 @@ bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutio if(!FindMatchingResolution(res, resolutions)) resolutions.push_back(res); } - return resolutions.size() > 0; } diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.h b/xbmc/windowing/egl/EGLNativeTypeIMX.h index a7b018e..1628954 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.h +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.h @@ -56,10 +56,10 @@ protected: bool m_readonly; bool m_show; float m_sar; + RESOLUTION_INFO m_init; bool ModeToResolution(std::string mode, RESOLUTION_INFO *res) const; bool FindMatchingResolution(const RESOLUTION_INFO &res, const std::vector &resolutions); float GetMonitorSAR(); - RESOLUTION_INFO m_init; EGLNativeDisplayType m_display; EGLNativeWindowType m_window; -- 2.7.1 From 8f91dd2efffc06ad862e813bf2f45e966c72deaa Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 28 Mar 2015 23:21:04 +0100 Subject: [PATCH 053/250] - Receive HDMI connection changes through new bus type. - Removed swapping actual resolution(non desktop) with RES_DESKTOP. - This should be last commit from the series around resolution handling whose are introducing dynamic resolution list (res. list can be updated during XBMC run - as result of different display device reattach, usage of passive CEC switches - which do not have HDMI/EDID signal passthrough when powered off). XBMC will also auto adapt the output resolution to match previous (or find as close as possible). - Change format of report of found resolutions Upstream-commit: a00cfb2606c387cb10b9d4131e7116d3d8f3c418 --- .../resource.language.en_gb/resources/strings.po | 25 +++- system/peripherals.xml | 5 + system/settings/settings.xml | 7 ++ xbmc/Application.cpp | 1 + xbmc/peripherals/PeripheralTypes.h | 25 +++- xbmc/peripherals/Peripherals.cpp | 25 ++++ xbmc/peripherals/Peripherals.h | 2 + xbmc/peripherals/bus/Makefile.in | 1 + xbmc/peripherals/bus/PeripheralBus.cpp | 16 +++ xbmc/peripherals/bus/PeripheralBus.h | 3 + .../bus/linux/PeripheralBusPLATFORMLibUdev.cpp | 139 +++++++++++++++++++++ .../bus/linux/PeripheralBusPLATFORMLibUdev.h | 47 +++++++ .../bus/linux/PeripheralBusUSBLibUdev.cpp | 12 +- .../bus/linux/PeripheralBusUSBLibUdev.h | 2 +- xbmc/peripherals/devices/Makefile.in | 1 + xbmc/peripherals/devices/Peripheral.h | 12 ++ xbmc/peripherals/devices/PeripheralVideo.cpp | 88 +++++++++++++ xbmc/peripherals/devices/PeripheralVideo.h | 46 +++++++ xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 6 + xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 28 +++++ xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h | 4 + xbmc/windowing/egl/WinSystemEGL.cpp | 29 ++--- 22 files changed, 494 insertions(+), 30 deletions(-) create mode 100644 xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp create mode 100644 xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h create mode 100644 xbmc/peripherals/devices/PeripheralVideo.cpp create mode 100644 xbmc/peripherals/devices/PeripheralVideo.h diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index ff65ede..478564f 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -5940,7 +5940,12 @@ msgctxt "#13287" msgid "Screen resolution:" msgstr "" -#empty strings from id 13288 to 13291 +#: peripheral/devices/PeripheralVideo.cpp +msgctxt "#13288" +msgid "Probing available resolutions" +msgstr "Probing available resolutions" + +#empty strings from id 13289 to 13291 msgctxt "#13292" msgid "A/V cable:" @@ -18119,3 +18124,21 @@ msgstr "" msgctxt "#38023" msgid "Set my rating" msgstr "" + +#. Label of setting "System -> Video output -> Refresh resolutions" +#: system/settings/settings.xml +msgctxt "#40000" +msgid "Update available resolutions on Display device changes" +msgstr "" + +#. Description of setting "System -> Video output -> Refresh resolutions" +#: system/settings/settings.xml +msgctxt "#40001" +msgid "Available resolutions will be updated on HDMI hotplug events. Currently active resolution will be matched agains new mode list. If new mode list doesn't provide same mode, closest mode will be used and changed to" +msgstr "" + +#. Label of "System -> Input devices -> HDMI Video -> Enable hotplug events be passed to Kodi" +#: system/peripherals.xml +msgctxt "#40002" +msgid "Detect hotplug events" +msgstr "" diff --git a/system/peripherals.xml b/system/peripherals.xml index ec3c3fe..1a31659 100644 --- a/system/peripherals.xml +++ b/system/peripherals.xml @@ -44,4 +44,9 @@ + + + + + diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 62a4f68..41bafb3 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -2474,6 +2474,13 @@ + + + 2 + true + + + diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 845ba6d..13e7056 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -767,6 +767,7 @@ bool CApplication::CreateGUI(bool showXBMCSplash) // Initialize core peripheral port support. Note: If these parameters // are 0 and NULL, respectively, then the default number and types of // controllers will be initialized. + CDisplaySettings::Get().SetCurrentResolution((RESOLUTION)CSettings::Get().GetInt("videoscreen.resolution")); if (!g_Windowing.InitWindowSystem()) { CLog::Log(LOGFATAL, "CApplication::Create: Unable to init windowing system"); diff --git a/xbmc/peripherals/PeripheralTypes.h b/xbmc/peripherals/PeripheralTypes.h index aa1f491..d45153a 100644 --- a/xbmc/peripherals/PeripheralTypes.h +++ b/xbmc/peripherals/PeripheralTypes.h @@ -39,7 +39,8 @@ namespace PERIPHERALS PERIPHERAL_BUS_PCI, PERIPHERAL_BUS_RPI, PERIPHERAL_BUS_IMX, - PERIPHERAL_BUS_CEC + PERIPHERAL_BUS_CEC, + PERIPHERAL_BUS_PLATFORM }; enum PeripheralFeature @@ -52,7 +53,8 @@ namespace PERIPHERALS FEATURE_CEC, FEATURE_BLUETOOTH, FEATURE_TUNER, - FEATURE_IMON + FEATURE_IMON, + FEATURE_CABLESTATE }; enum PeripheralType @@ -65,7 +67,8 @@ namespace PERIPHERALS PERIPHERAL_CEC, PERIPHERAL_BLUETOOTH, PERIPHERAL_TUNER, - PERIPHERAL_IMON + PERIPHERAL_IMON, + PERIPHERAL_VIDEO }; struct PeripheralID @@ -113,6 +116,8 @@ namespace PERIPHERALS return "tuner"; case PERIPHERAL_IMON: return "imon"; + case PERIPHERAL_VIDEO: + return "video"; default: return "unknown"; } @@ -139,6 +144,8 @@ namespace PERIPHERALS return PERIPHERAL_TUNER; else if (strTypeLowerCase == "imon") return PERIPHERAL_IMON; + else if (strTypeLowerCase.Equals("video")) + return PERIPHERAL_VIDEO; return PERIPHERAL_UNKNOWN; }; @@ -157,6 +164,8 @@ namespace PERIPHERALS return "imx"; case PERIPHERAL_BUS_CEC: return "cec"; + case PERIPHERAL_BUS_PLATFORM: + return "platform"; default: return "unknown"; } @@ -177,6 +186,8 @@ namespace PERIPHERALS return PERIPHERAL_BUS_IMX; else if (strTypeLowerCase == "cec") return PERIPHERAL_BUS_CEC; + else if (strTypeLowerCase.Equals("platform")) + return PERIPHERAL_BUS_PLATFORM; return PERIPHERAL_BUS_UNKNOWN; }; @@ -197,6 +208,14 @@ namespace PERIPHERALS strHexString = StringUtils::Format("%04X", iVal); }; + + static void UeventToName(CStdString &uevent, CStdString &name) + { + std::vector data = StringUtils::Split(uevent, "\n"); + for (size_t i = 0; i < data.size(); i++) + if (StringUtils::StartsWith(data[i], "OF_NAME=")) + name = data[i].substr(8, data[i].length()); + } }; class PeripheralScanResult diff --git a/xbmc/peripherals/Peripherals.cpp b/xbmc/peripherals/Peripherals.cpp index d7d275e..f736c5b 100644 --- a/xbmc/peripherals/Peripherals.cpp +++ b/xbmc/peripherals/Peripherals.cpp @@ -295,6 +295,10 @@ CPeripheral *CPeripherals::CreatePeripheral(CPeripheralBus &bus, const Periphera peripheral = new CPeripheralImon(mappedResult); break; + case PERIPHERAL_VIDEO: + peripheral = new CPeripheralVideo(mappedResult); + break; + default: break; } @@ -787,3 +791,24 @@ int CPeripherals::GetMessageMask() { return TMSG_MASK_PERIPHERALS; } + +CPeripheralBus *CPeripherals::CreatePeripheralBus(CPeripheralBus *bus) +{ + CPeripheralBus *pbus = GetBusByType(bus->Type()); + if (!pbus) + { + m_busses.push_back(bus); + if (!bus->Initialise()) + { + CLog::Log(LOGERROR, "%s - failed to initialise bus %s", __FUNCTION__, PeripheralTypeTranslator::BusTypeToString(bus->Type())); + delete bus; + m_busses.erase(m_busses.end()); + } + else + pbus = bus; + } + else + delete bus; + + return pbus; +} diff --git a/xbmc/peripherals/Peripherals.h b/xbmc/peripherals/Peripherals.h index 39c9f17..d9bcd4b 100644 --- a/xbmc/peripherals/Peripherals.h +++ b/xbmc/peripherals/Peripherals.h @@ -200,6 +200,8 @@ namespace PERIPHERALS */ virtual bool GetNextKeypress(float frameTime, CKey &key); + virtual CPeripheralBus *CreatePeripheralBus(CPeripheralBus *bus); + bool SupportsCEC(void) const { #if defined(HAVE_LIBCEC) diff --git a/xbmc/peripherals/bus/Makefile.in b/xbmc/peripherals/bus/Makefile.in index 2262e4a..cbda47d 100644 --- a/xbmc/peripherals/bus/Makefile.in +++ b/xbmc/peripherals/bus/Makefile.in @@ -2,6 +2,7 @@ SRCS = PeripheralBus.cpp ifeq (@USE_LIBUDEV@,1) SRCS += linux/PeripheralBusUSBLibUdev.cpp +SRCS += linux/PeripheralBusPLATFORMLibUdev.cpp endif ifeq (@USE_LIBUSB@,1) diff --git a/xbmc/peripherals/bus/PeripheralBus.cpp b/xbmc/peripherals/bus/PeripheralBus.cpp index 19754a7..2b04702 100644 --- a/xbmc/peripherals/bus/PeripheralBus.cpp +++ b/xbmc/peripherals/bus/PeripheralBus.cpp @@ -118,6 +118,15 @@ void CPeripheralBus::RegisterNewDevices(const PeripheralScanResults &results) } } +CPeripheral *CPeripheralBus::RegisterNewDevice(const PeripheralScanResult &result) +{ + CSingleLock lock(m_critSection); + if (!HasPeripheral(result.m_strLocation)) + return g_peripherals.CreatePeripheral(*this, result); + else + return GetPeripheral(result.m_strLocation); +} + bool CPeripheralBus::ScanForDevices(void) { bool bReturn(false); @@ -204,6 +213,13 @@ size_t CPeripheralBus::GetNumberOfPeripheralsWithId(const int iVendorId, const i return iReturn; } +size_t CPeripheralBus::GetNumberOfPeripheralsWithFeature(const PeripheralFeature feature) const +{ + vector peripherals; + GetPeripheralsWithFeature(peripherals, feature); + return peripherals.size(); +} + void CPeripheralBus::Process(void) { while (!m_bStop) diff --git a/xbmc/peripherals/bus/PeripheralBus.h b/xbmc/peripherals/bus/PeripheralBus.h index 6dff42c..b75a394 100644 --- a/xbmc/peripherals/bus/PeripheralBus.h +++ b/xbmc/peripherals/bus/PeripheralBus.h @@ -78,6 +78,7 @@ namespace PERIPHERALS virtual size_t GetNumberOfPeripherals() const; virtual size_t GetNumberOfPeripheralsWithId(const int iVendorId, const int iProductId) const; + virtual size_t GetNumberOfPeripheralsWithFeature(const PeripheralFeature feature) const; /*! * @brief Get all features that are supported by devices on this bus. @@ -149,6 +150,8 @@ namespace PERIPHERALS virtual bool IsInitialised(void) const { return m_bInitialised; } + virtual CPeripheral *RegisterNewDevice(const PeripheralScanResult &result); + protected: virtual void Process(void); virtual bool ScanForDevices(void); diff --git a/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp b/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp new file mode 100644 index 0000000..5f227bf --- /dev/null +++ b/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp @@ -0,0 +1,139 @@ +/* + + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "PeripheralBusPLATFORMLibUdev.h" +#include "peripherals/Peripherals.h" +extern "C" { +#include +} +#include +#include "utils/log.h" + +using namespace PERIPHERALS; + +CPeripheralBusPLATFORM::CPeripheralBusPLATFORM(CPeripherals *manager, const CStdString &threadname, PeripheralBusType type) : + CPeripheralBusUSB(manager, "PeripBusPLATFORMUdev", type) +{ + udev_monitor_filter_add_match_subsystem_devtype(m_udevMon, "platform", NULL); + udev_monitor_filter_update(m_udevMon); +} + +void CPeripheralBusPLATFORM::Clear(void) +{ + StopThread(false); +} + +bool CPeripheralBusPLATFORM::PerformDeviceScan(PeripheralScanResults &results) +{ + struct udev_enumerate *enumerate; + struct udev_list_entry *devices, *dev_list_entry; + struct udev_device *dev(NULL); + enumerate = udev_enumerate_new(m_udev); + udev_enumerate_scan_devices(enumerate); + devices = udev_enumerate_get_list_entry(enumerate); + + bool bContinue(true); + CStdString strPath, t; + udev_list_entry_foreach(dev_list_entry, devices) + { + strPath = udev_list_entry_get_name(dev_list_entry); + dev = udev_device_new_from_syspath(m_udev, strPath); + if (!strPath || !dev) + bContinue = false; + + if (bContinue) + { + bContinue = false; + if (GetCableState(udev_device_get_syspath(dev))) + bContinue = true; + } + + if (bContinue) + { + PeripheralScanResult result(m_type); + result.m_strLocation = udev_device_get_syspath(dev); + result.m_iSequence = GetNumberOfPeripheralsWithFeature(FEATURE_CABLESTATE); + result.m_type = PERIPHERAL_VIDEO; + + t = udev_device_get_sysattr_value(dev, "uevent"); + PeripheralTypeTranslator::UeventToName(t, result.m_strDeviceName); + if (result.m_strDeviceName.empty()) + result.m_strDeviceName += "generic_video"; + + result.m_iVendorId = 0; + result.m_iProductId = 0; + + if (!results.ContainsResult(result)) + results.m_results.push_back(result); + } + + bContinue = true; + } + /* Free the enumerator object */ + udev_enumerate_unref(enumerate); + + return true; +} + +int CPeripheralBusPLATFORM::GetCableState(const CStdString &strLocation) +{ + struct udev_device *dev = udev_device_new_from_syspath(m_udev, strLocation); + std::string files[] = { "cable_state", "status", "state" }; + std::vector cableState(files, files + 3); + + CStdString t; + int state = CABLE_UNKNOWN; + + if (!dev) + return state; + + for (std::vector::iterator f = cableState.begin() ; f != cableState.end(); ++f) + { + if (udev_device_get_sysattr_value(dev, f->c_str())) + t = udev_device_get_sysattr_value(dev, f->c_str()); + + if (!t.empty() && (t.find("connected") != std::string::npos || t.find("plugout") != std::string::npos)) + state = CABLE_DISCONNECTED; + if (!t.empty() && (t.find("disconnected") != std::string::npos || t.find("plugin") != std::string::npos)) + state = CABLE_CONNECTED; + + if (state) + break; + } + + return state; +} + +void CPeripheralBusPLATFORM::Process(void) +{ + while (!m_bStop) + WaitForUpdate(); + + m_bIsStarted = false; +} + +void CPeripheralBusPLATFORM::OnDeviceChanged(const CStdString &strLocation) +{ + CSingleLock lock(m_critSection); + CPeripheral *peripheral = GetPeripheral(strLocation); + if (peripheral) + peripheral->OnDeviceChanged(GetCableState(strLocation)); +} diff --git a/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h b/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h new file mode 100644 index 0000000..4d4a74c --- /dev/null +++ b/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h @@ -0,0 +1,47 @@ +#pragma once +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "peripherals/bus/linux/PeripheralBusUSBLibUdev.h" + +struct udev_device; + +namespace PERIPHERALS +{ + class CPeripherals; + + class CPeripheralBusPLATFORM : public CPeripheralBusUSB + { + public: + CPeripheralBusPLATFORM(CPeripherals *manager, const CStdString &threadname = "PeripBusPLATFORMUdev", PeripheralBusType type = PERIPHERAL_BUS_PLATFORM); + virtual ~CPeripheralBusPLATFORM(void) {}; + + virtual void Clear(void); + + bool PerformDeviceScan(PeripheralScanResults &results); + + virtual void OnDeviceChanged(const CStdString &strLocation); + virtual void OnDeviceAdded(const CStdString &strLocation) {}; + int GetCableState(const CStdString &strLocation); + + protected: + virtual void Process(void); + }; +} diff --git a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp index 85da382..bb5f490 100644 --- a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp +++ b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp @@ -76,8 +76,8 @@ extern "C" { using namespace PERIPHERALS; -CPeripheralBusUSB::CPeripheralBusUSB(CPeripherals *manager) : - CPeripheralBus("PeripBusUSBUdev", manager, PERIPHERAL_BUS_USB) +CPeripheralBusUSB::CPeripheralBusUSB(CPeripherals *manager, const CStdString &threadname, PeripheralBusType type) : + CPeripheralBus(threadname, manager, type) { /* the Process() method in this class overrides the one in CPeripheralBus, so leave this set to true */ m_bNeedsPolling = true; @@ -95,12 +95,13 @@ CPeripheralBusUSB::CPeripheralBusUSB(CPeripherals *manager) : m_udevMon = udev_monitor_new_from_netlink(m_udev, "udev"); udev_monitor_enable_receiving(m_udevMon); - CLog::Log(LOGDEBUG, "%s - initialised udev monitor", __FUNCTION__); + CLog::Log(LOGDEBUG, "%s - initialised %s monitor", __FUNCTION__, threadname.c_str()); } CPeripheralBusUSB::~CPeripheralBusUSB(void) { - StopThread(true); + if(IsRunning()) + StopThread(true); udev_monitor_unref(m_udevMon); udev_unref(m_udev); } @@ -245,7 +246,10 @@ bool CPeripheralBusUSB::WaitForUpdate() /* we have to read the message from the queue, even though we're not actually using it */ struct udev_device *dev = udev_monitor_receive_device(m_udevMon); if (dev) + { + OnDeviceChanged(udev_device_get_syspath(dev)); udev_device_unref(dev); + } else { CLog::Log(LOGERROR, "%s - failed to get device from udev_monitor_receive_device()", __FUNCTION__); diff --git a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.h b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.h index b7715ce..6d4362d 100644 --- a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.h +++ b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.h @@ -32,7 +32,7 @@ namespace PERIPHERALS class CPeripheralBusUSB : public CPeripheralBus { public: - CPeripheralBusUSB(CPeripherals *manager); + CPeripheralBusUSB(CPeripherals *manager, const CStdString &threadname = "PeripBusUSBUdev", PeripheralBusType type = PERIPHERAL_BUS_USB); virtual ~CPeripheralBusUSB(void); virtual void Clear(void); diff --git a/xbmc/peripherals/devices/Makefile.in b/xbmc/peripherals/devices/Makefile.in index 23989f2..730c5d4 100644 --- a/xbmc/peripherals/devices/Makefile.in +++ b/xbmc/peripherals/devices/Makefile.in @@ -6,6 +6,7 @@ SRCS += PeripheralImon.cpp SRCS += PeripheralNIC.cpp SRCS += PeripheralNyxboard.cpp SRCS += PeripheralTuner.cpp +SRCS += PeripheralVideo.cpp ifeq (@USE_LIBCEC@,1) SRCS += PeripheralCecAdapter.cpp diff --git a/xbmc/peripherals/devices/Peripheral.h b/xbmc/peripherals/devices/Peripheral.h index de7cac0..daad6b4 100644 --- a/xbmc/peripherals/devices/Peripheral.h +++ b/xbmc/peripherals/devices/Peripheral.h @@ -38,6 +38,13 @@ namespace PERIPHERALS STATE_STANDBY } CecStateChange; + typedef enum + { + CABLE_UNKNOWN = 0, + CABLE_DISCONNECTED, + CABLE_CONNECTED + } ScreenCableState; + class CPeripheral { friend class CGUIDialogPeripheralSettings; @@ -97,6 +104,11 @@ namespace PERIPHERALS virtual void OnSettingChanged(const std::string &strChangedSetting) {}; /*! + * @brief Called when this device is changed. + */ + virtual void OnDeviceChanged(int state) {}; + + /*! * @brief Called when this device is removed, before calling the destructor. */ virtual void OnDeviceRemoved(void) {} diff --git a/xbmc/peripherals/devices/PeripheralVideo.cpp b/xbmc/peripherals/devices/PeripheralVideo.cpp new file mode 100644 index 0000000..e2fac22 --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralVideo.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "PeripheralVideo.h" +#include "utils/log.h" +#include "guilib/GraphicContext.h" +#include "dialogs/GUIDialogKaiToast.h" +#include "guilib/LocalizeStrings.h" +#include "ApplicationMessenger.h" +#include "Application.h" +#include "settings/Settings.h" + +using namespace PERIPHERALS; + +CPeripheralVideo::CPeripheralVideo(const PeripheralScanResult& scanResult) + : CPeripheral(scanResult) + , m_cableState(0) + , m_timer(this) +{ + m_features.push_back(FEATURE_CABLESTATE); +} + +CPeripheralVideo::~CPeripheralVideo() +{ +} + +void CPeripheralVideo::OnDeviceChanged(int state) +{ + if (!GetSettingBool("pass_events")) + return; + + m_cableState = state; + + if (m_timer.IsRunning()) + m_timer.Restart(); + else + m_timer.Start(5000); +} + +void CPeripheralVideo::OnSettingChanged(const std::string &strChangedSetting) +{ + bool configSet = false; + + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, "VIDEO", g_localizeStrings.Get(configSet ? 36023 : 36024)); +} + +bool CPeripheralVideo::InitialiseFeature(const PeripheralFeature feature) +{ + return CPeripheral::InitialiseFeature(feature); +} + +void CPeripheralVideo::OnTimeout() +{ + switch (m_cableState) { + case CABLE_CONNECTED: + g_application.SetCecStandby(false); + + if (CSettings::Get().GetBool("videoscreen.updateresolutions")) + { + CApplicationMessenger::Get().SetupDisplayReconfigure(); + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, "VIDEO", g_localizeStrings.Get(13288)); + } + + break; + case CABLE_DISCONNECTED: + g_application.SetCecStandby(true); + + default: + ; + } +} diff --git a/xbmc/peripherals/devices/PeripheralVideo.h b/xbmc/peripherals/devices/PeripheralVideo.h new file mode 100644 index 0000000..de1cc67 --- /dev/null +++ b/xbmc/peripherals/devices/PeripheralVideo.h @@ -0,0 +1,46 @@ +#pragma once +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "Peripheral.h" +#include "peripherals/Peripherals.h" +#include "threads/Timer.h" + +namespace PERIPHERALS +{ + class CPeripheralVideo : public CPeripheral, protected ITimerCallback + { + public: + CPeripheralVideo(const PeripheralScanResult& scanResult); + virtual ~CPeripheralVideo(void); + + virtual void OnDeviceChanged(int state); + virtual void OnTimeout(); + + void OnSettingChanged(const std::string &strChangedSetting); + bool InitialiseFeature(const PeripheralFeature feature); + + protected: + int m_cableState; + CTimer m_timer; + + }; +} + diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 0ad9ff5..44e3e59 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -40,6 +40,10 @@ #include "windowing/WindowingFactory.h" #include "cores/AudioEngine/AEFactory.h" #include +#include "peripherals/Peripherals.h" +#include "peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h" + +using namespace PERIPHERALS; CEGLNativeTypeIMX::CEGLNativeTypeIMX() : m_sar(0.0f) @@ -48,6 +52,8 @@ CEGLNativeTypeIMX::CEGLNativeTypeIMX() { m_show = true; m_readonly = true; + + g_peripherals.CreatePeripheralBus(new CPeripheralBusPLATFORM(&g_peripherals)); } CEGLNativeTypeIMX::~CEGLNativeTypeIMX() diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp index 81417b6..a159010 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp @@ -29,6 +29,11 @@ #include "utils/StringUtils.h" #include "settings/Settings.h" #include +#include "peripherals/Peripherals.h" +#include "peripherals/bus/PeripheralBus.h" +#include "peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h" + +using namespace PERIPHERALS; #ifndef __VIDEOCORE4__ #define __VIDEOCORE4__ @@ -66,6 +71,9 @@ static SDTV_ASPECT_T get_sdtv_aspect_from_display_aspect(float display_aspect); #endif CEGLNativeTypeRaspberryPI::CEGLNativeTypeRaspberryPI() +#if defined(TARGET_RASPBERRY_PI) + : m_video(NULL) +#endif { #if defined(TARGET_RASPBERRY_PI) m_DllBcmHost = NULL; @@ -105,6 +113,22 @@ void CEGLNativeTypeRaspberryPI::Initialize() m_DllBcmHost = new DllBcmHost; m_DllBcmHost->Load(); + + CPeripheralBus *m_bus = g_peripherals.CreatePeripheralBus(new CPeripheralBusPLATFORM(&g_peripherals)); + if (!m_bus) + return; + + PeripheralScanResult result(m_bus->Type()); + PeripheralScanResults results; + result.m_strLocation = "/sys/class/graphics/fb0"; + result.m_iSequence = m_bus->GetNumberOfPeripheralsWithFeature(FEATURE_CABLESTATE); + result.m_type = PERIPHERAL_VIDEO; + result.m_strDeviceName = "generic_video"; + result.m_iVendorId = 0; + result.m_iProductId = 0; + results.m_results.push_back(result); + + m_video = m_bus->RegisterNewDevice(result); #endif } @@ -683,6 +707,8 @@ void CEGLNativeTypeRaspberryPI::TvServiceCallback(uint32_t reason, uint32_t para switch(reason) { case VC_HDMI_UNPLUGGED: + if (m_video) + m_video->OnDeviceChanged(CABLE_DISCONNECTED); break; case VC_HDMI_STANDBY: break; @@ -692,6 +718,8 @@ void CEGLNativeTypeRaspberryPI::TvServiceCallback(uint32_t reason, uint32_t para case VC_HDMI_DVI: //Signal we are ready now sem_post(&m_tv_synced); + if (m_video) + m_video->OnDeviceChanged(CABLE_CONNECTED); break; default: break; diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h index a0acb1a..cf85461 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h @@ -25,6 +25,9 @@ #include #include #endif +#include "peripherals/Peripherals.h" + +using namespace PERIPHERALS; class DllBcmHost; class CEGLNativeTypeRaspberryPI : public CEGLNativeType @@ -63,6 +66,7 @@ private: int m_width; int m_height; int m_initDesktopRes; + PERIPHERALS::CPeripheral *m_video; void GetSupportedModes(HDMI_RES_GROUP_T group, std::vector &resolutions); void TvServiceCallback(uint32_t reason, uint32_t param1, uint32_t param2); diff --git a/xbmc/windowing/egl/WinSystemEGL.cpp b/xbmc/windowing/egl/WinSystemEGL.cpp index 848e394..e1ff18f 100644 --- a/xbmc/windowing/egl/WinSystemEGL.cpp +++ b/xbmc/windowing/egl/WinSystemEGL.cpp @@ -390,14 +390,7 @@ void CWinSystemEGL::UpdateResolutions() g_graphicsContext.ResetOverscan(resolutions[i]); CDisplaySettings::GetInstance().GetResolutionInfo(res_index) = resolutions[i]; - CLog::Log(LOGNOTICE, "Found resolution %d x %d for display %d with %d x %d%s @ %f Hz\n", - resolutions[i].iWidth, - resolutions[i].iHeight, - resolutions[i].iScreen, - resolutions[i].iScreenWidth, - resolutions[i].iScreenHeight, - resolutions[i].dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "", - resolutions[i].fRefreshRate); + CLog::Log(LOGNOTICE, "Found resolution %s\n", resolutions[i].strMode.c_str()); res_index = (RESOLUTION)((int)res_index + 1); } @@ -407,8 +400,8 @@ void CWinSystemEGL::UpdateResolutions() */ if (!g_application.m_res.strMode.empty()) resDesktop = g_application.m_res; - else if (CDisplaySettings::Get().GetDisplayResolution() != RES_DESKTOP) - resDesktop = CDisplaySettings::Get().GetResolutionInfo(CDisplaySettings::Get().GetDisplayResolution()); + else if (CDisplaySettings::GetInstance().GetDisplayResolution() != RES_DESKTOP) + resDesktop = CDisplaySettings::GetInstance().GetResolutionInfo(CDisplaySettings::GetInstance().GetDisplayResolution()); else if (m_egl->GetNativeResolution(&curDisplay)) resDesktop = curDisplay; @@ -426,18 +419,12 @@ void CWinSystemEGL::UpdateResolutions() ResDesktop = (RESOLUTION)(i + (int)RES_DESKTOP); } - // swap desktop index for desktop res if available - if (ResDesktop != RES_INVALID) + // don't swap resolutions if current matches previous index + if(CDisplaySettings::Get()Instance.GetCurrentResolution() == ResDesktop) + return; + else if (ResDesktop != RES_INVALID) { - CLog::Log(LOGNOTICE, "Found (%dx%d%s@%f) at %d, setting to RES_DESKTOP at %d", - resDesktop.iWidth, resDesktop.iHeight, - resDesktop.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "", - resDesktop.fRefreshRate, - (int)ResDesktop, (int)RES_DESKTOP); - - RESOLUTION_INFO desktop = CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP); - CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP) = CDisplaySettings::GetInstance().GetResolutionInfo(ResDesktop); - CDisplaySettings::GetInstance().GetResolutionInfo(ResDesktop) = desktop; + CDisplaySettings::GetInstance().SetCurrentResolution(ResDesktop); return; } -- 2.7.1 From 2e82dd08a339b570065e6bdede792a4207d01d59 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 30 Apr 2015 08:37:13 +0200 Subject: [PATCH 054/250] EGL updates Upstream-commit: ccff7914282771272152965d19666b873053ab1e --- xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 28 +++++++++++-------------- xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h | 3 ++- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp index a159010..cdf2620 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp @@ -78,6 +78,7 @@ CEGLNativeTypeRaspberryPI::CEGLNativeTypeRaspberryPI() #if defined(TARGET_RASPBERRY_PI) m_DllBcmHost = NULL; m_nativeWindow = NULL; + m_event.Reset(); #endif } @@ -113,6 +114,10 @@ void CEGLNativeTypeRaspberryPI::Initialize() m_DllBcmHost = new DllBcmHost; m_DllBcmHost->Load(); + vc_tv_register_callback(CallbackTvServiceCallback, this); + + TV_DISPLAY_STATE_T tv_state; + m_DllBcmHost->vc_tv_get_display_state(&tv_state); CPeripheralBus *m_bus = g_peripherals.CreatePeripheralBus(new CPeripheralBusPLATFORM(&g_peripherals)); if (!m_bus) @@ -135,6 +140,7 @@ void CEGLNativeTypeRaspberryPI::Initialize() void CEGLNativeTypeRaspberryPI::Destroy() { #if defined(TARGET_RASPBERRY_PI) + vc_tv_unregister_callback_full(CallbackTvServiceCallback, this); if(m_DllBcmHost && m_DllBcmHost->IsLoaded()) m_DllBcmHost->Unload(); delete m_DllBcmHost; @@ -293,9 +299,6 @@ bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res) if(GETFLAGS_GROUP(res.dwFlags) && GETFLAGS_MODE(res.dwFlags)) { - sem_init(&m_tv_synced, 0, 0); - m_DllBcmHost->vc_tv_register_callback(CallbackTvServiceCallback, this); - if (res.dwFlags & (D3DPRESENTFLAG_MODE3DSBS|D3DPRESENTFLAG_MODE3DTB)) { /* inform TV of any 3D settings. Note this property just applies to next hdmi mode change, so no need to call for 2D modes */ @@ -331,7 +334,7 @@ bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res) (res.dwFlags & D3DPRESENTFLAG_MODE3DSBS) ? " SBS":"", (res.dwFlags & D3DPRESENTFLAG_MODE3DTB) ? " TB":""); - sem_wait(&m_tv_synced); + m_event.WaitMSec(10000); } else { @@ -340,16 +343,11 @@ bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res) (res.dwFlags & D3DPRESENTFLAG_MODE3DSBS) ? " SBS":"", (res.dwFlags & D3DPRESENTFLAG_MODE3DTB) ? " TB":""); } - m_DllBcmHost->vc_tv_unregister_callback(CallbackTvServiceCallback); - sem_destroy(&m_tv_synced); m_desktopRes = res; } else if(!GETFLAGS_GROUP(res.dwFlags) && GETFLAGS_MODE(res.dwFlags)) { - sem_init(&m_tv_synced, 0, 0); - m_DllBcmHost->vc_tv_register_callback(CallbackTvServiceCallback, this); - SDTV_OPTIONS_T options; options.aspect = get_sdtv_aspect_from_display_aspect((float)res.iScreenWidth / (float)res.iScreenHeight); @@ -360,15 +358,13 @@ bool CEGLNativeTypeRaspberryPI::SetNativeResolution(const RESOLUTION_INFO &res) CLog::Log(LOGDEBUG, "EGL set SDTV mode (%d,%d)=%d\n", GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), success); - sem_wait(&m_tv_synced); + m_event.WaitMSec(10000); } else { CLog::Log(LOGERROR, "EGL failed to set SDTV mode (%d,%d)=%d\n", GETFLAGS_GROUP(res.dwFlags), GETFLAGS_MODE(res.dwFlags), success); } - m_DllBcmHost->vc_tv_unregister_callback(CallbackTvServiceCallback); - sem_destroy(&m_tv_synced); m_desktopRes = res; } @@ -710,16 +706,16 @@ void CEGLNativeTypeRaspberryPI::TvServiceCallback(uint32_t reason, uint32_t para if (m_video) m_video->OnDeviceChanged(CABLE_DISCONNECTED); break; - case VC_HDMI_STANDBY: + case VC_HDMI_ATTACHED: + if (m_video) + m_video->OnDeviceChanged(CABLE_CONNECTED); break; case VC_SDTV_NTSC: case VC_SDTV_PAL: case VC_HDMI_HDMI: case VC_HDMI_DVI: //Signal we are ready now - sem_post(&m_tv_synced); - if (m_video) - m_video->OnDeviceChanged(CABLE_CONNECTED); + m_event.Set(); break; default: break; diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h index cf85461..ba6d9d2 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h @@ -26,6 +26,7 @@ #include #endif #include "peripherals/Peripherals.h" +#include "threads/Thread.h" using namespace PERIPHERALS; @@ -61,7 +62,7 @@ private: DISPMANX_ELEMENT_HANDLE_T m_dispman_display; DISPMANX_ELEMENT_HANDLE_T m_dispman_element; TV_GET_STATE_RESP_T m_tv_state; - sem_t m_tv_synced; + CEvent m_event; RESOLUTION_INFO m_desktopRes; int m_width; int m_height; -- 2.7.1 From 67b4b1592d594c25d8acbba31beac5709170da2e Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 6 May 2015 09:36:24 +0200 Subject: [PATCH 055/250] Fallback to device type PLAYER if RECORDER is out of free LAs. Upstream-commit: eebcb54fecea75e6ff43b1f5ff1f1f70981fc49b (cherry picked from commit 8f2b3bb10e601b34de6dd3583b21271f6e995fee) --- xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index 1200ca7..68b359b 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -1326,6 +1326,11 @@ void CPeripheralCecAdapter::SetConfigurationFromSettings(void) iDeviceType = (int)CEC_DEVICE_TYPE_RECORDING_DEVICE; m_configuration.deviceTypes.Add((cec_device_type)iDeviceType); + // add all other remaining device types - in case we have already 3 recorders + // XBMC would fail obtaining LA + m_configuration.deviceTypes.Add((cec_device_type)CEC_DEVICE_TYPE_PLAYBACK_DEVICE); + m_configuration.deviceTypes.Add((cec_device_type)CEC_DEVICE_TYPE_TUNER); + // always try to autodetect the address. // when the firmware supports this, it will override the physical address, connected device and hdmi port settings m_configuration.bAutodetectAddress = CEC_DEFAULT_SETTING_AUTODETECT_ADDRESS; -- 2.7.1 From 72236b6d2efeeb729c958b0a1710c1f9a6412d3e Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 27 Feb 2015 17:50:12 +0100 Subject: [PATCH 056/250] configure.ac use_platform=cubox-i Upstream-commit: c7969923e4b598ba1e68b32a5360268f2ed6fc42 --- configure.ac | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 22cb60c..c3ea7e6 100644 --- a/configure.ac +++ b/configure.ac @@ -710,8 +710,31 @@ case $use_platform in raspberry-pi) target_platform=target_raspberry_pi use_neon=no - use_arch="arm" use_cpu=arm1176jzf-s + extrarpiflags=rpi1 + ;; + cubox-i) + target_platform="cubox-i" + use_static_ffmpeg=yes + use_joystick=no + use_sdl=no + use_hardcoded_tables="yes" + CFLAGS="$CFLAGS -pipe -O3 -march=armv7-a -mtune=cortex-a9 -mcpu=cortex-a9 -mfloat-abi=hard -mfpu=neon -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " + CXXFLAGS="$CXXFLAGS -pipe -O3 -march=armv7-a -mtune=cortex-a9 -mcpu=cortex-a9 -mfloat-abi=hard -mfpu=neon -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " + FFMPEG_EXTRACFLAGS="$FFMPEG_EXTRACFLAGS -pipe -O3 -march=armv7-a -mtune=cortex-a9 -mcpu=cortex-a9 -mfloat-abi=hard -mfpu=neon -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " + use_cpu=cortex-a9 + use_x11=no + use_neon=yes + ;; + raspberry-pi2) + target_platform=target_raspberry_pi + use_neon=yes + use_cpu=cortex-a7 + extrarpiflags=rpi2 + ;; +esac + +if test "$target_platform" = "target_raspberry_pi" ; then use_hardcoded_tables="yes" use_openmax=no ARCH="arm" @@ -721,6 +744,9 @@ case $use_platform in CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" ;; +else + ARCH="arm" + ;; esac if test "$host_vendor" = "apple"; then @@ -839,8 +865,8 @@ elif test "$use_arch" = "arm"; then use_cpu=cortex-a8]) else if test "$use_neon" = "yes"; then - CFLAGS="$CFLAGS -mfpu=neon -mvectorize-with-neon-quad" - CXXFLAGS="$CXXFLAGS -mfpu=neon -mvectorize-with-neon-quad" + CFLAGS="$CFLAGS -mfpu=neon -funsafe-math-optimizations -mvectorize-with-neon-quad" + CXXFLAGS="$CXXFLAGS -mfpu=neon -funsafe-math-optimizations -mvectorize-with-neon-quad" fi fi fi @@ -1006,6 +1032,17 @@ else AC_MSG_RESULT($wayland_disabled) fi +# i.MX6 +if test "$target_platform" = "cubox-i"; then + AC_MSG_CHECKING([for i.MX framebuffer support]) + AC_CHECK_HEADER([linux/mxcfb.h], have_imxfb=yes,have_imxfb=no) + AC_MSG_RESULT($have_imxfb) + if test "x$have_imxfb" = "xyes"; then + AC_DEFINE([HAS_IMXFB], [1], [Whether i.MX framebuffer support is enabled.]) + AC_SUBST([USE_IMXFB], 1) + fi +fi + # Checks for platforms libraries. if test "$use_gles" = "yes"; then use_gl="no" @@ -1020,6 +1057,10 @@ if test "$use_gles" = "yes"; then AC_DEFINE([HAVE_LIBGLESV2],[1],["Define to 1 if you have the `GLESv2' library (-lGLESv2)."]) AC_MSG_RESULT(== WARNING: OpenGLES support is assumed.) LIBS="$LIBS -lEGL -lGLESv2 -lbcm_host -lvcos -lvchiq_arm -lmmal -lmmal_core -lmmal_util" + elif test "$target_platform" = "cubox-i"; then + AC_DEFINE([HAVE_LIBEGL],[1],["Define to 1 if you have the `EGL' library (-lEGL)."]) + AC_DEFINE([HAVE_LIBGLESV2],[1],["Define to 1 if you have the `GLESv2' library (-lGLESv2)."]) + LIBS="$LIBS -lEGL -lGLESv2 -lGAL " else AC_CHECK_LIB([EGL], [main],, AC_MSG_ERROR($missing_library)) AC_CHECK_LIB([GLESv2],[main],, AC_MSG_ERROR($missing_library)) @@ -1675,6 +1716,8 @@ if test "${USE_STATIC_FFMPEG}" = "1"; then FFMPEG_OPTS="${FFMPEG_OPTS} --disable-optimizations" fi + FFMPEG_OPTS="${FFMPEG_OPTS} --disable-libxcb --cpu=${use_cpu} --arch=${use_arch}" + if test "$with_ffmpeg" = "auto" || test "$with_ffmpeg" = "yes"; then SAVE_INCLUDES="$INCLUDES" SAVE_LIBS="$LIBS" -- 2.7.1 From e6fef127d349fa1992fc9171ed359086f6371170 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 7 May 2015 11:03:24 +0200 Subject: [PATCH 057/250] IMX EGL code inactive when not compiling this platform Upstream-commit: 85cb9ac6a224c431d966c830743d11681001de3c --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 47 +++++++++++++++++++++++++++++++-- xbmc/windowing/egl/EGLNativeTypeIMX.h | 2 ++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 44e3e59..777d8c2 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -46,14 +46,18 @@ using namespace PERIPHERALS; CEGLNativeTypeIMX::CEGLNativeTypeIMX() +#ifdef HAS_IMXVPU : m_sar(0.0f) , m_display(NULL) , m_window(NULL) +#endif { +#ifdef HAS_IMXVPU m_show = true; m_readonly = true; g_peripherals.CreatePeripheralBus(new CPeripheralBusPLATFORM(&g_peripherals)); +#endif } CEGLNativeTypeIMX::~CEGLNativeTypeIMX() @@ -62,12 +66,17 @@ CEGLNativeTypeIMX::~CEGLNativeTypeIMX() bool CEGLNativeTypeIMX::CheckCompatibility() { +#ifdef HAS_IMXVPU std::ifstream file("/sys/class/graphics/fb0/fsl_disp_dev_property"); return file.is_open(); +#else + return false; +#endif } void CEGLNativeTypeIMX::Initialize() { +#ifdef HAS_IMXVPU int fd; // Check if we can change the framebuffer resolution @@ -110,7 +119,7 @@ void CEGLNativeTypeIMX::Initialize() CLog::Log(LOGERROR, "%s - Error while opening /dev/fb0.\n", __FUNCTION__); return; } -#ifdef HAS_IMXVPU + struct mxcfb_color_key colorKey; struct mxcfb_gbl_alpha gbl_alpha; struct mxcfb_loc_alpha lalpha; @@ -131,18 +140,20 @@ void CEGLNativeTypeIMX::Initialize() colorKey.color_key = (16 << 16)|(8 << 8)|16; if (ioctl(fd, MXCFB_SET_CLR_KEY, &colorKey) < 0) CLog::Log(LOGERROR, "%s - Failed to setup color keying\n", __FUNCTION__); -#endif + // Check if we can change the framebuffer resolution if (!m_readonly) GetNativeResolution(&m_init); m_sar = GetMonitorSAR(); close(fd); +#endif return; } void CEGLNativeTypeIMX::Destroy() { +#ifdef HAS_IMXVPU CLog::Log(LOGDEBUG, "%s\n", __FUNCTION__); struct fb_fix_screeninfo fixed_info; void *fb_buffer; @@ -172,6 +183,7 @@ void CEGLNativeTypeIMX::Destroy() SetNativeResolution(m_init); system("/usr/bin/splash --force -i -m 'stopping xbmc...'"); +#endif return; } @@ -213,20 +225,28 @@ bool CEGLNativeTypeIMX::CreateNativeWindow() bool CEGLNativeTypeIMX::GetNativeDisplay(XBNativeDisplayType **nativeDisplay) const { +#ifdef HAS_IMXVPU if (!m_nativeDisplay) return false; *nativeDisplay = (XBNativeDisplayType*)m_nativeDisplay; return true; +#else + return false; +#endif } bool CEGLNativeTypeIMX::GetNativeWindow(XBNativeWindowType **nativeWindow) const { +#ifdef HAS_IMXVPU if (!m_nativeWindow) return false; *nativeWindow = (XBNativeWindowType*)m_nativeWindow; return true; +#else + return false; +#endif } bool CEGLNativeTypeIMX::DestroyNativeDisplay() @@ -261,11 +281,15 @@ bool CEGLNativeTypeIMX::DestroyNativeWindow() bool CEGLNativeTypeIMX::GetNativeResolution(RESOLUTION_INFO *res) const { +#ifdef HAS_IMXVPU std::string mode; SysfsUtils::GetString("/sys/class/graphics/fb0/mode", mode); CLog::Log(LOGDEBUG,": %s, %s", __FUNCTION__, mode.c_str()); return ModeToResolution(mode, res); +#else + return false; +#endif } bool CEGLNativeTypeIMX::SetNativeResolution(const RESOLUTION_INFO &res) @@ -293,8 +317,12 @@ bool CEGLNativeTypeIMX::SetNativeResolution(const RESOLUTION_INFO &res) CreateNativeWindow(); return true; +#else + return false; +#endif } +#ifdef HAS_IMXVPU bool CEGLNativeTypeIMX::FindMatchingResolution(const RESOLUTION_INFO &res, const std::vector &resolutions) { for (int i = 0; i < (int)resolutions.size(); i++) @@ -309,9 +337,11 @@ bool CEGLNativeTypeIMX::FindMatchingResolution(const RESOLUTION_INFO &res, const } return false; } +#endif bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutions) { +#ifdef HAS_IMXVPU if (m_readonly) return false; @@ -339,15 +369,23 @@ bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutio resolutions.push_back(res); } return resolutions.size() > 0; +#else + return false; +#endif } bool CEGLNativeTypeIMX::GetPreferredResolution(RESOLUTION_INFO *res) const { +#ifdef HAS_IMXVPU return GetNativeResolution(res); +#else + return false; +#endif } bool CEGLNativeTypeIMX::ShowWindow(bool show) { +#ifdef HAS_IMXVPU if (m_show == show) return true; @@ -362,8 +400,12 @@ bool CEGLNativeTypeIMX::ShowWindow(bool show) m_show = show; return true; +#else + return false; +#endif } +#ifdef HAS_IMXVPU float CEGLNativeTypeIMX::GetMonitorSAR() { FILE *f_edid; @@ -485,3 +527,4 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) return res->iWidth > 0 && res->iHeight> 0; } +#endif diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.h b/xbmc/windowing/egl/EGLNativeTypeIMX.h index 1628954..7101bcc 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.h +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.h @@ -52,6 +52,7 @@ public: virtual bool ShowWindow(bool show = true); +#ifdef HAS_IMXVPU protected: bool m_readonly; bool m_show; @@ -64,4 +65,5 @@ protected: EGLNativeDisplayType m_display; EGLNativeWindowType m_window; uint8_t m_edid[512]; +#endif }; -- 2.7.1 From f6a864fc19bd7ba9052365127b49e3f3759a37f8 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 23 Apr 2015 00:21:51 +0100 Subject: [PATCH 058/250] Add new gles screensavers Upstream-commit: 2497d8e7b154c147c325f3f7e155a2beb7491d5c (cherry picked from commit 17163155d122faf3f12f313f04790cd9976a0a12) Signed-off-by: Matus Kral --- Makefile.in | 25 + addons/screensaver.gles.ball/addon.xml | 121 +++ addons/screensaver.gles.ball/icon.png | Bin 0 -> 5657 bytes addons/screensaver.gles.noise/addon.xml | 121 +++ addons/screensaver.gles.noise/icon.png | Bin 0 -> 5657 bytes addons/screensaver.gles.plasma/addon.xml | 121 +++ addons/screensaver.gles.plasma/icon.png | Bin 0 -> 5657 bytes addons/screensaver.gles.plasma2/addon.xml | 121 +++ addons/screensaver.gles.plasma2/icon.png | Bin 0 -> 5657 bytes addons/screensaver.gles.solarwinds/addon.xml | 119 +++ addons/screensaver.gles.solarwinds/icon.png | Bin 0 -> 14774 bytes addons/screensaver.gles.spiral/addon.xml | 121 +++ addons/screensaver.gles.spiral/icon.png | Bin 0 -> 5657 bytes addons/screensaver.gles.stellar/addon.xml | 121 +++ addons/screensaver.gles.stellar/icon.png | Bin 0 -> 5657 bytes addons/screensaver.gles.warp/addon.xml | 119 +++ addons/screensaver.gles.warp/icon.png | Bin 0 -> 9424 bytes configure.ac | 33 + xbmc/screensavers/gles/Makefile.in | 6 + xbmc/screensavers/gles/ball/Makefile.in | 36 + xbmc/screensavers/gles/ball/wrapper.cc | 102 +++ xbmc/screensavers/gles/noise/Makefile.in | 36 + xbmc/screensavers/gles/noise/wrapper.cc | 102 +++ xbmc/screensavers/gles/plasma/Makefile.in | 36 + xbmc/screensavers/gles/plasma/wrapper.cc | 102 +++ xbmc/screensavers/gles/plasma2/Makefile.in | 36 + xbmc/screensavers/gles/plasma2/wrapper.cc | 102 +++ xbmc/screensavers/gles/solarwinds/Makefile.in | 36 + xbmc/screensavers/gles/solarwinds/solarwinds.c | 531 +++++++++++++ xbmc/screensavers/gles/solarwinds/solarwinds.h | 60 ++ xbmc/screensavers/gles/solarwinds/wrapper.cc | 96 +++ xbmc/screensavers/gles/spiral/Makefile.in | 36 + xbmc/screensavers/gles/spiral/wrapper.cc | 102 +++ xbmc/screensavers/gles/stellar/Makefile.in | 36 + xbmc/screensavers/gles/stellar/wrapper.cc | 102 +++ xbmc/screensavers/gles/triangle2.c | 990 +++++++++++++++++++++++++ xbmc/screensavers/gles/triangle2.h | 64 ++ xbmc/screensavers/gles/warp/Makefile.in | 36 + xbmc/screensavers/gles/warp/wrapper.cc | 102 +++ 39 files changed, 3771 insertions(+) create mode 100644 addons/screensaver.gles.ball/addon.xml create mode 100644 addons/screensaver.gles.ball/icon.png create mode 100644 addons/screensaver.gles.noise/addon.xml create mode 100644 addons/screensaver.gles.noise/icon.png create mode 100644 addons/screensaver.gles.plasma/addon.xml create mode 100644 addons/screensaver.gles.plasma/icon.png create mode 100644 addons/screensaver.gles.plasma2/addon.xml create mode 100644 addons/screensaver.gles.plasma2/icon.png create mode 100644 addons/screensaver.gles.solarwinds/addon.xml create mode 100644 addons/screensaver.gles.solarwinds/icon.png create mode 100644 addons/screensaver.gles.spiral/addon.xml create mode 100644 addons/screensaver.gles.spiral/icon.png create mode 100644 addons/screensaver.gles.stellar/addon.xml create mode 100644 addons/screensaver.gles.stellar/icon.png create mode 100644 addons/screensaver.gles.warp/addon.xml create mode 100644 addons/screensaver.gles.warp/icon.png create mode 100644 xbmc/screensavers/gles/Makefile.in create mode 100644 xbmc/screensavers/gles/ball/Makefile.in create mode 100644 xbmc/screensavers/gles/ball/wrapper.cc create mode 100644 xbmc/screensavers/gles/noise/Makefile.in create mode 100644 xbmc/screensavers/gles/noise/wrapper.cc create mode 100644 xbmc/screensavers/gles/plasma/Makefile.in create mode 100644 xbmc/screensavers/gles/plasma/wrapper.cc create mode 100644 xbmc/screensavers/gles/plasma2/Makefile.in create mode 100644 xbmc/screensavers/gles/plasma2/wrapper.cc create mode 100644 xbmc/screensavers/gles/solarwinds/Makefile.in create mode 100644 xbmc/screensavers/gles/solarwinds/solarwinds.c create mode 100644 xbmc/screensavers/gles/solarwinds/solarwinds.h create mode 100644 xbmc/screensavers/gles/solarwinds/wrapper.cc create mode 100644 xbmc/screensavers/gles/spiral/Makefile.in create mode 100644 xbmc/screensavers/gles/spiral/wrapper.cc create mode 100644 xbmc/screensavers/gles/stellar/Makefile.in create mode 100644 xbmc/screensavers/gles/stellar/wrapper.cc create mode 100644 xbmc/screensavers/gles/triangle2.c create mode 100644 xbmc/screensavers/gles/triangle2.h create mode 100644 xbmc/screensavers/gles/warp/Makefile.in create mode 100644 xbmc/screensavers/gles/warp/wrapper.cc diff --git a/Makefile.in b/Makefile.in index 09d5a79..88b5ab9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -193,6 +193,20 @@ LIB_DIRS=\ lib/cpluff \ lib/xbmc-dll-symbols +SS_DIRS= +ifneq (@DISABLE_GLESSCREENSAVERS@,1) + SS_DIRS+= xbmc/screensavers/gles/solarwinds + SS_DIRS+= xbmc/screensavers/gles/plasma + SS_DIRS+= xbmc/screensavers/gles/plasma2 + SS_DIRS+= xbmc/screensavers/gles/noise + SS_DIRS+= xbmc/screensavers/gles/warp + SS_DIRS+= xbmc/screensavers/gles/stellar + SS_DIRS+= xbmc/screensavers/gles/spiral + SS_DIRS+= xbmc/screensavers/gles/ball +else + INSTALL_FILTER+= .*screensaver\.gles.* +endif + LIBADDON_DIRS=\ lib/addons/library.xbmc.addon \ lib/addons/library.kodi.adsp \ @@ -331,6 +345,17 @@ exports: xbmc/cores/DllLoader/exports/exports.a xbmc/cores/DllLoader/exports/uti $(MAKE) -C xbmc/cores/DllLoader/exports wrapper.def dllloader: exports xbmc/cores/DllLoader/dllloader.a +ifeq (@USE_OPENGLES@,1) +GLESHELPERS=xbmc/screensavers/gles/gleshelpers.a +$(GLESHELPERS): force exports + $(MAKE) -C xbmc/screensavers/gles +endif + +$(SS_DIRS): force exports $(GLESHELPERS) + $(MAKE) -C $@ + +screensavers: $(SS_DIRS) + libaddon: exports $(MAKE) -C lib/addons/library.xbmc.addon $(MAKE) -C lib/addons/library.kodi.adsp diff --git a/addons/screensaver.gles.ball/addon.xml b/addons/screensaver.gles.ball/addon.xml new file mode 100644 index 0000000..523e339 --- /dev/null +++ b/addons/screensaver.gles.ball/addon.xml @@ -0,0 +1,121 @@ + + + + + + + + Seker die tweede mees psigedeliese sluimerskerm ooit + ربما شاشة التوقف الثانية الأكثر هدوء على الإطلاق + Напэўна, другі найбольш псіхадэлічны ахоўнік экрану + Вероятно вторият най-халюциногенен скрийнсейвър + Probablement el segon estalvi de pantalla més psicodèlic mai creat + Pravděpodobně druhý nejdivočejší šetřič obrazovky všech dob + Mwy na thebyg yr ail arbedwr sgrin mwyaf seicadelig + Formodentlig den anden mest psykedeliske pauseskærm nogensinde + Wahrscheinlich der zweit-psychodelischste Bildschirmschoner überhaupt + Πιθανότατα η δεύτερη πιο ψυχεδελική προφύλαξη οθόνης που έγινε ποτέ + Rotating ball screensaver + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probablemente el segundo salvapantallas más psicodélico jamás creado + Probablemente el segundo protector de pantalla más psicodélico jamás creado + Probablemente el segundo protector de pantalla más psicodélico + Arvatavasti teine kõige psühhedeelsem ekraanisäästja, mis iial tehtud + Ziurrenik inoizko bigarren pantaila-babesle psikodelikoena + Todennäköisesti toiseksi psykedeelisin näytönsäästäjä koskaan + Probablement le deuxième économiseur d'écran le plus psychédélique jamais créé + Probablement le deuxième économiseur d'écran le plus psychédélique + Probabelmente o segundo protector de pantalla máis psicodélico. + כנראה שומר המסך השני בדירוג הפסיכדליות + Vjerojatno drugi najveći psihodelični čuvar zaslona ikad + A második legpszihedelikusabb képernyővédő + Mungkin screensaver paling psikedelik nomor dua yang pernah ada + Líklega í öðru sæti yfir klikkuðustu skjáhvíluna + Probabilmente il secondo salvaschermo più psichedelico di sempre + 世界で2番目にサイケなスクリーンセーバー + 아마도 지금까지 두번째로 가장 환상적인 화면보호기 + Tikriausiai antra labiausiai psichodelinė ekrano užsklanda pasaulyje. + Iespējams viens no vispsihodēliskākajiem ekrānsaudzētājiem pasaulē + Можеби втора нај психоделична заштита на екран + Waarschijnlijk de op één na meest psychedelische schermbeveiliging ooit + Helt sikkert den nest mest psykedeliske skjermspareren som finnes + Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie + Este é provavelmente o segundo melhor protector de ecrã psicadélico de sempre + Provavelmente a segunda mais psicodélica proteção de tela já vista + Probabil al doilea cel mai năucitor screensaver care a existat vreodată + Наверное, вторая из самых психоделических заставок в мире + Förmodligen den näst psykedeliska skärmsläckaren + පෙනෙන විදියට සදා දෙවන මහත් අධිචිත්ත වේගී තිරමෙහෙකරු + Pravdepodobne druhý najviac hypnotizujúci šetrič obrazovky vôbec + Gotovo drugi najbolj psihadelični ohranjevalnik zaslona na svetu + Troligen den näst mest psykedeliska skärmsläckaren någonsin. + Эҳтимол аст, ки имрӯз дар тамоми ҷаҳон ин пардаи экран ҷои дуюмро мегирад + Muhtemelen insanı hayallere sürükleyen en iyi ikinci ekran koruyucu + Напевно, друга серед найбільш психоделічних заставок + Xứng đáng làm trình bảo vệ màn hình gây ảo giác mạnh thứ hai + 或许是排名第二的迷幻效果屏幕保护程序 + 可能是有史以來第二最夢幻的螢幕保護程式保護程式 + Seker die tweede mees psigedeliese sluimerskerm wat bestaan. Verbeel jou net al daai kleure wat rond beweeg. + ربما شاشة التوقف الثانية الأكثر هدوء في الوجود. فقط حاول تصوير هذه الألوان المتحركة . + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + Вероятно вторият по сила халюциногенен скрийнсейвър създаван някога. Просто се опитайте да съзрете всички тези цветове. + Probablement el segon estalvi de pantalla més psicodèlic que existeix. Intenta imaginar tots aquests colors movent-se. + Pravděpodobně druhý nejdivočejší šetřič obrazovky všech dob. Zkuste si představit všechny ty poletující barvy. + Mwy na thebyg yr ail arbedwr sgrin mwyaf seicadelig sy'n bod. Ceisiwch ddychmygu'r holl liwiau na'n symud o gwmpas. + Formodentlig den anden mest psykedeliske pauseskærm, der eksisterer. Forestil dig alle de farver, der bevæger sig omkring. + Wahrscheinlich der zweit-psychodelischste Bildschirmschoner, den es gibt. Versuche doch alle diese Farben, die sich umher bewegen, festzuhalten. + Πιθανότατα η δεύτερη πιο ψυχεδελική προφύλαξη οθόνης που υπάρχει. Απλά προσπαθήστε να φανταστείτε όλα αυτά τα χρώματα σε κίνηση. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + Probablemente el segundo salvapantallas más psicodélico que existe. Intente imaginarse todos esos colores moviéndose. + Probablemente el segundo protector de pantalla más psicodélico que existe. Solo intente imaginarse todos esos colores moviéndose. + Probablemente el segundo protector de pantallas más psicodélico. Solo trate de captar todos los colores moviéndose alrededor. + Arvatavasti ajaloo teine kõige psühhedeelsem ekraanisäästja. Püüa lihtsalt kujutleda kõiki neid värve, mis ringi liiguvad. + Ziurrenik existitzen den bigarren pantaila-babesle psikodelikoena. Saiatu kolore guzti horiek mugitzen irudikatzen. + Todennäköisesti toiseksi psykedeelisin olemassa oleva näytönsäästäjä. Kuvittelepa vain kaikki nuo värit lentelemässä ympäriinsä. + Probablement le deuxième économiseur d'écran le plus psychédélique de l'histoire. Essayez seulement d'imaginer toutes ces couleurs en mouvement. + Probablement le deuxième économiseur d'écran le plus psychédélique de l'histoire. Essayez seulement d'imaginer toutes ces couleurs en mouvement. + Probabelmente o segundo protector de pantalla máis psicodélico do mundo. Tan só probe a imaxinarse todas esas cores movéndose ó redor. + כנראה שומר המסך השני בדירוג הפסיכדליות שקיים כיום. פשוט נסו לדמיין את כל הצבעים האלו נעים ממקום למקום. + Vjerojatno drugi najveći psihodelični čuvar zaslona koji postoji. Samo pokušajte zamisliti sve te boje koje se gibaju okolo. + Valószínüleg a második legpszihedelikusabb képernyővédő ami létezik. Csak képzeld el mindezt a színkavalkádot mozogni. + Mungkin screensaver paling psikedelik nomor dua yang pernah ada. Coba bayangkan warna-warni itu bergerak ke sana kemari. + Líklega í öðru sæti yfir klikkuðustu skjáhvíluna sem til er. Reyndi bara að ímynda þér alla þessa liti á hreyfingu. + Probabilmente il secondo salvaschermo più psichedelico di sempre. Prova semplicemente a guardare tutti quei colori che si muovono. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + 아마도 존재하는 두번째로 가장 환상적인 화면보호기. 모든 색깔들이 움직이는 것을 상상해보세요. + Turbūt antra labiausiai psichodelinė ekrano užsklanda pasaulyje. Išbandykite ją ir pamatysite judančių spalvų šventę. + Iespējams viens no vispsihodēliskākajiem ekrānsaudzētājiem pasaulē. Pamēģiniet, lai gūtu priekšstatu par krāsu kustību un plūsmu visapkārt. + Можеби втора нај психоделична заштита на екран. Само обидете се да ги согледате сите тие бои кои се движат. + Waarschlijnlijk de op één na meest psychedelische schermbeveliging ooit. Probeer u het voor te stellen: al die kleuren die door elkaar lopen. + Helt sikkert den nest mest psykadeliske skjermsparern i verden. Bare prøv å se for deg alle de fargene som beveger seg rundt. + Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie. Spróbuj i zobacz ferie poruszających się barw. + Provavelmente, o segundo melhor protector de ecrã psicadélico de sempre. Experimente visualizar todas as cores a moverem-se. + Provavelmente a segundo mais psicodélica proteção de tela existente. Experimente ver todas essas cores se movimentando ao redor da tela. + Probabil al doilea cel mai năucitor screensaver care a existat vreodată. Doar încercați să vă imaginați toate acele culori mișcându-se. + Просто попробуйте представить себе все цвета в движении. + Förmodligen den näst psykedeliska skärmsläckaren som finns. Försök bara att uppfatta alla färger som rör sig runt och runt. + පෙනෙන විදියට සදා පවතින දෙවන මහත් අධිචිත්ත වේගී තිරමෙහෙකරු.වටේ තිබෙන එම සියළු වර්ණ ඡායාරූප කිරීමට උත්සාහ කිරීම පමණයි. + Pravdepodobne druhý najviac hypnotizujúci šetrič obrazovky aký vôbec existuje. Iba si skúste predstaviť všetky tie farby pohybujúc sa okolo. + Gotovo drugi najbolj psihadelični ohranjevalnik zaslona na svetu. Samo predstavljajte si vse te barve, ki letijo naokrog. + Troligen den näst mest psykedeliska skärmsläckaren som existerar. Bara tänk dig alla färgerna som rör på sig. + Эҳтимол аст, ки имрӯз дар тамоми ҷаҳон ин пардаи экран ҷои дуюмро мегирад. Танҳо тасаввур кунед, ки чӣ қадар зебо ҳамаи рангҳояш бозӣ мекунанд. + Muhtemelen insanı hayallere sürükleyen en iyi ikinci ekran koruyucu. Ekranda dolaşan tüm renkleri seyretmeye çalışın. + Напевно, друга серед найбільш психоделічних заставок. Лише уявіть усі ці переливи кольорів. + Đây có thể là trình bảo vệ màn hình gây ảo giác mạnh thứ hai tại thời điểm này. Hãy thử xem các hình ảnh tạo nên từ các màu sắc di chuyển khắp nơi + 或许是排名第二的迷幻效果屏幕保护程序。你将看到所有颜色满处乱飞。 + 可能是現存第二最夢幻的螢幕保護程式。快來嘗試想像一下所有移動中的色彩變化。 + all + + diff --git a/addons/screensaver.gles.ball/icon.png b/addons/screensaver.gles.ball/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a6784afc53d95a655742f9b7db247471fc52a105 GIT binary patch literal 5657 zcmd5=%_yf)hI}rNdW+$&`^i!0RZ0Z5f2~+-G*^$ zdC}XzSS?I;T#Z?V*$oLUxq6 zE9lIcr+wgK*+sd{`L^(P-8a3lYQ&E}UA|67z<}ug9WVyQrWc4}FGAmYqBl>1bONzv zC+?Ez!vf2~`U3PpH94L~S5!~e3>{ftnwqYDHkO#%!3Eds-f-vU<#x3ok^P!#c&&Mj zzqU{)hEWAAwchi(#n$&f83OU#4u794xU3pF;=hiq3z=Iyzy>gw6Z9jc|#L>RDEfDP^{ zw1VZPJzaiK3d}>fS&jI4kUS-TdMLJX#O%vmQUu7;ka*&oPz;Dus2GWytedNb0VVFo z=kC>iea=I}ER0DJ)^vpcb6$-b?rJ8LX9^5>nJ}Xg6!55(@FZlJA9&Z2c z!+;}TZ4V{di+qq?Xf=8;-O}LTGYj|nvT$g|IzXn0C-KCg_?NN3#>vI=#XWhw?Wi^+ z^5c(n?^!b~o5{zi??H}^N`*^@ANh^k1$*V8eb%ysgxv^$Gs<9_i2oVtX{VnGo`hq+ zylhDS*9eiVK!Mjpe5VF{IPTn9Mgq4AI)Ep>o|344+WxA@`KN8z(B22(wE%zr&1Wb(!JYd`bl)I`2oCbOeV)*7eJt@Rok8|jq%ZHWu5Ak2x( z`UFt5tE>DaycfyOpHB3v>FWnYB4&^~-QE=wrbh62 zn@A$`0LoZf#ctGs9~hCsirP#OM22xhr~DjQh$2s$IAh95$xVO& zcI->QTatShXtbcLfgS3SfEPF^93rtz6YI-*0?-UuSjH{Z8 z>at!RLM1%!4T?6mr+tW3;$0ZF^9h1MSU+qSkfN+qVan0pj3C9$(Z zjg$p*`xnG=-UpXTg`QTr$bZ+KkmkjM7f<<(oJvf&LnN6o5O;~iCm}~b@LEPWSb~QN zJvrf{&fR@?rCsTVW+tuPtR{j_|4_OdieB5wpOErln*d&^`xYqJB}54VP*d3 z&)HR_0%}>q-`}5IKKOF?%tuz&P=uHyk2`%>v1o6vPOEdVi%Kw@Nh zsjWuVK={$ASC{xw0)zYuzvdKk^U%<6W5MG3WD#Ejd`MLp9;CT{9CUmC2jO!ymsF@> zEJt^3H~ZaVHI7i*i^D?A^p=+9^>{;x7xfK)b&!IRtzcI_RMEO>f}0;4fI<;(ly1&N$3` z-lic`n(t!wdUcV5JB2Ggdf&nj!kCklV<1M7J})(5`kK99*4W%!E?~c>2~v?P3~@C^ zlX#f*?4#Xl7f;*0*W9*Ap;Hk+8EhNdv&>DKEVtG>FH{2TPBet|=osjln*M%-LGu2z zL6!@uFSC7y!qJ0oM~konMa2pq-U#1Mp!gd_SWhtcc~8c~oTsDdcMQ?2n~~swL^X!1 zU11*XYJom55TMsw%_BXl>M{}2WD-1$=>I;lpg%S*dMmaX&mWYf)OX8wAK-SRl0BBP zzA@l068Eb=Je9%tc+6~qLwaHz#^ta7gMzMGf#fH4fLLsE5pRxwC2(Mzkx5C zw7vTiDbg1x93}BMYY{lp9EWlJymk`-D?Ba)BQ@35Zb40#md}y7xw&?h46NCd_GU-K zGI~0z+h?G82a$RIW$drvbmGF!xHz=yk>lgp$C4bf5naT>bUzfw1ow%)-r>PKoE9&}$SiH|ip)kt z;9-&()<{0ja4c^nGqS!$e$9FYSWnjAN}suVph5bo_MONsLq)<;i7%VV7Q}SCuAH%d zLMNI{m@*=+WwbE;v7kzShVaF25xR7xjPwUtI0G~gn z)vub}A?$;;u$@>@qWUID4EfMbSJ~S<9##^~>E0UgzwDtmQB>KgKoZAQcw_K(e7vcq zAA7nD>s5sh!>rjK9pa~8^1;Z=yzbSpAbkkHfEcxOJG3z+EaTK?Zugxnoo=pt88IRB zXqvOYzUEJJ`affS{VZyCta=bM;-fvk!OecIa2$I<`9PXsUL-1va znVb_V!RY8z_|?}$RmTLdcr4+t_)jMmam~}=)=*0G5i;mb3z(sIDqT#g^%Ni&E%1^D zxmd*BDX1hwOAMqQ53VV{l$S%))EB}$4@SA~I-!oT#l{MVq=`x0^J*IAm&Bj#lmoks zsV3eYGvXiAJ>LhsR?z0xok{K}D)7F!cKRJEn;w2ma^s(W&8C&fUJ#wIu}K~9{;iJ` zH7V+;&Y07SBe>e*SRwOfDaLdW{3^W~N-9ey+i^AYPtSZ%MR5$%^s!g*9}f92+4qdU zez3N;p8D=)dq_%2<#NPf2#I<+J+C|eXf$>91vam*um4Wbhle2)I7PA;|LpHiEyS2+ z=j4oqCV!Td)_@;X4_U4Oj#b?X%r!MNt5P24S5Hr-&PB2^I~EDQrzJ+LQ&5`Il-XqA zuPV&m*P{AVpREo2^EpZEM`;L!95dy8$Mhr>ZR`JAw+l%=9y=oc`d5Sq#zg$6@4gW{ z2J=(+Iw<&DyGE3XZv*u-;i2_K*ra6KfXziFGQ=tdW*-Hc?S!T z(NpC~VI@4sDC&1sExFsz464|E@h0e$ua0-Dt!X(IIl9ep#S#4 ziX_7C_Rwm6c+sOxLET(7w&Mi~12b1084)Wtt!@OS^rGpGU|KAwfC_4UJLiEX- zP`(_BpzXDZiIo+7*@&FrpGQMaqM;1=LM!ADmdGOXw>T%bmFXZD(eQ@JJ|fnb5VLu5 zb`{27Qz|WDnf1K0Rd@c|MnmaMfcVQ*h%NeMy||&xOt^)Gq&t%=ToEASU8UE@Lw({m z4XkPQtA}WH?{uD zu}%YCK0+eEf^RhsA38sOxh^Q36O9&O_Cq5^pCX91hLi|sfAi6d|0(@-?p7Gol(9%!s zvY~TS4YaVaeOvM}tuHPtaoMo1d>ro9JuIGDBm`C*K@G{@^;9WeMbmm--&IwXc%;Q$ zCfQs-`80gFaeusrHtBSLqpqfoERlkOa_VBcQcsNF&|l$_YZ`k9)Q7EWFEuUO?>RO8 zZc#P#_4PHvz~AcWb!587$e10A4Am*-kP}$Z20e7PzEV4`&8RkGm)84!64;uwgc!_h$W6()k z+XeP?;6rc!)b!Lki}m?P#=3eRH;9~%wr0n7NdmW7>EG|!)PRA-6JV?TPd&Z!P+q~_nc0`O(Gln;7?+~vWa z9EAJ&$1D-bYbAvTRQDr-{^X$gl!lh&9{p#HlQ&zi> z%d#}SnT(Bm+UwCf5|9O2kMo-~vY0D>&1azzOQK4JoWg7bqhL_-6O>^_qJ-&7T_GMj z&{d}|SV4R#g$6OCj9Guk9IafN*Omq1tb70J6fDI@qR+Q5DJ(XTrAhV<9 zS$!p$kqdI#O=pMB`T#}l9RoIvVqD6&1d2=@kM+LQ715}8Bn(JQkX0{`V9(zx1fvQ; zLG|V1HwOHSWI;D)2(NeGt2)&jro$XR0{L1zP= z(Vzk#3)E)mYu99*qIUeQ{2mxFoJ<6K!`!b51|E~bO{oc%jQ*Z=cD0+mi(C`MMT0y& zDC-@3JN>5bmJk&HW~BF-+Jur!@-Eek-Yssfek=jz-{kztOH>tKV9wm-0h^W%l+UX#F1wq)~lB}t= z?q*_bk5um3PfOJ!l*tAZcCqlvt&{XP5Vt*Dr5W_LD%_^7-s zYA0b$eB?hfI~#Po8zht-#UVXAX*l`+i-JObQMW$o3SDZ)@RXJgyF8tlnI4wEi5^(n`yI&J!$OQ-?PPl&1onO?v7%w5DiNX?gHkZcFcyYdis#Jjc`uhBPF|)X_QRaG8pMk^SK6`ZccI4)=xw!1i zgz-@$tZ{jd87k=-{S*C-SaKmZ^VjTRn9Nd6`EXgh;Hf}{FzM?g zQ=$AGrF&jWLqkLJmzUVp0jp1^ai;^}eU!p4jI0J`f~*5HOc;F&IvYRsG4^m0jOL)A zRzwL2I@pk)gCw~u#t2+~&tc|m;!H{Xgt0<{7d8$V3HA3}_jk8s!>{#C0KRMe=h{zV#)M?A0%Nm zm&YzUE+WEh_9|U*&NO~Ke{@A2%}T>8i@f`pnt(gyG%PBKrhY_T+BHC6WcqEx{7A;z z!JzAw{%qkFuVfj$UR0DNoQpDo@6guWeIeL7$5@_ViJ7L@QfuK_9?h7|m7Sum|1xw| zSCZ@QKgM4sg>jwMZc%F86Au{a1L|LVn>HC*+q0CCx?6qOepVeaq2!F04`EgE@DOH= ztoPuL5&g(SFdDs-{<=h^^5jAm+JafPKiMVei8_xQmkNmgH48Lsw>#-wc@0Jer zmJP=mO)18Ia~P(_NLrvl{q-J=*5!rwdg<}h<>eh$R%X@^HdC(F{oR=Z*%>B3L3VE= z*f^ymXhlBDyly0ag~=I<7}SRt|^E{(nylbLBVkn|D0 zj%fwa9nNK)bt=O*@!_fHIRECsLEasi83=a>2*d&wwy@At#D6?cQct0p1dtrO6D)D& ztMQTMk9MI>yywmJyhdg#D~fN|%#VmACR!=EVLDieC+0uZ5(H5CpM>|;SqpFnC>g0) V_ay9mdAsWcG*q;qwMtfz{|8C@VfFw3 literal 0 HcmV?d00001 diff --git a/addons/screensaver.gles.noise/addon.xml b/addons/screensaver.gles.noise/addon.xml new file mode 100644 index 0000000..ed29862 --- /dev/null +++ b/addons/screensaver.gles.noise/addon.xml @@ -0,0 +1,121 @@ + + + + + + + + Seker die tweede mees psigedeliese sluimerskerm ooit + ربما شاشة التوقف الثانية الأكثر هدوء على الإطلاق + Напэўна, другі найбольш псіхадэлічны ахоўнік экрану + Вероятно вторият най-халюциногенен скрийнсейвър + Probablement el segon estalvi de pantalla més psicodèlic mai creat + Pravděpodobně druhý nejdivočejší šetřič obrazovky všech dob + Mwy na thebyg yr ail arbedwr sgrin mwyaf seicadelig + Formodentlig den anden mest psykedeliske pauseskærm nogensinde + Wahrscheinlich der zweit-psychodelischste Bildschirmschoner überhaupt + Πιθανότατα η δεύτερη πιο ψυχεδελική προφύλαξη οθόνης που έγινε ποτέ + Random noise. Useful for fixing image retention on a plasma TV + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probablemente el segundo salvapantallas más psicodélico jamás creado + Probablemente el segundo protector de pantalla más psicodélico jamás creado + Probablemente el segundo protector de pantalla más psicodélico + Arvatavasti teine kõige psühhedeelsem ekraanisäästja, mis iial tehtud + Ziurrenik inoizko bigarren pantaila-babesle psikodelikoena + Todennäköisesti toiseksi psykedeelisin näytönsäästäjä koskaan + Probablement le deuxième économiseur d'écran le plus psychédélique jamais créé + Probablement le deuxième économiseur d'écran le plus psychédélique + Probabelmente o segundo protector de pantalla máis psicodélico. + כנראה שומר המסך השני בדירוג הפסיכדליות + Vjerojatno drugi najveći psihodelični čuvar zaslona ikad + A második legpszihedelikusabb képernyővédő + Mungkin screensaver paling psikedelik nomor dua yang pernah ada + Líklega í öðru sæti yfir klikkuðustu skjáhvíluna + Probabilmente il secondo salvaschermo più psichedelico di sempre + 世界で2番目にサイケなスクリーンセーバー + 아마도 지금까지 두번째로 가장 환상적인 화면보호기 + Tikriausiai antra labiausiai psichodelinė ekrano užsklanda pasaulyje. + Iespējams viens no vispsihodēliskākajiem ekrānsaudzētājiem pasaulē + Можеби втора нај психоделична заштита на екран + Waarschijnlijk de op één na meest psychedelische schermbeveiliging ooit + Helt sikkert den nest mest psykedeliske skjermspareren som finnes + Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie + Este é provavelmente o segundo melhor protector de ecrã psicadélico de sempre + Provavelmente a segunda mais psicodélica proteção de tela já vista + Probabil al doilea cel mai năucitor screensaver care a existat vreodată + Наверное, вторая из самых психоделических заставок в мире + Förmodligen den näst psykedeliska skärmsläckaren + පෙනෙන විදියට සදා දෙවන මහත් අධිචිත්ත වේගී තිරමෙහෙකරු + Pravdepodobne druhý najviac hypnotizujúci šetrič obrazovky vôbec + Gotovo drugi najbolj psihadelični ohranjevalnik zaslona na svetu + Troligen den näst mest psykedeliska skärmsläckaren någonsin. + Эҳтимол аст, ки имрӯз дар тамоми ҷаҳон ин пардаи экран ҷои дуюмро мегирад + Muhtemelen insanı hayallere sürükleyen en iyi ikinci ekran koruyucu + Напевно, друга серед найбільш психоделічних заставок + Xứng đáng làm trình bảo vệ màn hình gây ảo giác mạnh thứ hai + 或许是排名第二的迷幻效果屏幕保护程序 + 可能是有史以來第二最夢幻的螢幕保護程式保護程式 + Seker die tweede mees psigedeliese sluimerskerm wat bestaan. Verbeel jou net al daai kleure wat rond beweeg. + ربما شاشة التوقف الثانية الأكثر هدوء في الوجود. فقط حاول تصوير هذه الألوان المتحركة . + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + Вероятно вторият по сила халюциногенен скрийнсейвър създаван някога. Просто се опитайте да съзрете всички тези цветове. + Probablement el segon estalvi de pantalla més psicodèlic que existeix. Intenta imaginar tots aquests colors movent-se. + Pravděpodobně druhý nejdivočejší šetřič obrazovky všech dob. Zkuste si představit všechny ty poletující barvy. + Mwy na thebyg yr ail arbedwr sgrin mwyaf seicadelig sy'n bod. Ceisiwch ddychmygu'r holl liwiau na'n symud o gwmpas. + Formodentlig den anden mest psykedeliske pauseskærm, der eksisterer. Forestil dig alle de farver, der bevæger sig omkring. + Wahrscheinlich der zweit-psychodelischste Bildschirmschoner, den es gibt. Versuche doch alle diese Farben, die sich umher bewegen, festzuhalten. + Πιθανότατα η δεύτερη πιο ψυχεδελική προφύλαξη οθόνης που υπάρχει. Απλά προσπαθήστε να φανταστείτε όλα αυτά τα χρώματα σε κίνηση. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + Probablemente el segundo salvapantallas más psicodélico que existe. Intente imaginarse todos esos colores moviéndose. + Probablemente el segundo protector de pantalla más psicodélico que existe. Solo intente imaginarse todos esos colores moviéndose. + Probablemente el segundo protector de pantallas más psicodélico. Solo trate de captar todos los colores moviéndose alrededor. + Arvatavasti ajaloo teine kõige psühhedeelsem ekraanisäästja. Püüa lihtsalt kujutleda kõiki neid värve, mis ringi liiguvad. + Ziurrenik existitzen den bigarren pantaila-babesle psikodelikoena. Saiatu kolore guzti horiek mugitzen irudikatzen. + Todennäköisesti toiseksi psykedeelisin olemassa oleva näytönsäästäjä. Kuvittelepa vain kaikki nuo värit lentelemässä ympäriinsä. + Probablement le deuxième économiseur d'écran le plus psychédélique de l'histoire. Essayez seulement d'imaginer toutes ces couleurs en mouvement. + Probablement le deuxième économiseur d'écran le plus psychédélique de l'histoire. Essayez seulement d'imaginer toutes ces couleurs en mouvement. + Probabelmente o segundo protector de pantalla máis psicodélico do mundo. Tan só probe a imaxinarse todas esas cores movéndose ó redor. + כנראה שומר המסך השני בדירוג הפסיכדליות שקיים כיום. פשוט נסו לדמיין את כל הצבעים האלו נעים ממקום למקום. + Vjerojatno drugi najveći psihodelični čuvar zaslona koji postoji. Samo pokušajte zamisliti sve te boje koje se gibaju okolo. + Valószínüleg a második legpszihedelikusabb képernyővédő ami létezik. Csak képzeld el mindezt a színkavalkádot mozogni. + Mungkin screensaver paling psikedelik nomor dua yang pernah ada. Coba bayangkan warna-warni itu bergerak ke sana kemari. + Líklega í öðru sæti yfir klikkuðustu skjáhvíluna sem til er. Reyndi bara að ímynda þér alla þessa liti á hreyfingu. + Probabilmente il secondo salvaschermo più psichedelico di sempre. Prova semplicemente a guardare tutti quei colori che si muovono. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + 아마도 존재하는 두번째로 가장 환상적인 화면보호기. 모든 색깔들이 움직이는 것을 상상해보세요. + Turbūt antra labiausiai psichodelinė ekrano užsklanda pasaulyje. Išbandykite ją ir pamatysite judančių spalvų šventę. + Iespējams viens no vispsihodēliskākajiem ekrānsaudzētājiem pasaulē. Pamēģiniet, lai gūtu priekšstatu par krāsu kustību un plūsmu visapkārt. + Можеби втора нај психоделична заштита на екран. Само обидете се да ги согледате сите тие бои кои се движат. + Waarschlijnlijk de op één na meest psychedelische schermbeveliging ooit. Probeer u het voor te stellen: al die kleuren die door elkaar lopen. + Helt sikkert den nest mest psykadeliske skjermsparern i verden. Bare prøv å se for deg alle de fargene som beveger seg rundt. + Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie. Spróbuj i zobacz ferie poruszających się barw. + Provavelmente, o segundo melhor protector de ecrã psicadélico de sempre. Experimente visualizar todas as cores a moverem-se. + Provavelmente a segundo mais psicodélica proteção de tela existente. Experimente ver todas essas cores se movimentando ao redor da tela. + Probabil al doilea cel mai năucitor screensaver care a existat vreodată. Doar încercați să vă imaginați toate acele culori mișcându-se. + Просто попробуйте представить себе все цвета в движении. + Förmodligen den näst psykedeliska skärmsläckaren som finns. Försök bara att uppfatta alla färger som rör sig runt och runt. + පෙනෙන විදියට සදා පවතින දෙවන මහත් අධිචිත්ත වේගී තිරමෙහෙකරු.වටේ තිබෙන එම සියළු වර්ණ ඡායාරූප කිරීමට උත්සාහ කිරීම පමණයි. + Pravdepodobne druhý najviac hypnotizujúci šetrič obrazovky aký vôbec existuje. Iba si skúste predstaviť všetky tie farby pohybujúc sa okolo. + Gotovo drugi najbolj psihadelični ohranjevalnik zaslona na svetu. Samo predstavljajte si vse te barve, ki letijo naokrog. + Troligen den näst mest psykedeliska skärmsläckaren som existerar. Bara tänk dig alla färgerna som rör på sig. + Эҳтимол аст, ки имрӯз дар тамоми ҷаҳон ин пардаи экран ҷои дуюмро мегирад. Танҳо тасаввур кунед, ки чӣ қадар зебо ҳамаи рангҳояш бозӣ мекунанд. + Muhtemelen insanı hayallere sürükleyen en iyi ikinci ekran koruyucu. Ekranda dolaşan tüm renkleri seyretmeye çalışın. + Напевно, друга серед найбільш психоделічних заставок. Лише уявіть усі ці переливи кольорів. + Đây có thể là trình bảo vệ màn hình gây ảo giác mạnh thứ hai tại thời điểm này. Hãy thử xem các hình ảnh tạo nên từ các màu sắc di chuyển khắp nơi + 或许是排名第二的迷幻效果屏幕保护程序。你将看到所有颜色满处乱飞。 + 可能是現存第二最夢幻的螢幕保護程式。快來嘗試想像一下所有移動中的色彩變化。 + all + + diff --git a/addons/screensaver.gles.noise/icon.png b/addons/screensaver.gles.noise/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a6784afc53d95a655742f9b7db247471fc52a105 GIT binary patch literal 5657 zcmd5=%_yf)hI}rNdW+$&`^i!0RZ0Z5f2~+-G*^$ zdC}XzSS?I;T#Z?V*$oLUxq6 zE9lIcr+wgK*+sd{`L^(P-8a3lYQ&E}UA|67z<}ug9WVyQrWc4}FGAmYqBl>1bONzv zC+?Ez!vf2~`U3PpH94L~S5!~e3>{ftnwqYDHkO#%!3Eds-f-vU<#x3ok^P!#c&&Mj zzqU{)hEWAAwchi(#n$&f83OU#4u794xU3pF;=hiq3z=Iyzy>gw6Z9jc|#L>RDEfDP^{ zw1VZPJzaiK3d}>fS&jI4kUS-TdMLJX#O%vmQUu7;ka*&oPz;Dus2GWytedNb0VVFo z=kC>iea=I}ER0DJ)^vpcb6$-b?rJ8LX9^5>nJ}Xg6!55(@FZlJA9&Z2c z!+;}TZ4V{di+qq?Xf=8;-O}LTGYj|nvT$g|IzXn0C-KCg_?NN3#>vI=#XWhw?Wi^+ z^5c(n?^!b~o5{zi??H}^N`*^@ANh^k1$*V8eb%ysgxv^$Gs<9_i2oVtX{VnGo`hq+ zylhDS*9eiVK!Mjpe5VF{IPTn9Mgq4AI)Ep>o|344+WxA@`KN8z(B22(wE%zr&1Wb(!JYd`bl)I`2oCbOeV)*7eJt@Rok8|jq%ZHWu5Ak2x( z`UFt5tE>DaycfyOpHB3v>FWnYB4&^~-QE=wrbh62 zn@A$`0LoZf#ctGs9~hCsirP#OM22xhr~DjQh$2s$IAh95$xVO& zcI->QTatShXtbcLfgS3SfEPF^93rtz6YI-*0?-UuSjH{Z8 z>at!RLM1%!4T?6mr+tW3;$0ZF^9h1MSU+qSkfN+qVan0pj3C9$(Z zjg$p*`xnG=-UpXTg`QTr$bZ+KkmkjM7f<<(oJvf&LnN6o5O;~iCm}~b@LEPWSb~QN zJvrf{&fR@?rCsTVW+tuPtR{j_|4_OdieB5wpOErln*d&^`xYqJB}54VP*d3 z&)HR_0%}>q-`}5IKKOF?%tuz&P=uHyk2`%>v1o6vPOEdVi%Kw@Nh zsjWuVK={$ASC{xw0)zYuzvdKk^U%<6W5MG3WD#Ejd`MLp9;CT{9CUmC2jO!ymsF@> zEJt^3H~ZaVHI7i*i^D?A^p=+9^>{;x7xfK)b&!IRtzcI_RMEO>f}0;4fI<;(ly1&N$3` z-lic`n(t!wdUcV5JB2Ggdf&nj!kCklV<1M7J})(5`kK99*4W%!E?~c>2~v?P3~@C^ zlX#f*?4#Xl7f;*0*W9*Ap;Hk+8EhNdv&>DKEVtG>FH{2TPBet|=osjln*M%-LGu2z zL6!@uFSC7y!qJ0oM~konMa2pq-U#1Mp!gd_SWhtcc~8c~oTsDdcMQ?2n~~swL^X!1 zU11*XYJom55TMsw%_BXl>M{}2WD-1$=>I;lpg%S*dMmaX&mWYf)OX8wAK-SRl0BBP zzA@l068Eb=Je9%tc+6~qLwaHz#^ta7gMzMGf#fH4fLLsE5pRxwC2(Mzkx5C zw7vTiDbg1x93}BMYY{lp9EWlJymk`-D?Ba)BQ@35Zb40#md}y7xw&?h46NCd_GU-K zGI~0z+h?G82a$RIW$drvbmGF!xHz=yk>lgp$C4bf5naT>bUzfw1ow%)-r>PKoE9&}$SiH|ip)kt z;9-&()<{0ja4c^nGqS!$e$9FYSWnjAN}suVph5bo_MONsLq)<;i7%VV7Q}SCuAH%d zLMNI{m@*=+WwbE;v7kzShVaF25xR7xjPwUtI0G~gn z)vub}A?$;;u$@>@qWUID4EfMbSJ~S<9##^~>E0UgzwDtmQB>KgKoZAQcw_K(e7vcq zAA7nD>s5sh!>rjK9pa~8^1;Z=yzbSpAbkkHfEcxOJG3z+EaTK?Zugxnoo=pt88IRB zXqvOYzUEJJ`affS{VZyCta=bM;-fvk!OecIa2$I<`9PXsUL-1va znVb_V!RY8z_|?}$RmTLdcr4+t_)jMmam~}=)=*0G5i;mb3z(sIDqT#g^%Ni&E%1^D zxmd*BDX1hwOAMqQ53VV{l$S%))EB}$4@SA~I-!oT#l{MVq=`x0^J*IAm&Bj#lmoks zsV3eYGvXiAJ>LhsR?z0xok{K}D)7F!cKRJEn;w2ma^s(W&8C&fUJ#wIu}K~9{;iJ` zH7V+;&Y07SBe>e*SRwOfDaLdW{3^W~N-9ey+i^AYPtSZ%MR5$%^s!g*9}f92+4qdU zez3N;p8D=)dq_%2<#NPf2#I<+J+C|eXf$>91vam*um4Wbhle2)I7PA;|LpHiEyS2+ z=j4oqCV!Td)_@;X4_U4Oj#b?X%r!MNt5P24S5Hr-&PB2^I~EDQrzJ+LQ&5`Il-XqA zuPV&m*P{AVpREo2^EpZEM`;L!95dy8$Mhr>ZR`JAw+l%=9y=oc`d5Sq#zg$6@4gW{ z2J=(+Iw<&DyGE3XZv*u-;i2_K*ra6KfXziFGQ=tdW*-Hc?S!T z(NpC~VI@4sDC&1sExFsz464|E@h0e$ua0-Dt!X(IIl9ep#S#4 ziX_7C_Rwm6c+sOxLET(7w&Mi~12b1084)Wtt!@OS^rGpGU|KAwfC_4UJLiEX- zP`(_BpzXDZiIo+7*@&FrpGQMaqM;1=LM!ADmdGOXw>T%bmFXZD(eQ@JJ|fnb5VLu5 zb`{27Qz|WDnf1K0Rd@c|MnmaMfcVQ*h%NeMy||&xOt^)Gq&t%=ToEASU8UE@Lw({m z4XkPQtA}WH?{uD zu}%YCK0+eEf^RhsA38sOxh^Q36O9&O_Cq5^pCX91hLi|sfAi6d|0(@-?p7Gol(9%!s zvY~TS4YaVaeOvM}tuHPtaoMo1d>ro9JuIGDBm`C*K@G{@^;9WeMbmm--&IwXc%;Q$ zCfQs-`80gFaeusrHtBSLqpqfoERlkOa_VBcQcsNF&|l$_YZ`k9)Q7EWFEuUO?>RO8 zZc#P#_4PHvz~AcWb!587$e10A4Am*-kP}$Z20e7PzEV4`&8RkGm)84!64;uwgc!_h$W6()k z+XeP?;6rc!)b!Lki}m?P#=3eRH;9~%wr0n7NdmW7>EG|!)PRA-6JV?TPd&Z!P+q~_nc0`O(Gln;7?+~vWa z9EAJ&$1D-bYbAvTRQDr-{^X$gl!lh&9{p#HlQ&zi> z%d#}SnT(Bm+UwCf5|9O2kMo-~vY0D>&1azzOQK4JoWg7bqhL_-6O>^_qJ-&7T_GMj z&{d}|SV4R#g$6OCj9Guk9IafN*Omq1tb70J6fDI@qR+Q5DJ(XTrAhV<9 zS$!p$kqdI#O=pMB`T#}l9RoIvVqD6&1d2=@kM+LQ715}8Bn(JQkX0{`V9(zx1fvQ; zLG|V1HwOHSWI;D)2(NeGt2)&jro$XR0{L1zP= z(Vzk#3)E)mYu99*qIUeQ{2mxFoJ<6K!`!b51|E~bO{oc%jQ*Z=cD0+mi(C`MMT0y& zDC-@3JN>5bmJk&HW~BF-+Jur!@-Eek-Yssfek=jz-{kztOH>tKV9wm-0h^W%l+UX#F1wq)~lB}t= z?q*_bk5um3PfOJ!l*tAZcCqlvt&{XP5Vt*Dr5W_LD%_^7-s zYA0b$eB?hfI~#Po8zht-#UVXAX*l`+i-JObQMW$o3SDZ)@RXJgyF8tlnI4wEi5^(n`yI&J!$OQ-?PPl&1onO?v7%w5DiNX?gHkZcFcyYdis#Jjc`uhBPF|)X_QRaG8pMk^SK6`ZccI4)=xw!1i zgz-@$tZ{jd87k=-{S*C-SaKmZ^VjTRn9Nd6`EXgh;Hf}{FzM?g zQ=$AGrF&jWLqkLJmzUVp0jp1^ai;^}eU!p4jI0J`f~*5HOc;F&IvYRsG4^m0jOL)A zRzwL2I@pk)gCw~u#t2+~&tc|m;!H{Xgt0<{7d8$V3HA3}_jk8s!>{#C0KRMe=h{zV#)M?A0%Nm zm&YzUE+WEh_9|U*&NO~Ke{@A2%}T>8i@f`pnt(gyG%PBKrhY_T+BHC6WcqEx{7A;z z!JzAw{%qkFuVfj$UR0DNoQpDo@6guWeIeL7$5@_ViJ7L@QfuK_9?h7|m7Sum|1xw| zSCZ@QKgM4sg>jwMZc%F86Au{a1L|LVn>HC*+q0CCx?6qOepVeaq2!F04`EgE@DOH= ztoPuL5&g(SFdDs-{<=h^^5jAm+JafPKiMVei8_xQmkNmgH48Lsw>#-wc@0Jer zmJP=mO)18Ia~P(_NLrvl{q-J=*5!rwdg<}h<>eh$R%X@^HdC(F{oR=Z*%>B3L3VE= z*f^ymXhlBDyly0ag~=I<7}SRt|^E{(nylbLBVkn|D0 zj%fwa9nNK)bt=O*@!_fHIRECsLEasi83=a>2*d&wwy@At#D6?cQct0p1dtrO6D)D& ztMQTMk9MI>yywmJyhdg#D~fN|%#VmACR!=EVLDieC+0uZ5(H5CpM>|;SqpFnC>g0) V_ay9mdAsWcG*q;qwMtfz{|8C@VfFw3 literal 0 HcmV?d00001 diff --git a/addons/screensaver.gles.plasma/addon.xml b/addons/screensaver.gles.plasma/addon.xml new file mode 100644 index 0000000..3f334f1 --- /dev/null +++ b/addons/screensaver.gles.plasma/addon.xml @@ -0,0 +1,121 @@ + + + + + + + + Seker die tweede mees psigedeliese sluimerskerm ooit + ربما شاشة التوقف الثانية الأكثر هدوء على الإطلاق + Напэўна, другі найбольш псіхадэлічны ахоўнік экрану + Вероятно вторият най-халюциногенен скрийнсейвър + Probablement el segon estalvi de pantalla més psicodèlic mai creat + Pravděpodobně druhý nejdivočejší šetřič obrazovky všech dob + Mwy na thebyg yr ail arbedwr sgrin mwyaf seicadelig + Formodentlig den anden mest psykedeliske pauseskærm nogensinde + Wahrscheinlich der zweit-psychodelischste Bildschirmschoner überhaupt + Πιθανότατα η δεύτερη πιο ψυχεδελική προφύλαξη οθόνης που έγινε ποτέ + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probablemente el segundo salvapantallas más psicodélico jamás creado + Probablemente el segundo protector de pantalla más psicodélico jamás creado + Probablemente el segundo protector de pantalla más psicodélico + Arvatavasti teine kõige psühhedeelsem ekraanisäästja, mis iial tehtud + Ziurrenik inoizko bigarren pantaila-babesle psikodelikoena + Todennäköisesti toiseksi psykedeelisin näytönsäästäjä koskaan + Probablement le deuxième économiseur d'écran le plus psychédélique jamais créé + Probablement le deuxième économiseur d'écran le plus psychédélique + Probabelmente o segundo protector de pantalla máis psicodélico. + כנראה שומר המסך השני בדירוג הפסיכדליות + Vjerojatno drugi najveći psihodelični čuvar zaslona ikad + A második legpszihedelikusabb képernyővédő + Mungkin screensaver paling psikedelik nomor dua yang pernah ada + Líklega í öðru sæti yfir klikkuðustu skjáhvíluna + Probabilmente il secondo salvaschermo più psichedelico di sempre + 世界で2番目にサイケなスクリーンセーバー + 아마도 지금까지 두번째로 가장 환상적인 화면보호기 + Tikriausiai antra labiausiai psichodelinė ekrano užsklanda pasaulyje. + Iespējams viens no vispsihodēliskākajiem ekrānsaudzētājiem pasaulē + Можеби втора нај психоделична заштита на екран + Waarschijnlijk de op één na meest psychedelische schermbeveiliging ooit + Helt sikkert den nest mest psykedeliske skjermspareren som finnes + Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie + Este é provavelmente o segundo melhor protector de ecrã psicadélico de sempre + Provavelmente a segunda mais psicodélica proteção de tela já vista + Probabil al doilea cel mai năucitor screensaver care a existat vreodată + Наверное, вторая из самых психоделических заставок в мире + Förmodligen den näst psykedeliska skärmsläckaren + පෙනෙන විදියට සදා දෙවන මහත් අධිචිත්ත වේගී තිරමෙහෙකරු + Pravdepodobne druhý najviac hypnotizujúci šetrič obrazovky vôbec + Gotovo drugi najbolj psihadelični ohranjevalnik zaslona na svetu + Troligen den näst mest psykedeliska skärmsläckaren någonsin. + Эҳтимол аст, ки имрӯз дар тамоми ҷаҳон ин пардаи экран ҷои дуюмро мегирад + Muhtemelen insanı hayallere sürükleyen en iyi ikinci ekran koruyucu + Напевно, друга серед найбільш психоделічних заставок + Xứng đáng làm trình bảo vệ màn hình gây ảo giác mạnh thứ hai + 或许是排名第二的迷幻效果屏幕保护程序 + 可能是有史以來第二最夢幻的螢幕保護程式保護程式 + Seker die tweede mees psigedeliese sluimerskerm wat bestaan. Verbeel jou net al daai kleure wat rond beweeg. + ربما شاشة التوقف الثانية الأكثر هدوء في الوجود. فقط حاول تصوير هذه الألوان المتحركة . + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + Вероятно вторият по сила халюциногенен скрийнсейвър създаван някога. Просто се опитайте да съзрете всички тези цветове. + Probablement el segon estalvi de pantalla més psicodèlic que existeix. Intenta imaginar tots aquests colors movent-se. + Pravděpodobně druhý nejdivočejší šetřič obrazovky všech dob. Zkuste si představit všechny ty poletující barvy. + Mwy na thebyg yr ail arbedwr sgrin mwyaf seicadelig sy'n bod. Ceisiwch ddychmygu'r holl liwiau na'n symud o gwmpas. + Formodentlig den anden mest psykedeliske pauseskærm, der eksisterer. Forestil dig alle de farver, der bevæger sig omkring. + Wahrscheinlich der zweit-psychodelischste Bildschirmschoner, den es gibt. Versuche doch alle diese Farben, die sich umher bewegen, festzuhalten. + Πιθανότατα η δεύτερη πιο ψυχεδελική προφύλαξη οθόνης που υπάρχει. Απλά προσπαθήστε να φανταστείτε όλα αυτά τα χρώματα σε κίνηση. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + Probablemente el segundo salvapantallas más psicodélico que existe. Intente imaginarse todos esos colores moviéndose. + Probablemente el segundo protector de pantalla más psicodélico que existe. Solo intente imaginarse todos esos colores moviéndose. + Probablemente el segundo protector de pantallas más psicodélico. Solo trate de captar todos los colores moviéndose alrededor. + Arvatavasti ajaloo teine kõige psühhedeelsem ekraanisäästja. Püüa lihtsalt kujutleda kõiki neid värve, mis ringi liiguvad. + Ziurrenik existitzen den bigarren pantaila-babesle psikodelikoena. Saiatu kolore guzti horiek mugitzen irudikatzen. + Todennäköisesti toiseksi psykedeelisin olemassa oleva näytönsäästäjä. Kuvittelepa vain kaikki nuo värit lentelemässä ympäriinsä. + Probablement le deuxième économiseur d'écran le plus psychédélique de l'histoire. Essayez seulement d'imaginer toutes ces couleurs en mouvement. + Probablement le deuxième économiseur d'écran le plus psychédélique de l'histoire. Essayez seulement d'imaginer toutes ces couleurs en mouvement. + Probabelmente o segundo protector de pantalla máis psicodélico do mundo. Tan só probe a imaxinarse todas esas cores movéndose ó redor. + כנראה שומר המסך השני בדירוג הפסיכדליות שקיים כיום. פשוט נסו לדמיין את כל הצבעים האלו נעים ממקום למקום. + Vjerojatno drugi najveći psihodelični čuvar zaslona koji postoji. Samo pokušajte zamisliti sve te boje koje se gibaju okolo. + Valószínüleg a második legpszihedelikusabb képernyővédő ami létezik. Csak képzeld el mindezt a színkavalkádot mozogni. + Mungkin screensaver paling psikedelik nomor dua yang pernah ada. Coba bayangkan warna-warni itu bergerak ke sana kemari. + Líklega í öðru sæti yfir klikkuðustu skjáhvíluna sem til er. Reyndi bara að ímynda þér alla þessa liti á hreyfingu. + Probabilmente il secondo salvaschermo più psichedelico di sempre. Prova semplicemente a guardare tutti quei colori che si muovono. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + 아마도 존재하는 두번째로 가장 환상적인 화면보호기. 모든 색깔들이 움직이는 것을 상상해보세요. + Turbūt antra labiausiai psichodelinė ekrano užsklanda pasaulyje. Išbandykite ją ir pamatysite judančių spalvų šventę. + Iespējams viens no vispsihodēliskākajiem ekrānsaudzētājiem pasaulē. Pamēģiniet, lai gūtu priekšstatu par krāsu kustību un plūsmu visapkārt. + Можеби втора нај психоделична заштита на екран. Само обидете се да ги согледате сите тие бои кои се движат. + Waarschlijnlijk de op één na meest psychedelische schermbeveliging ooit. Probeer u het voor te stellen: al die kleuren die door elkaar lopen. + Helt sikkert den nest mest psykadeliske skjermsparern i verden. Bare prøv å se for deg alle de fargene som beveger seg rundt. + Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie. Spróbuj i zobacz ferie poruszających się barw. + Provavelmente, o segundo melhor protector de ecrã psicadélico de sempre. Experimente visualizar todas as cores a moverem-se. + Provavelmente a segundo mais psicodélica proteção de tela existente. Experimente ver todas essas cores se movimentando ao redor da tela. + Probabil al doilea cel mai năucitor screensaver care a existat vreodată. Doar încercați să vă imaginați toate acele culori mișcându-se. + Просто попробуйте представить себе все цвета в движении. + Förmodligen den näst psykedeliska skärmsläckaren som finns. Försök bara att uppfatta alla färger som rör sig runt och runt. + පෙනෙන විදියට සදා පවතින දෙවන මහත් අධිචිත්ත වේගී තිරමෙහෙකරු.වටේ තිබෙන එම සියළු වර්ණ ඡායාරූප කිරීමට උත්සාහ කිරීම පමණයි. + Pravdepodobne druhý najviac hypnotizujúci šetrič obrazovky aký vôbec existuje. Iba si skúste predstaviť všetky tie farby pohybujúc sa okolo. + Gotovo drugi najbolj psihadelični ohranjevalnik zaslona na svetu. Samo predstavljajte si vse te barve, ki letijo naokrog. + Troligen den näst mest psykedeliska skärmsläckaren som existerar. Bara tänk dig alla färgerna som rör på sig. + Эҳтимол аст, ки имрӯз дар тамоми ҷаҳон ин пардаи экран ҷои дуюмро мегирад. Танҳо тасаввур кунед, ки чӣ қадар зебо ҳамаи рангҳояш бозӣ мекунанд. + Muhtemelen insanı hayallere sürükleyen en iyi ikinci ekran koruyucu. Ekranda dolaşan tüm renkleri seyretmeye çalışın. + Напевно, друга серед найбільш психоделічних заставок. Лише уявіть усі ці переливи кольорів. + Đây có thể là trình bảo vệ màn hình gây ảo giác mạnh thứ hai tại thời điểm này. Hãy thử xem các hình ảnh tạo nên từ các màu sắc di chuyển khắp nơi + 或许是排名第二的迷幻效果屏幕保护程序。你将看到所有颜色满处乱飞。 + 可能是現存第二最夢幻的螢幕保護程式。快來嘗試想像一下所有移動中的色彩變化。 + all + + diff --git a/addons/screensaver.gles.plasma/icon.png b/addons/screensaver.gles.plasma/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a6784afc53d95a655742f9b7db247471fc52a105 GIT binary patch literal 5657 zcmd5=%_yf)hI}rNdW+$&`^i!0RZ0Z5f2~+-G*^$ zdC}XzSS?I;T#Z?V*$oLUxq6 zE9lIcr+wgK*+sd{`L^(P-8a3lYQ&E}UA|67z<}ug9WVyQrWc4}FGAmYqBl>1bONzv zC+?Ez!vf2~`U3PpH94L~S5!~e3>{ftnwqYDHkO#%!3Eds-f-vU<#x3ok^P!#c&&Mj zzqU{)hEWAAwchi(#n$&f83OU#4u794xU3pF;=hiq3z=Iyzy>gw6Z9jc|#L>RDEfDP^{ zw1VZPJzaiK3d}>fS&jI4kUS-TdMLJX#O%vmQUu7;ka*&oPz;Dus2GWytedNb0VVFo z=kC>iea=I}ER0DJ)^vpcb6$-b?rJ8LX9^5>nJ}Xg6!55(@FZlJA9&Z2c z!+;}TZ4V{di+qq?Xf=8;-O}LTGYj|nvT$g|IzXn0C-KCg_?NN3#>vI=#XWhw?Wi^+ z^5c(n?^!b~o5{zi??H}^N`*^@ANh^k1$*V8eb%ysgxv^$Gs<9_i2oVtX{VnGo`hq+ zylhDS*9eiVK!Mjpe5VF{IPTn9Mgq4AI)Ep>o|344+WxA@`KN8z(B22(wE%zr&1Wb(!JYd`bl)I`2oCbOeV)*7eJt@Rok8|jq%ZHWu5Ak2x( z`UFt5tE>DaycfyOpHB3v>FWnYB4&^~-QE=wrbh62 zn@A$`0LoZf#ctGs9~hCsirP#OM22xhr~DjQh$2s$IAh95$xVO& zcI->QTatShXtbcLfgS3SfEPF^93rtz6YI-*0?-UuSjH{Z8 z>at!RLM1%!4T?6mr+tW3;$0ZF^9h1MSU+qSkfN+qVan0pj3C9$(Z zjg$p*`xnG=-UpXTg`QTr$bZ+KkmkjM7f<<(oJvf&LnN6o5O;~iCm}~b@LEPWSb~QN zJvrf{&fR@?rCsTVW+tuPtR{j_|4_OdieB5wpOErln*d&^`xYqJB}54VP*d3 z&)HR_0%}>q-`}5IKKOF?%tuz&P=uHyk2`%>v1o6vPOEdVi%Kw@Nh zsjWuVK={$ASC{xw0)zYuzvdKk^U%<6W5MG3WD#Ejd`MLp9;CT{9CUmC2jO!ymsF@> zEJt^3H~ZaVHI7i*i^D?A^p=+9^>{;x7xfK)b&!IRtzcI_RMEO>f}0;4fI<;(ly1&N$3` z-lic`n(t!wdUcV5JB2Ggdf&nj!kCklV<1M7J})(5`kK99*4W%!E?~c>2~v?P3~@C^ zlX#f*?4#Xl7f;*0*W9*Ap;Hk+8EhNdv&>DKEVtG>FH{2TPBet|=osjln*M%-LGu2z zL6!@uFSC7y!qJ0oM~konMa2pq-U#1Mp!gd_SWhtcc~8c~oTsDdcMQ?2n~~swL^X!1 zU11*XYJom55TMsw%_BXl>M{}2WD-1$=>I;lpg%S*dMmaX&mWYf)OX8wAK-SRl0BBP zzA@l068Eb=Je9%tc+6~qLwaHz#^ta7gMzMGf#fH4fLLsE5pRxwC2(Mzkx5C zw7vTiDbg1x93}BMYY{lp9EWlJymk`-D?Ba)BQ@35Zb40#md}y7xw&?h46NCd_GU-K zGI~0z+h?G82a$RIW$drvbmGF!xHz=yk>lgp$C4bf5naT>bUzfw1ow%)-r>PKoE9&}$SiH|ip)kt z;9-&()<{0ja4c^nGqS!$e$9FYSWnjAN}suVph5bo_MONsLq)<;i7%VV7Q}SCuAH%d zLMNI{m@*=+WwbE;v7kzShVaF25xR7xjPwUtI0G~gn z)vub}A?$;;u$@>@qWUID4EfMbSJ~S<9##^~>E0UgzwDtmQB>KgKoZAQcw_K(e7vcq zAA7nD>s5sh!>rjK9pa~8^1;Z=yzbSpAbkkHfEcxOJG3z+EaTK?Zugxnoo=pt88IRB zXqvOYzUEJJ`affS{VZyCta=bM;-fvk!OecIa2$I<`9PXsUL-1va znVb_V!RY8z_|?}$RmTLdcr4+t_)jMmam~}=)=*0G5i;mb3z(sIDqT#g^%Ni&E%1^D zxmd*BDX1hwOAMqQ53VV{l$S%))EB}$4@SA~I-!oT#l{MVq=`x0^J*IAm&Bj#lmoks zsV3eYGvXiAJ>LhsR?z0xok{K}D)7F!cKRJEn;w2ma^s(W&8C&fUJ#wIu}K~9{;iJ` zH7V+;&Y07SBe>e*SRwOfDaLdW{3^W~N-9ey+i^AYPtSZ%MR5$%^s!g*9}f92+4qdU zez3N;p8D=)dq_%2<#NPf2#I<+J+C|eXf$>91vam*um4Wbhle2)I7PA;|LpHiEyS2+ z=j4oqCV!Td)_@;X4_U4Oj#b?X%r!MNt5P24S5Hr-&PB2^I~EDQrzJ+LQ&5`Il-XqA zuPV&m*P{AVpREo2^EpZEM`;L!95dy8$Mhr>ZR`JAw+l%=9y=oc`d5Sq#zg$6@4gW{ z2J=(+Iw<&DyGE3XZv*u-;i2_K*ra6KfXziFGQ=tdW*-Hc?S!T z(NpC~VI@4sDC&1sExFsz464|E@h0e$ua0-Dt!X(IIl9ep#S#4 ziX_7C_Rwm6c+sOxLET(7w&Mi~12b1084)Wtt!@OS^rGpGU|KAwfC_4UJLiEX- zP`(_BpzXDZiIo+7*@&FrpGQMaqM;1=LM!ADmdGOXw>T%bmFXZD(eQ@JJ|fnb5VLu5 zb`{27Qz|WDnf1K0Rd@c|MnmaMfcVQ*h%NeMy||&xOt^)Gq&t%=ToEASU8UE@Lw({m z4XkPQtA}WH?{uD zu}%YCK0+eEf^RhsA38sOxh^Q36O9&O_Cq5^pCX91hLi|sfAi6d|0(@-?p7Gol(9%!s zvY~TS4YaVaeOvM}tuHPtaoMo1d>ro9JuIGDBm`C*K@G{@^;9WeMbmm--&IwXc%;Q$ zCfQs-`80gFaeusrHtBSLqpqfoERlkOa_VBcQcsNF&|l$_YZ`k9)Q7EWFEuUO?>RO8 zZc#P#_4PHvz~AcWb!587$e10A4Am*-kP}$Z20e7PzEV4`&8RkGm)84!64;uwgc!_h$W6()k z+XeP?;6rc!)b!Lki}m?P#=3eRH;9~%wr0n7NdmW7>EG|!)PRA-6JV?TPd&Z!P+q~_nc0`O(Gln;7?+~vWa z9EAJ&$1D-bYbAvTRQDr-{^X$gl!lh&9{p#HlQ&zi> z%d#}SnT(Bm+UwCf5|9O2kMo-~vY0D>&1azzOQK4JoWg7bqhL_-6O>^_qJ-&7T_GMj z&{d}|SV4R#g$6OCj9Guk9IafN*Omq1tb70J6fDI@qR+Q5DJ(XTrAhV<9 zS$!p$kqdI#O=pMB`T#}l9RoIvVqD6&1d2=@kM+LQ715}8Bn(JQkX0{`V9(zx1fvQ; zLG|V1HwOHSWI;D)2(NeGt2)&jro$XR0{L1zP= z(Vzk#3)E)mYu99*qIUeQ{2mxFoJ<6K!`!b51|E~bO{oc%jQ*Z=cD0+mi(C`MMT0y& zDC-@3JN>5bmJk&HW~BF-+Jur!@-Eek-Yssfek=jz-{kztOH>tKV9wm-0h^W%l+UX#F1wq)~lB}t= z?q*_bk5um3PfOJ!l*tAZcCqlvt&{XP5Vt*Dr5W_LD%_^7-s zYA0b$eB?hfI~#Po8zht-#UVXAX*l`+i-JObQMW$o3SDZ)@RXJgyF8tlnI4wEi5^(n`yI&J!$OQ-?PPl&1onO?v7%w5DiNX?gHkZcFcyYdis#Jjc`uhBPF|)X_QRaG8pMk^SK6`ZccI4)=xw!1i zgz-@$tZ{jd87k=-{S*C-SaKmZ^VjTRn9Nd6`EXgh;Hf}{FzM?g zQ=$AGrF&jWLqkLJmzUVp0jp1^ai;^}eU!p4jI0J`f~*5HOc;F&IvYRsG4^m0jOL)A zRzwL2I@pk)gCw~u#t2+~&tc|m;!H{Xgt0<{7d8$V3HA3}_jk8s!>{#C0KRMe=h{zV#)M?A0%Nm zm&YzUE+WEh_9|U*&NO~Ke{@A2%}T>8i@f`pnt(gyG%PBKrhY_T+BHC6WcqEx{7A;z z!JzAw{%qkFuVfj$UR0DNoQpDo@6guWeIeL7$5@_ViJ7L@QfuK_9?h7|m7Sum|1xw| zSCZ@QKgM4sg>jwMZc%F86Au{a1L|LVn>HC*+q0CCx?6qOepVeaq2!F04`EgE@DOH= ztoPuL5&g(SFdDs-{<=h^^5jAm+JafPKiMVei8_xQmkNmgH48Lsw>#-wc@0Jer zmJP=mO)18Ia~P(_NLrvl{q-J=*5!rwdg<}h<>eh$R%X@^HdC(F{oR=Z*%>B3L3VE= z*f^ymXhlBDyly0ag~=I<7}SRt|^E{(nylbLBVkn|D0 zj%fwa9nNK)bt=O*@!_fHIRECsLEasi83=a>2*d&wwy@At#D6?cQct0p1dtrO6D)D& ztMQTMk9MI>yywmJyhdg#D~fN|%#VmACR!=EVLDieC+0uZ5(H5CpM>|;SqpFnC>g0) V_ay9mdAsWcG*q;qwMtfz{|8C@VfFw3 literal 0 HcmV?d00001 diff --git a/addons/screensaver.gles.plasma2/addon.xml b/addons/screensaver.gles.plasma2/addon.xml new file mode 100644 index 0000000..e772cc4 --- /dev/null +++ b/addons/screensaver.gles.plasma2/addon.xml @@ -0,0 +1,121 @@ + + + + + + + + Seker die tweede mees psigedeliese sluimerskerm ooit + ربما شاشة التوقف الثانية الأكثر هدوء على الإطلاق + Напэўна, другі найбольш псіхадэлічны ахоўнік экрану + Вероятно вторият най-халюциногенен скрийнсейвър + Probablement el segon estalvi de pantalla més psicodèlic mai creat + Pravděpodobně druhý nejdivočejší šetřič obrazovky všech dob + Mwy na thebyg yr ail arbedwr sgrin mwyaf seicadelig + Formodentlig den anden mest psykedeliske pauseskærm nogensinde + Wahrscheinlich der zweit-psychodelischste Bildschirmschoner überhaupt + Πιθανότατα η δεύτερη πιο ψυχεδελική προφύλαξη οθόνης που έγινε ποτέ + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probablemente el segundo salvapantallas más psicodélico jamás creado + Probablemente el segundo protector de pantalla más psicodélico jamás creado + Probablemente el segundo protector de pantalla más psicodélico + Arvatavasti teine kõige psühhedeelsem ekraanisäästja, mis iial tehtud + Ziurrenik inoizko bigarren pantaila-babesle psikodelikoena + Todennäköisesti toiseksi psykedeelisin näytönsäästäjä koskaan + Probablement le deuxième économiseur d'écran le plus psychédélique jamais créé + Probablement le deuxième économiseur d'écran le plus psychédélique + Probabelmente o segundo protector de pantalla máis psicodélico. + כנראה שומר המסך השני בדירוג הפסיכדליות + Vjerojatno drugi najveći psihodelični čuvar zaslona ikad + A második legpszihedelikusabb képernyővédő + Mungkin screensaver paling psikedelik nomor dua yang pernah ada + Líklega í öðru sæti yfir klikkuðustu skjáhvíluna + Probabilmente il secondo salvaschermo più psichedelico di sempre + 世界で2番目にサイケなスクリーンセーバー + 아마도 지금까지 두번째로 가장 환상적인 화면보호기 + Tikriausiai antra labiausiai psichodelinė ekrano užsklanda pasaulyje. + Iespējams viens no vispsihodēliskākajiem ekrānsaudzētājiem pasaulē + Можеби втора нај психоделична заштита на екран + Waarschijnlijk de op één na meest psychedelische schermbeveiliging ooit + Helt sikkert den nest mest psykedeliske skjermspareren som finnes + Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie + Este é provavelmente o segundo melhor protector de ecrã psicadélico de sempre + Provavelmente a segunda mais psicodélica proteção de tela já vista + Probabil al doilea cel mai năucitor screensaver care a existat vreodată + Наверное, вторая из самых психоделических заставок в мире + Förmodligen den näst psykedeliska skärmsläckaren + පෙනෙන විදියට සදා දෙවන මහත් අධිචිත්ත වේගී තිරමෙහෙකරු + Pravdepodobne druhý najviac hypnotizujúci šetrič obrazovky vôbec + Gotovo drugi najbolj psihadelični ohranjevalnik zaslona na svetu + Troligen den näst mest psykedeliska skärmsläckaren någonsin. + Эҳтимол аст, ки имрӯз дар тамоми ҷаҳон ин пардаи экран ҷои дуюмро мегирад + Muhtemelen insanı hayallere sürükleyen en iyi ikinci ekran koruyucu + Напевно, друга серед найбільш психоделічних заставок + Xứng đáng làm trình bảo vệ màn hình gây ảo giác mạnh thứ hai + 或许是排名第二的迷幻效果屏幕保护程序 + 可能是有史以來第二最夢幻的螢幕保護程式保護程式 + Seker die tweede mees psigedeliese sluimerskerm wat bestaan. Verbeel jou net al daai kleure wat rond beweeg. + ربما شاشة التوقف الثانية الأكثر هدوء في الوجود. فقط حاول تصوير هذه الألوان المتحركة . + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + Вероятно вторият по сила халюциногенен скрийнсейвър създаван някога. Просто се опитайте да съзрете всички тези цветове. + Probablement el segon estalvi de pantalla més psicodèlic que existeix. Intenta imaginar tots aquests colors movent-se. + Pravděpodobně druhý nejdivočejší šetřič obrazovky všech dob. Zkuste si představit všechny ty poletující barvy. + Mwy na thebyg yr ail arbedwr sgrin mwyaf seicadelig sy'n bod. Ceisiwch ddychmygu'r holl liwiau na'n symud o gwmpas. + Formodentlig den anden mest psykedeliske pauseskærm, der eksisterer. Forestil dig alle de farver, der bevæger sig omkring. + Wahrscheinlich der zweit-psychodelischste Bildschirmschoner, den es gibt. Versuche doch alle diese Farben, die sich umher bewegen, festzuhalten. + Πιθανότατα η δεύτερη πιο ψυχεδελική προφύλαξη οθόνης που υπάρχει. Απλά προσπαθήστε να φανταστείτε όλα αυτά τα χρώματα σε κίνηση. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + Probablemente el segundo salvapantallas más psicodélico que existe. Intente imaginarse todos esos colores moviéndose. + Probablemente el segundo protector de pantalla más psicodélico que existe. Solo intente imaginarse todos esos colores moviéndose. + Probablemente el segundo protector de pantallas más psicodélico. Solo trate de captar todos los colores moviéndose alrededor. + Arvatavasti ajaloo teine kõige psühhedeelsem ekraanisäästja. Püüa lihtsalt kujutleda kõiki neid värve, mis ringi liiguvad. + Ziurrenik existitzen den bigarren pantaila-babesle psikodelikoena. Saiatu kolore guzti horiek mugitzen irudikatzen. + Todennäköisesti toiseksi psykedeelisin olemassa oleva näytönsäästäjä. Kuvittelepa vain kaikki nuo värit lentelemässä ympäriinsä. + Probablement le deuxième économiseur d'écran le plus psychédélique de l'histoire. Essayez seulement d'imaginer toutes ces couleurs en mouvement. + Probablement le deuxième économiseur d'écran le plus psychédélique de l'histoire. Essayez seulement d'imaginer toutes ces couleurs en mouvement. + Probabelmente o segundo protector de pantalla máis psicodélico do mundo. Tan só probe a imaxinarse todas esas cores movéndose ó redor. + כנראה שומר המסך השני בדירוג הפסיכדליות שקיים כיום. פשוט נסו לדמיין את כל הצבעים האלו נעים ממקום למקום. + Vjerojatno drugi najveći psihodelični čuvar zaslona koji postoji. Samo pokušajte zamisliti sve te boje koje se gibaju okolo. + Valószínüleg a második legpszihedelikusabb képernyővédő ami létezik. Csak képzeld el mindezt a színkavalkádot mozogni. + Mungkin screensaver paling psikedelik nomor dua yang pernah ada. Coba bayangkan warna-warni itu bergerak ke sana kemari. + Líklega í öðru sæti yfir klikkuðustu skjáhvíluna sem til er. Reyndi bara að ímynda þér alla þessa liti á hreyfingu. + Probabilmente il secondo salvaschermo più psichedelico di sempre. Prova semplicemente a guardare tutti quei colori che si muovono. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + 아마도 존재하는 두번째로 가장 환상적인 화면보호기. 모든 색깔들이 움직이는 것을 상상해보세요. + Turbūt antra labiausiai psichodelinė ekrano užsklanda pasaulyje. Išbandykite ją ir pamatysite judančių spalvų šventę. + Iespējams viens no vispsihodēliskākajiem ekrānsaudzētājiem pasaulē. Pamēģiniet, lai gūtu priekšstatu par krāsu kustību un plūsmu visapkārt. + Можеби втора нај психоделична заштита на екран. Само обидете се да ги согледате сите тие бои кои се движат. + Waarschlijnlijk de op één na meest psychedelische schermbeveliging ooit. Probeer u het voor te stellen: al die kleuren die door elkaar lopen. + Helt sikkert den nest mest psykadeliske skjermsparern i verden. Bare prøv å se for deg alle de fargene som beveger seg rundt. + Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie. Spróbuj i zobacz ferie poruszających się barw. + Provavelmente, o segundo melhor protector de ecrã psicadélico de sempre. Experimente visualizar todas as cores a moverem-se. + Provavelmente a segundo mais psicodélica proteção de tela existente. Experimente ver todas essas cores se movimentando ao redor da tela. + Probabil al doilea cel mai năucitor screensaver care a existat vreodată. Doar încercați să vă imaginați toate acele culori mișcându-se. + Просто попробуйте представить себе все цвета в движении. + Förmodligen den näst psykedeliska skärmsläckaren som finns. Försök bara att uppfatta alla färger som rör sig runt och runt. + පෙනෙන විදියට සදා පවතින දෙවන මහත් අධිචිත්ත වේගී තිරමෙහෙකරු.වටේ තිබෙන එම සියළු වර්ණ ඡායාරූප කිරීමට උත්සාහ කිරීම පමණයි. + Pravdepodobne druhý najviac hypnotizujúci šetrič obrazovky aký vôbec existuje. Iba si skúste predstaviť všetky tie farby pohybujúc sa okolo. + Gotovo drugi najbolj psihadelični ohranjevalnik zaslona na svetu. Samo predstavljajte si vse te barve, ki letijo naokrog. + Troligen den näst mest psykedeliska skärmsläckaren som existerar. Bara tänk dig alla färgerna som rör på sig. + Эҳтимол аст, ки имрӯз дар тамоми ҷаҳон ин пардаи экран ҷои дуюмро мегирад. Танҳо тасаввур кунед, ки чӣ қадар зебо ҳамаи рангҳояш бозӣ мекунанд. + Muhtemelen insanı hayallere sürükleyen en iyi ikinci ekran koruyucu. Ekranda dolaşan tüm renkleri seyretmeye çalışın. + Напевно, друга серед найбільш психоделічних заставок. Лише уявіть усі ці переливи кольорів. + Đây có thể là trình bảo vệ màn hình gây ảo giác mạnh thứ hai tại thời điểm này. Hãy thử xem các hình ảnh tạo nên từ các màu sắc di chuyển khắp nơi + 或许是排名第二的迷幻效果屏幕保护程序。你将看到所有颜色满处乱飞。 + 可能是現存第二最夢幻的螢幕保護程式。快來嘗試想像一下所有移動中的色彩變化。 + all + + diff --git a/addons/screensaver.gles.plasma2/icon.png b/addons/screensaver.gles.plasma2/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a6784afc53d95a655742f9b7db247471fc52a105 GIT binary patch literal 5657 zcmd5=%_yf)hI}rNdW+$&`^i!0RZ0Z5f2~+-G*^$ zdC}XzSS?I;T#Z?V*$oLUxq6 zE9lIcr+wgK*+sd{`L^(P-8a3lYQ&E}UA|67z<}ug9WVyQrWc4}FGAmYqBl>1bONzv zC+?Ez!vf2~`U3PpH94L~S5!~e3>{ftnwqYDHkO#%!3Eds-f-vU<#x3ok^P!#c&&Mj zzqU{)hEWAAwchi(#n$&f83OU#4u794xU3pF;=hiq3z=Iyzy>gw6Z9jc|#L>RDEfDP^{ zw1VZPJzaiK3d}>fS&jI4kUS-TdMLJX#O%vmQUu7;ka*&oPz;Dus2GWytedNb0VVFo z=kC>iea=I}ER0DJ)^vpcb6$-b?rJ8LX9^5>nJ}Xg6!55(@FZlJA9&Z2c z!+;}TZ4V{di+qq?Xf=8;-O}LTGYj|nvT$g|IzXn0C-KCg_?NN3#>vI=#XWhw?Wi^+ z^5c(n?^!b~o5{zi??H}^N`*^@ANh^k1$*V8eb%ysgxv^$Gs<9_i2oVtX{VnGo`hq+ zylhDS*9eiVK!Mjpe5VF{IPTn9Mgq4AI)Ep>o|344+WxA@`KN8z(B22(wE%zr&1Wb(!JYd`bl)I`2oCbOeV)*7eJt@Rok8|jq%ZHWu5Ak2x( z`UFt5tE>DaycfyOpHB3v>FWnYB4&^~-QE=wrbh62 zn@A$`0LoZf#ctGs9~hCsirP#OM22xhr~DjQh$2s$IAh95$xVO& zcI->QTatShXtbcLfgS3SfEPF^93rtz6YI-*0?-UuSjH{Z8 z>at!RLM1%!4T?6mr+tW3;$0ZF^9h1MSU+qSkfN+qVan0pj3C9$(Z zjg$p*`xnG=-UpXTg`QTr$bZ+KkmkjM7f<<(oJvf&LnN6o5O;~iCm}~b@LEPWSb~QN zJvrf{&fR@?rCsTVW+tuPtR{j_|4_OdieB5wpOErln*d&^`xYqJB}54VP*d3 z&)HR_0%}>q-`}5IKKOF?%tuz&P=uHyk2`%>v1o6vPOEdVi%Kw@Nh zsjWuVK={$ASC{xw0)zYuzvdKk^U%<6W5MG3WD#Ejd`MLp9;CT{9CUmC2jO!ymsF@> zEJt^3H~ZaVHI7i*i^D?A^p=+9^>{;x7xfK)b&!IRtzcI_RMEO>f}0;4fI<;(ly1&N$3` z-lic`n(t!wdUcV5JB2Ggdf&nj!kCklV<1M7J})(5`kK99*4W%!E?~c>2~v?P3~@C^ zlX#f*?4#Xl7f;*0*W9*Ap;Hk+8EhNdv&>DKEVtG>FH{2TPBet|=osjln*M%-LGu2z zL6!@uFSC7y!qJ0oM~konMa2pq-U#1Mp!gd_SWhtcc~8c~oTsDdcMQ?2n~~swL^X!1 zU11*XYJom55TMsw%_BXl>M{}2WD-1$=>I;lpg%S*dMmaX&mWYf)OX8wAK-SRl0BBP zzA@l068Eb=Je9%tc+6~qLwaHz#^ta7gMzMGf#fH4fLLsE5pRxwC2(Mzkx5C zw7vTiDbg1x93}BMYY{lp9EWlJymk`-D?Ba)BQ@35Zb40#md}y7xw&?h46NCd_GU-K zGI~0z+h?G82a$RIW$drvbmGF!xHz=yk>lgp$C4bf5naT>bUzfw1ow%)-r>PKoE9&}$SiH|ip)kt z;9-&()<{0ja4c^nGqS!$e$9FYSWnjAN}suVph5bo_MONsLq)<;i7%VV7Q}SCuAH%d zLMNI{m@*=+WwbE;v7kzShVaF25xR7xjPwUtI0G~gn z)vub}A?$;;u$@>@qWUID4EfMbSJ~S<9##^~>E0UgzwDtmQB>KgKoZAQcw_K(e7vcq zAA7nD>s5sh!>rjK9pa~8^1;Z=yzbSpAbkkHfEcxOJG3z+EaTK?Zugxnoo=pt88IRB zXqvOYzUEJJ`affS{VZyCta=bM;-fvk!OecIa2$I<`9PXsUL-1va znVb_V!RY8z_|?}$RmTLdcr4+t_)jMmam~}=)=*0G5i;mb3z(sIDqT#g^%Ni&E%1^D zxmd*BDX1hwOAMqQ53VV{l$S%))EB}$4@SA~I-!oT#l{MVq=`x0^J*IAm&Bj#lmoks zsV3eYGvXiAJ>LhsR?z0xok{K}D)7F!cKRJEn;w2ma^s(W&8C&fUJ#wIu}K~9{;iJ` zH7V+;&Y07SBe>e*SRwOfDaLdW{3^W~N-9ey+i^AYPtSZ%MR5$%^s!g*9}f92+4qdU zez3N;p8D=)dq_%2<#NPf2#I<+J+C|eXf$>91vam*um4Wbhle2)I7PA;|LpHiEyS2+ z=j4oqCV!Td)_@;X4_U4Oj#b?X%r!MNt5P24S5Hr-&PB2^I~EDQrzJ+LQ&5`Il-XqA zuPV&m*P{AVpREo2^EpZEM`;L!95dy8$Mhr>ZR`JAw+l%=9y=oc`d5Sq#zg$6@4gW{ z2J=(+Iw<&DyGE3XZv*u-;i2_K*ra6KfXziFGQ=tdW*-Hc?S!T z(NpC~VI@4sDC&1sExFsz464|E@h0e$ua0-Dt!X(IIl9ep#S#4 ziX_7C_Rwm6c+sOxLET(7w&Mi~12b1084)Wtt!@OS^rGpGU|KAwfC_4UJLiEX- zP`(_BpzXDZiIo+7*@&FrpGQMaqM;1=LM!ADmdGOXw>T%bmFXZD(eQ@JJ|fnb5VLu5 zb`{27Qz|WDnf1K0Rd@c|MnmaMfcVQ*h%NeMy||&xOt^)Gq&t%=ToEASU8UE@Lw({m z4XkPQtA}WH?{uD zu}%YCK0+eEf^RhsA38sOxh^Q36O9&O_Cq5^pCX91hLi|sfAi6d|0(@-?p7Gol(9%!s zvY~TS4YaVaeOvM}tuHPtaoMo1d>ro9JuIGDBm`C*K@G{@^;9WeMbmm--&IwXc%;Q$ zCfQs-`80gFaeusrHtBSLqpqfoERlkOa_VBcQcsNF&|l$_YZ`k9)Q7EWFEuUO?>RO8 zZc#P#_4PHvz~AcWb!587$e10A4Am*-kP}$Z20e7PzEV4`&8RkGm)84!64;uwgc!_h$W6()k z+XeP?;6rc!)b!Lki}m?P#=3eRH;9~%wr0n7NdmW7>EG|!)PRA-6JV?TPd&Z!P+q~_nc0`O(Gln;7?+~vWa z9EAJ&$1D-bYbAvTRQDr-{^X$gl!lh&9{p#HlQ&zi> z%d#}SnT(Bm+UwCf5|9O2kMo-~vY0D>&1azzOQK4JoWg7bqhL_-6O>^_qJ-&7T_GMj z&{d}|SV4R#g$6OCj9Guk9IafN*Omq1tb70J6fDI@qR+Q5DJ(XTrAhV<9 zS$!p$kqdI#O=pMB`T#}l9RoIvVqD6&1d2=@kM+LQ715}8Bn(JQkX0{`V9(zx1fvQ; zLG|V1HwOHSWI;D)2(NeGt2)&jro$XR0{L1zP= z(Vzk#3)E)mYu99*qIUeQ{2mxFoJ<6K!`!b51|E~bO{oc%jQ*Z=cD0+mi(C`MMT0y& zDC-@3JN>5bmJk&HW~BF-+Jur!@-Eek-Yssfek=jz-{kztOH>tKV9wm-0h^W%l+UX#F1wq)~lB}t= z?q*_bk5um3PfOJ!l*tAZcCqlvt&{XP5Vt*Dr5W_LD%_^7-s zYA0b$eB?hfI~#Po8zht-#UVXAX*l`+i-JObQMW$o3SDZ)@RXJgyF8tlnI4wEi5^(n`yI&J!$OQ-?PPl&1onO?v7%w5DiNX?gHkZcFcyYdis#Jjc`uhBPF|)X_QRaG8pMk^SK6`ZccI4)=xw!1i zgz-@$tZ{jd87k=-{S*C-SaKmZ^VjTRn9Nd6`EXgh;Hf}{FzM?g zQ=$AGrF&jWLqkLJmzUVp0jp1^ai;^}eU!p4jI0J`f~*5HOc;F&IvYRsG4^m0jOL)A zRzwL2I@pk)gCw~u#t2+~&tc|m;!H{Xgt0<{7d8$V3HA3}_jk8s!>{#C0KRMe=h{zV#)M?A0%Nm zm&YzUE+WEh_9|U*&NO~Ke{@A2%}T>8i@f`pnt(gyG%PBKrhY_T+BHC6WcqEx{7A;z z!JzAw{%qkFuVfj$UR0DNoQpDo@6guWeIeL7$5@_ViJ7L@QfuK_9?h7|m7Sum|1xw| zSCZ@QKgM4sg>jwMZc%F86Au{a1L|LVn>HC*+q0CCx?6qOepVeaq2!F04`EgE@DOH= ztoPuL5&g(SFdDs-{<=h^^5jAm+JafPKiMVei8_xQmkNmgH48Lsw>#-wc@0Jer zmJP=mO)18Ia~P(_NLrvl{q-J=*5!rwdg<}h<>eh$R%X@^HdC(F{oR=Z*%>B3L3VE= z*f^ymXhlBDyly0ag~=I<7}SRt|^E{(nylbLBVkn|D0 zj%fwa9nNK)bt=O*@!_fHIRECsLEasi83=a>2*d&wwy@At#D6?cQct0p1dtrO6D)D& ztMQTMk9MI>yywmJyhdg#D~fN|%#VmACR!=EVLDieC+0uZ5(H5CpM>|;SqpFnC>g0) V_ay9mdAsWcG*q;qwMtfz{|8C@VfFw3 literal 0 HcmV?d00001 diff --git a/addons/screensaver.gles.solarwinds/addon.xml b/addons/screensaver.gles.solarwinds/addon.xml new file mode 100644 index 0000000..820fa9c --- /dev/null +++ b/addons/screensaver.gles.solarwinds/addon.xml @@ -0,0 +1,119 @@ + + + + + + + + 'n Betoverende deeltjie effek sluimerskerm + أداة ساحرة تؤثر بشاشة التوقف + Ахоўнік экрану з зачаравальнымі эфэктамі часьціцаў + Скрийнсейвър от частици, които очароват + Un estalvi de pantalla amb uns efectes de partícula fascinants + Spořič obrazovky s fascinujícími částicovými efekty + Arbedwr sgrin effeithiau gronynnau llesmeiriol + En tryllebindende pauseskærm med partikeleffekter + Ein faszinierender Bildschirmschoner mit Partikeleffekten + Μία μαγευτική σωματιδιακή προφύλαξη οθόνης + A mesmerising particle effects screensaver + A mesmerising particle effects screensaver + A mesmerising particle effects screensaver + A mesmerizing particle effects screensaver + Un salvapantallas con unos efectos de partículas hipnotizantes + Un protector de pantalla con unos efectos de partículas hipnotizantes + Un sorprendente protector de pantalla de partículas + Hüpnotiseeriv osakeste efektiga ekraanisäästja + Lumoava partikkelitehostenäytönsäästäjä + Un économiseur envoûtant à effets de particules + Un économiseur d'écran hypnotisant à effets de particules + Un hipnotizante protector de pantalla con efectos de partículas + שומר מסך עם אפקט חלקיקים מהפנט + Čuvar zaslona - Očaravajuće kretanje čestica. + Egy igéző részecske-effektus képernyővédő + Penyelamat layar dengan efek partikel yang mencuri perhatian + Dáleiðandi skjáhvíla með brellum með agnir + Un salvaschermo con effetti particellari ipnotizzanti + 幻想的な粒子エフェクトのスクリーンセーバー + 매혹적인 파티클 이펙트 화면보호기 + Įtaigaus dalelių poveikio ekrano užsklanda + Hipnotizējošs daļiņu efekta ekrānsaudzētājs + Заштита на екран со смирувачки честички + Een hypnotiserende schermbeveiliging met partikeleffecten + En hypnotiserende skjermsparer med partikkeleffekter + Wygaszacz hipnotyzujący efektami cząsteczek + Protector de ecrã com um impressionante efeito de partículas + Um protetor de tela hipnotizante com efeitos de partículas + Un srceensaver cu efecte de particule fascinant + Завораживающая заставка с эффектами частиц + En fascinerande skärmsläckare av partikeleffekter + මෝහනය කිරීම් තිරමෙහෙයුම් වෙත ප්‍රයෝගිකව බලපෑම + Fascinujúci šetrič s efektom častíc + Ohranjevalnik zaslona z dih jemajočimi delčki + En hypnotiserande partikeleffektskärmsläckare + Пардаи экрани аҷоиб бо таъсири зарраҳо + Büyüleyici bir parçacık efektli ekran koruyucu + Заставка із частинок, що має гіпнотизуючий ефект + Một trình bảo vệ màn hình với hiệu ứng thôi miên tạo từ các hạt + 一个迷人的粒子效果屏幕保护程序 + 一個令人著迷的粒子效果的螢幕保護程式 + Hierdie is 'n uiters betoverende deeltjie effek sluimerskerm. Jy sal vind dat jy 'n ongelooflike aantal verskillende patrone kan bewerkstellig. + أداة ساحرة جدا تؤثر بشاشة التوقف. ستجد أنك تستطيع أن تحقق عدد مذهل من الأنماط المختلفة. + This is a very mesmerizing particle effects screensaver. You'll find that you can achieve an amazing number of different patterns. + Това е скрийнсейвър, който очарова с частиците си. Ще откриете, че можете да създадете изключително голям брой различни модели. + Aquest és un estalvi de pantalla amb uns efectes de partícules fascinants. Veuràs que pot obtenir un nombre increïble de patrons diferents. + Spořič obrazovky s velmi fascinujícími částicovými efekty. Zjistíte, že můžete dosáhnout úžasného množství různých vzorů. + Mae hwn yn arbedwr sgrin effeithiau gronynnau hynod lesmeiriol. Mae modd cynhyrchu nifer anferthol o batrymau gwahanol. + Dette er en meget tryllebindende pauseskærm med partikeleffekter. Du vil opdage, at man kan opnå et forbløffende antal af forskellige mønstre. + Dies ist ein faszinierender Bildschirmschoner mit Partikeleffekten. Du kannst eine verblüffend große Anzahl an verschiedenen Animationen einstellen. + Αυτή είναι μία μαγευτική σωματιδιακή προφύλαξη οθόνης. Θα διαπιστώσετε ότι μπορείτε να επιτύχετε έναν απίστευτο αριθμό διαφορετικών σχεδίων. + This is a very mesmerising particle effects screensaver. You'll find that you can achieve an amazing number of different patterns. + This is a very mesmerising particle effects screensaver. You'll find that you can achieve an amazing number of different patterns. + This is a very mesmerising particle effects screensaver. You'll find that you can achieve an amazing number of different patterns. + This is a very mesmerizing particle effects screensaver. You'll find that you can achieve an amazing number of different patterns. + Este es un salvapantallas con unos efectos de partículas hipnotizantes. Descubrirás que puedes obtener un número increíble de patrones diferentes. + Este es un protector de pantalla con unos efectos de partículas hipnotizantes. Descubrirás que puedes obtener un número increíble de patrones diferentes. + Éste es un sorprendente protector de pantalla de partículas. Encontrará que puede obtener un gran número de patrones diferentes. + See on väga hüpnotiseeriv osakeste efektiga ekraanisäästja. Võimalik on koostada tohutul hulgal erinevaid mustreid. + Erittäin lumoava partikkelitehostenäytönsäästäjä. Tulet huomaamaan uskomattoman määrän erilaisia kuvioita. + Voici un économiseur d'écran à effets de particules particulièrement envoûtant. Vous trouverez qu'il permet d'obtenir un nombre incroyable de modèles et d'effets différents. + C'est un économiseur d'écran à effets de particules particulièrement hypnotisant. Il vous permettra d'obtenir un nombre incroyable de modèles différents. + Este é un protector de pantalla con efectos de partículas moi hipnotizante. Atopará que pode acadar un incrible número de patróns diferentes. + זהו שומר מסך עם אפקט חלקיקים מהפנט ביותר. מספר מפתיע של צורות שונות ומרהיבות יתקבלו. + Ovo je zaista očaravajuči čuvar zaslona. Moguće je ostvariti zapanjujući broj različitih uzoraka. + Ez egy lebilincselő hatású részecske-effektus képernyővédő. Hihetetlen mennyiségű különböző minta képes benne kialakulni. + Ini adalah penyelamat layar dengan efek partikel yang sangat mencuri perhatian. Anda akan lihat bahwa Anda bisa mendapat sejumlah yang mengagumkan dari pola yang berbeda. + Þetta er mjög dáleiðandi skjáhvíla með brellum með ögnum. Þú munt komast að því að þú getur fengið ótrúlegan fjölda af mismunandi mynstri. + Questo è un salvaschermo con effetti particellari è veramente ipnotizzante. E' inoltre possibile ottenere un incredibile numero di differenti schemi. + 非常に幻想的な粒子エフェクトのスクリーンセーバーです。驚くほどの様々なパターンを知ることになるでしょう。 + 매혹적인 파티클 이펙트 화면보호기입니다. 아주 다양한 패턴의 보여줍니다. + Tai labai įtaigaus dalelių poveikio ekrano užsklanda. Atrasite, kad galite sukurti neįtikėtina skaičių skirtingų šablonų. + Šis ir ļoti valdzinošs daļiņu efekta ekrānsaudzētājs. Jūs redzēsit, ka tas spēj izveidot neticamu skaitu dažādu musturu. + Ова е заштита на екран со смирувачки честички. Ќе откриете дека можете да постигнете зачудувачки шеми. + Dit is een erg hypnotiserende screensaver. Je kunt ongelooflijk veel verschillende patronen maken. + Dette er en veldig hypnotiserende skjermsparer med partikkeleffekter. Du vil finne ut av at du kan oppnå en utrolig mengde forskjellige mønstre. + Bardzo hipnotyzujący wygaszacz. Przekonaj się, ile niespotykanch wzorów da się osiągnąć. + Um fantástico protector de ecrã com um impressionante efeito de partículas. Experimente e verá que pode obter um número quase infinito de padrões. + Este é um protetor de tela com efeitos de partícula bem hipnotizante. Você verá que pode alcançar um incrível número de diferentes padrões. + Acesta este un screensaver cu efecte de particule foarte fascinant. O să vedeți că veți putea obține un număr uimitor de modele diferite. + Завораживающая заставка с эффектами частиц. Для этой заставки на выбор доступно огромное количество вариаций эффектов. + Detta är en mycket fascinerande partikeleffektsskärmsläckare. Du kommer att upptäcka att du kan uppnå ett otroligt antal olika mönster. + මෙම මෝහනය කිරීම් තිරමෙහෙයුම් වෙත ප්‍රයෝගිකව මහත් බලපෑම සහිතයි. පුදුම සහගත විවිධ මෝස්‌තර ප්‍රමාණයක් ඔබට ලබා ගැනීමට හැකි බව ඔබ සොයගනිවී + Toto je veľmi fascinujúci šetrič s efektom častíc. Zistíte, že môžete dosiahnuť neskutočné číslo rôznych vzorov. + To je ohranjevalnik zaslona z dih jemajočimi delčki. Odkrili boste, da lahko dosežejo neverjetno število različnih vzorcev. + Detta är en väldigt hypnotiserande partikeleffektskärmsläckare. Du kommer att upptäcka att du kan åstadkomma ett häpnadsväckande antal olika mönster. + Ин пардаи экран бо таъсири зарраҳо аҷоиб мебошад. Барои ин парда шумо бисёр таъсирҳои аҷиби нотакрорро пайдо мекунед. + Son derece büyüleyici bir parçacık efektli ekran koruyucu. Birçok değişik şekle ulaşabildiğinizi farkedeceksiniz. + Це дуже гіпнотизуюча заставка із різноманітних ефектів частинок. Ви побачите надзвичайно велику кількість різноманітних візерунків. + Đây là trình bảo vệ có hiệu ứng thôi miên cục kỳ lợi hại. Bạn sẽ thấy sự sáng tạo từ những kiểu kết hợp có thể là không giới hạn + 这是一个非常迷人的粒子效果屏幕保护程序。你会发现你能看到惊人数量的不同图案。 + 這是一個非常令人著迷的粒子效果螢幕保護程式。您會發現可以達到一個另人驚豔的圖形數。 + all + + diff --git a/addons/screensaver.gles.solarwinds/icon.png b/addons/screensaver.gles.solarwinds/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1f5800360734c51b7d628f644d65625f9c6d39df GIT binary patch literal 14774 zcmd6OQ*fkhv~J9aZB6WnZA@$@9oxyob~5qAwr$(CZQDHk-=8{F=W6eZuCJ@Rs`1sk z)_SzU733rk;BetUKtK?FONuIifPey@f`Y(+0Wb5&0?fb*jjP{`>^RmpClsY?lH%D-#JAsQ~{;Ld6*mVY|GF^oRAeGgaHjSyzk?l^r%VpZgNs&-Q8*59{Z15&ncz84h zQX&>q9qD9VOrmTMCrJYX1Jk9VwKd!t6joFDe-HoQ9$Zm8a{uHg#izE;vb$C5wnP2I zkfYUkE8npF-s;e^^A-tYj%69=+>yO)A^8+>x!j1$$oMgb1iin%U*Bwv!}SZ5jU>2% z82Gakt`Nj@SQ?PMh=}m;>~G}cq*&20{#Z?^#S9x+#ik}6>iZ~M{ZJ(k8yr+sbwTWj z%gZz5{5xIiJc^1pKa(U_DA~SeEkX>Y)BfP(G*8)|0i8f-B6m24#La!eMO|82SXkHw zKXR_yZoAp!+EnY*1~(02gGj_r7lgf5Tu_AlMdX5K$_`OSZcLQWa3xNRx09~?KrgN0 zl^Q`y5wUD%j)fZ?5Xkc}U7AtB*ZPu66dDrJ=d7rEY5L2KlcTnC{?yveE|eXmiUdU@ zl%0w7mlkKH%$xTZ#-%pBU#(Cax~QL>_**N0h22HROGn4q+1bKEQ_qJ`k`gYdy$v_S za((3ooV=}GR_@jbGXkR6`N;{V`(432PJo=ZG4uvlIx$gNT6%g~+OCdd*j6N8m zJsA^-_4Fturs^%;3w3I&BLjr64P;M72<7bYU)KcwvE}+pr`9@)5)}; zAU6?*>ah_GMP+R(27PK_q2-sB3UDz%y>M7XtPcqP=uU5->(vIc;4ko(e+5fROJ#_g za{B)g*y8(^F#KU=c);vCi3*4YY`-OlR;L0EWHVTQyF5v>=;XBdi9-z7!(bbA7$O-c z%rqpb&@p@tQLDOM(FTCPY1`jN;p2>M=G@w6wF}i-Vk6bk0=~aK|NV>CPXmLjs3|Gw z=;$k@RU7~wQnuADK|cv1_n-7OrM~H6)YKRliBt!|eX2$$7`SqR{VLG`L$lr^JH6iT zPp20js4B#ij>E)$8jeR5teJde7Ev{5pKp)jQ(LHLXk=IM>FMo`i!7Wdqfbz)AVJkV z!L(82WdQTC177b#k%$nX@$m4rz0NPklNlT?!z`YJ-$0+YcnS{`U`sTX zDu2n;LzmrZiU9b1$LlgU@k5%udB67 zNlObYBf&bX{jmxcMg?t16?j9D66iT}oXmL5-`L=ND2R^0G4V|C2Zz?{uvb)G6}~$d z{bx3r1`DmNrPb8g{<+cWgs95WC+JBz+3-^zl0FDB-iLZA9@+)BTsLBFZ7D6ONruh{ z^y!*WM*E3#xr}^pO#`o~I{Ee)_?e@w_z(iPDqM9G{%iP$e}6MS4obA$w5 zZ$-RqJ5}kJ;L{x7%CZD$Q3ZA3Q1Wncu;v(HZBrDvz~{8@*>#4|OvWk;l6-A>2n`MG z#r`qJ$lzdn6;%!eXUsg)6l3eikGe@_qd4KW#A1&}T*|>#zmEW-%C;Wv#EQtI@ zZp-8SlKLN|{}5Qd<6&Gr=TE%;j=TpNt5_Tv|I6KfT#FAC&Fe+DUQN(MUQ9baAE7=U zMn%S@y)E405HNIn+D=VF!^7kFC1sA)y3Kk>XUtI6{Aw)uuUG9?5r1R;+PBJOazB1S zd#2Wor+>ZLml|G#2yq<+SV6JDfUB&jtrFnjr6;6>Ap(1C$Hyk5sW|a(VRyg!eBk*W zOQ7E4qK(04CeW&bD=@#kb@&2cKF>g0!r`C@Dt;vS2o0>QtsPBfCZ{C8u)-i2X-_%b z-?g?~s2~)IF{`;i2Zai}?0~VlOGM!wI<~TReBf=iJm4u5p7!zgqmmVS*<8BGURJjg(uNdp44-6$7Z1=NP=VbA-TqpUiD7_v%Bsq-q{BU30QQ z!RbExH*Zl?9Rs1NAMo%9hKHjiuoQgsx=`4!YustbPnWqAG&NxZ{-iU*vI0RW8^>-6 z%^{QVb9f{^wX}fYY@V2QUHvXip_wi(9i5B}C+3@jVO}w`YB_)NR-1k=*aQD*Zc#Gh z?s7?G>2F!t$%zefIy+CtCfm&pcNR~T++`HdfGF@3?VI4^?0?NG0SZM$1x>Eb*y&mm zi^{9|J;*_f-5n1{zFn{s6jZ|WSPWh_y?Pr2rqQ2oZ)vDRSVT9>J4@+x?2iS7RBxt$ zIId;N5X;xz8}I)r@)>Svq@#6oz4<$u)>fvpoX_2H2_#Ecx$tZK*B3DZcVh2R$5&u zEkFw^a`pZBT3%8zc6zVLLqy!W?@xiGw4+Y8_#t$fVjD@Tq_>3cV zX?pW|8J+-*mq)+!th+y8l-l9sXvxN_`^w>R&xtvZ%;SNX8z__%44!hBK^=6qh9-%!U;V2B2h zxIk}`L|BKQ`lFvVSI_>TZRcUq>pfA=%K@;%G})}XoZgwJwoqe;AsWXnhu`1bVbSZD zuUCvHbzxwE+i6Hf7x`~B8XlHa$flE$l6DYQx3{e^xi`-E5Sbjd5n42$FS4WASQKV8R28zDp?fSx05Jiu(3D_E3!F5ge{9cLR2 z??1|=@($vl8q%L|F*^BAn3$SI(ErWZD5m$s z4_X-|TPXko4-puvz?tu~I<87dF;BOtak~|fBeOzYyWiafABx67Fgrgxlgs9!wF~07 zZ+HGPnaTov@-suOx7CW@%?!kOD#tQ5Is01Puab+)Yjybn2~Lra(>!M*zI;0XduPX=LzZREx-;bTDnPo!@yx|4BwdwYA*)q6Z|l>3S)J9yS~XF!PY#iifzoG148 zA(B?;pEk#e4G3RU;L*soE{LVf#mlXEd{bj1m*)(`4hYp!zeFT*^mkq#se7ehf=!%m zIg?5;y{_d!tkVe3$dB1)i#avy(8bYtykOCkO{J8wAr8s9Fc@kx6wl*AC@^9g?l&M0 z{S^=x3CUzmgNU3l76JEzDOTFy6*hZqVo2dAFiN`*c$=EgI@G0r z!4MKcbHPQgasT~}oi{CmE%%k{>rP;2G9%#bwdHoKZ!4khuFg*$prI00kB%y44#=0- zW=WEeBJ!8ubxGJBGnn$?0~ta3hl)b15vi|v+H>R1f|m;*4#dCly4@Sx+XIiddR#UN zI*>I0)h!1y%BbjwGCp^uS~^r(Y{ln)*&i!m)VPGZjwU8Hjv<_pBR?eE-MLmu*_Hgu z)Rg;CV`vQL`MTc^e*Y7N3rFb>MZ#sh>FE^^rd>>-y}P^naDw*#O<)ag5KWxyqpLkD zy=viD&}9yc}U=w{DoInK|3kFJ0^H z^%v?&(XGSn?yf;$p$T1bC8^GCUCP-V(mv~miG-P%uI^@`bTU3^-fGiH`Q1-mz7uRI zJ8~H`nO~ecD;@6lMY8FSogj4RtfFd*9(6h?&R7%6=F!^1RmAEmh^B`uwm z1og-9aL)HmAeReVPNv0-9NxP*;5}3;TU!R}#pC0S7CHIw^guRySlPVw|5VqZvd8SB1G&4+P?Jc z)KYOvFukm#V!$7>oMconPl@XX5yJ)z;$M_8e9_IGJRfbJ_ogu7G$sRKML+cnr4}flwnweiW;_@{BtHi%RL^k) z*>IT+A=W^MKZTX=hhlp>rYS=C4a-Skz_zk|-Ym2~@IP8y zCeN}zKaNS$154L(izBvGRAsgk&YB;;fI~i+Qg9}L@OyO{s79#rll^=-$bx5m>jMu4 z@y{%idZZX&BgUAVJkIjn4c_e!>8)*>HxnJqEtg^Sz-9LapOK0<84&)UrKz`w(Df;JG3;n zZgW13pGW3di~$#C$`Bis3yTSbHTzFI#NjJzYG{C2F1wL}Qc9I~s~=vWqhk zwYm=gLA(+&Jd2_yvy)fOS-*Tb_QR6IFy`40bR-azOhe{WMT$(qOvXo5Wo4zKludh> z&;BsJSgBPm{+h=Ec+D;>{G6lJw(P$dX>!;fDl9Huw}rz8!OL%KR5hMBGrz_r52o+< z?u73?vK~Er$MMD z?^%O|1*V8X$8<2Nhc9S*WR|0(gamXV&XHoae{zz`A0L}DcvPQtkKO-`_bP@Ir2+_7 z))GbN$i&9zFu&BCj*5+5a->GG1MsyVaA?GuM-T}=5No}p3Kj4z;p&5 znd7OiW-%q;m3!cHL%MZx=bl=}&Au z4Hb>RC;8Y!WW+Q57F#_9kIAz|SlG5-3IITMQd31!(j|=IE58__QN^7#JYemOIcDUq zgt)=q5JFVJgruZ!0)`3XWj=Hv2!$?hxN zTQ^kGkDC1az~oLRsy8{OqlMJ(o^H5eSursaTRjFSqc>S@;yBzhDDG*TYSyU zWt>$kG+QNcDXUP^v2RC!B-2`MLI@lh`}J6bdI&l@jKJkLB2kc4*!jlmec#&RLm`LF zMvFt<1;EWs!_o1V`8OoU~vlOnmyHa7>FjvesrzM(2^hde3U z?YRJ!kiF!jh2!i$1QQM}3h-xpwbM@GTGU+qx{?eWHHEd47aH;*y%^cs&1R z#0&88<=56S>krxM&|veKK78IE?Z$atcXF_>{H=s4Nh2rAL&u^wWI{k|#cOzi-5>5( zH8C-XijtM%s|c$l=isQWx^kA0Va2cJRSGXm+9`9`r%SvM-17%P%(`XbVC-&r>FE&y zmtW2ts_{8Dvg+jip$LW+>^$`->}{>YW4sEbl`s_Nq1|5E&_v`n{`Ht?%NO885B-& zM*UT|om-7e+t+_Cu-q%udI3NtZ4n`9NdRocq19Q6bm_QETb-{PTXz>Pfkmx?)AK1( z*)^4WA*TWvtz$LUqlBeam#S21k;X< zuD-^Lvmw0Vuf3iN$NL{S5+fx%67O^k-4kh=AC zi7A5l=p07pA)!P92Kz5!tnK>>vx`N!KKLQ5G9|=f@|p1ln?!63>?cNmS=B84s`f#n znL=|0xLIUJa)iYA{{Y>HVm&+M-R1lKI&GtEC#2cE|Fr&mwN9%poj8c2 zycU4buHX9s#5(^C(1lWE;udx>$)#DOWWujrBp-X|VEnRbz~UwpkkvVrPEjg60E{RK3spb-0BUS2*=w+k>k$U(?IUAxrpNxns6X0uZ= zJ7lUf1SDE(wn{NO$_4HWN8_~{k18qLcIq)|)LJc9+U-BG9sG>=y7A!qiXifbxoLFI zr!p!K{ypLkv?EeAzCeWqg8~Bhgtdf{4HvIj0XiEGfBdDIDtvFnCV2R~-ySApyp4?A z+&D8J=ZXr7nwlGp4A1N8dS2(H$H#uiWBnFb1>wW)2X%tzr7B8i80B24W&x!radwbgr^V4+p#BXb{P_K!ho_%W&V3w#`(EAy=N{y25ls(@*>MOc7_!gMCbpST^1 z(L)eyP%1z+X6}6#3yN+PjCVk_?5^%tO56t}C{z9?9C}I7x{B60#VJx)j!Phol1vZ{ zhJ+(_YAVL}o}?i$$FI_n^X{1f`D|?>&xcvh>r7M}94?cwgrSg-X@PGd6a#~Q!d!mP zE2z7Uqg;ZTqe&()08^fkmHv$H4=>>ko97}9o7H{Y%}vBbgCRpnq(frBu_`2SiU^6Z zYt&0NeXW7D^#z0;cU^8Szkn|XK&Wn*E^H72;QBo98}0Cdnx3A%`}Ns(xMK#?>11te zabPIA-;2h+owp^kYoq8{!27M?;c%R}1Z^|Nt8&c({%97=4k>;)}E4q`GzF1$D|W zE<#yq=}{Qe0c2YlcY$<49y!HS?V)^hc(h)dad>4*L4j!P^q)V)hth5cpv<|>+KvZf zV&^}g<0eJQpe@hr=uV<->V7!fAtaG_;Q5|%un-!E2FuF_3loDq_^`uh9J5k$tpegB zJFH~jkUn3hDdjSd-=?E8+nLCaMhx6ER&-rAaWFBLHW$ey5MXg(9Fj8&A}$0vwU}ZG z`DI;QvAg%_Nk}$PPfuc`^>VhDh=Djpn}~A>As@BL?t62GL&NG8OH#eHEO}k^;jcr$*P&h(bz6PC)A5upaERe*_OpUN zY;m1EdVC_)^96-e&?u>rN>`XmjsWM$RMuy?Ee(}rHotf911;SEmF>+=uct zS##_PiE=wp$Y(_cZ^|z(`ddOI>~e`j(Pa(!+5EIwj%0P*Y~J!XPnk7(+gfTaD=TY# z%{a(VO|O9b;Ku24ep3f2?q+Wl`kVxmPEms|DY>?nYiny48V5#5s#;-U-mv@*_H>>b z2(LFi^_-)np>@4n3!dYB%bF$4!BtREao*_>QoZ|(!Qu1R$?^a5=a1P`21=s#>(qqy zToMDyAe-R0fXhb;%!VHi1tnz^i_(wV`r*tJs!gGJ{z(w^3=mcogs6)jdB$ZO6p0BX z%lu&F#AfF_jcjag;r(`(uspB#y8_FZRp;x)NRb1wld{4}Vz_hzHM{-ZgV1gfE-uN1 z(n&Cn;m2d2Gmp-4wj9hH>~>X8b32-qmOb{sMNS4YD{xFbfOzu`y ztpY{+(l%~4X4%gZMb&BL!T<}}?LJAb^7+$~*?e*+cfmJ-mG))2b((+b3E{<@FiQSi zC_#@kPQg5XS=R{-Rn#XG6jp^nw39R&rT)m$&j>bSiUzBNE_qeqP=OY)oZJ$Bu5WEJ z9FZn&_O)L33tVhI=jK5pYN|z>pw4GU!rUOpK;}IuYHFtXdb`Jjnza4-g;dH%pKJLd z!N%p#U|?C_Fjsa2Fz}Nnh=>E8Wz-X4TbPbR@m|gCV3-@%A@ z#YltU1>?*=jup-vT+Iax6gYzkB;4)19LTXk2F_B=f7P)M{}66CiUqYjwJj~nR(z(; z&giwDrkY$+0NIp`r>@%F0RG1VBL0o%WO)Ji_sZs>XaX|BUx|XNV`4Aq;&qr1)i zD+0AhQJ>3S9EHI(TOwOjWMZJH)PEfOU5=+Rn_fxiZC3pQp+D<=)5NYl2)pS=QDIrZ zKdR-y`f_pldf~*<;w#B1DBg}KW#j=20e2>t;n*!%hKax5!aA8 zDk>@~38J~(YSL;m=qOo+VN??7bV++2CBez0;XEOo;{$Rx6t;W%C0ALIakv~O&)Arm z+lmfu-ISF6qZbbUs;?vyopz*XEecTLP`onNhK1`_Tlb%5eZ=i={SAM7Km2)5NyIm@ z=oz1{kMER&UMeyha_;s4CS6d6hHL=Z+81!wZ_Mbv?Wf2e2+9V6gI)XKb+ow%Pp#^tN%4Oi}k5c2MS?fDJdy0FE233 zOW9iWWREWI)!l@_jd+-ItfUwZr@$O1aA5fKqT z;Ni`73l9$svvxEaQsB+c7A#Wn0Kw%&vSz`jNa$GZyj!jJM{FD%`%8L-uI>Vd#i#@P zE(tbw9cB;MizBcb=>THju_@eujvzwLWlPhMtO_+vD?r6I(-?x5?TqNkJ-&fW$dtO; ze(Uk-&KnAOU0eGXab)!FIysSRYHsG>;Gnfu_waCNco7PWui-J*2d2jLUDG~4jH9S5 zPb_HJyN1duE@b)oi~5~wycK?`E9J2+t}q&o6_V%6rT-j78INd? z7er+{MbzqvORRS3MepI~#wgv29OaZf7F2XlG&k3iW->Tlkr!Y0|ZNYYC^1o6Gc|3dg>6(<(HA`-G!i^`d728zw& z2hEiP)Q*Ve!k#UUz+{tkoR@oZ>p%*zUBK0G9C=Tc?W9<-`e7e}O= zW9`1Uh8o|=5V`+ddVp+ z9;urn$+W$#jmY~U4oQGD{nKaoI#&~`;rwdJi$9$@42n4;2x|N5sTuGZ^UcKY@qk2h zrCp=%qprSOoQ?ktp*I{O^n4S5WPdO(FMz{!w{B0y8yub^@O3TV{|B_0Wsl$6?Qf~_ z_vuNTl$&h&o4ljjNkge}jEY)9aw2IZ|JU_*2%&-1Oa7_{vm` zbp7cDs(+AK%7|lr(rU&9$H#|hF~|3~q9CJlfmkCaV5BVOC+%D>>{FnLNwFAfrC9 z79qxCQ=`56`$L0u)X+Hdm(pP|5{r=hCt~0)r9lub9VI0&jl3Iw`~umkDCwl70~uSq zUhjhOf#!Ya7clo{nCshVr>2bI4sVvsAgkSCj?!Tytr!gJ8+z+7?=OtUVM;+k!5}X$ zFDHjdsBs6Td#!>@B%i^_44nDC9rsfRjGZcg?Ha>DxQ8Y>tri6cbbNjScJ} z>xG4ca5PFsi!eDUnThdfW!Cg|acOC7nus~?hgk_=c;a=)g`SPv1n3T8CWj|_o}S_W zv!yNgP?wumXK!yF#DZ&c?AcqSl3tRC!-EU- z(__+0IjFZgouCEbD4cQB{?alG16m&E%TL zd89l)7w9*-X>dB;ypH{-V+GggzQLvy%@>dII4w-x>HmO)*EeU?!P9bdjF0^ahR4Fd zz)Dn4=;!eYA#?v zMWg7c=#x0HrE`78f%XEq9lRCbk0z)tE3-5&N&b{|tV?9GT2fP2ugAsVodL6r>wgdB zcTgDC=fS=fdOOTxxnX8xBsvCdINpUSoLEu#_3IY}E*p(lBc52@9dH)IPjrWtRq3{? z;dg(3y?;Lp3v{*k@I~g3W(ZOJWO}-niqOy=gv~aXTgD(!fMpdx)1DoG=`{ekXg=PRKiUvZEWgfcr?Ck+#&|0u(u&t$rmef zE5i^w31dDygP?V49ZfvMp>*J#ROIBI?uxUQ==Gyu>@!(}6s3`pr?U8t6V>%@v3=EJ zNm6EHIk<*{!qEx>x__91zx+)W=<5@b&ATQoL1YClsoRL)7~cYsQ8f4b(W;qF}hZEu7oxbJKFazj+zaToY~@9T20;y;|qJ+5Bx5;g*oR6gXr^%5`*3^%z& z6z-^eh830^HI|k(St&F~A<~S|O~K|g>xTj}iC-jG51;P>eYbf0Juw2TF#0lT z(LH<9E{H!=O^(Wx>gd0Srr0-{P^K1b73D_jjFj1kaK8K*(6NZ1@n`m{8mlo}Wg%YD z-+Wi#hfHU*;o;yYWYZv6-m}Rop-c>x8N4?jSAoKGWK`7U)fpi$-A+quHS}Y1Xp zcD(RRBBU0^337uRi0oDzW`yV-$UOZEn3rpaO`HZL9UvJK#_bVb6tuKLAgB%zi5xm= zY9yz>si#4dx`6?iK6Z>p^8;8a9!fl$tAc@_+Mk651p}>4{|X-w#bl6QtR8h9V2+@{ zZAZ)%oFn=H56{<~SOg=(NWOhRK{&+BIpashX7JO^0%c_zqfW=%ZrH+$;oaD#%;nAm zxR_ckzTHg0p2E(~KQ=~ej2*wOp1T-P^-INrLA!n~vjH_*;Xsv~8rc+16pq&Z)w%xA zTXB1@y@JsdaI?1SfBVC&>E}Ef>*HBBp4;6L8Y_m3ca+01y`|S)$L$(J`ao0u#GHnn zesXH+){Sr1V3&zfhDnESg_6nU5xzV>KR>Cc(EDk5I;Z)dbrd*p?masH6>re`qNIUV zG16k2`OGAOX93z>2qGl4t+ch)erabpD8Fr9B`ly9XOC-ZB;`=R&I=C#3wy$BR@(KI ztF(dw)OlrP_pSQGhm|N zTlqR_vzC0EyfI4E4%AxCt&pN>Z6B}*jv#Pz6QV~CL)>cmn6&2aY4P`4Ik|b8&d?Kq}jVfB@ zh_bJ3O ztmBrczPTy86i+h=TurQ3MFXuOLp(usTIB2XvFYjqaLhCUDxtrjuV(AIhqO!7PwF`U z8*7nI5Zfs-FKaemn9Ezp-T35T|Du$%(1jHOfg48uU%N)T*8w#(HD=kLs$%Xq9eP_e zplBy>qT=Fxz2Jjl_DwnZ&kYvJyE|y|ABImC?>msgMD8yJvu;3xZGC$air!|}a~|Y9 z=&KfV1K#IiQbai09zwpi@utVk>kAyIpvZw*Nc6L)w)S=v@QphqF4}^Ni@WQlV*C?k2?!nGpDw7YOJWDlqd2~t z`p3KdljJ}4u0rChr(;5tE_7GQ)d+Nw~Mi64r2_(-QnbnHR*%kBCgCidLY2w{xdvGHV0FANm>n z!u@48yHBVELIad&%iGoSn&{|UQUGNqq!&$||M4y)S#bE~tMC2J&WCJB8VieT!Tkd$ z`7U$_tr4pESh6sAtnRE4Dm5$VZOxoL22{nkiW@|zYgrDK&dsS5#i%z}L>^yK+E`SCpVzPevj0GdCu?0>R zhKUjzwCET48J;`#9oS|Nh^CN@*;|7}o$#;suGP+ke1*xDBdF!4*f^a_6tsYEFR%#y z22kw)w)OgBJTGk09$7GSL{`?_&bA?$h&J!{>zy4kB!Pu(;jK36az#;T`F^KiiEPv%j5}}!y1b+YtP$J=_Ik6Dx_!`2?HOQ4w zXMcdh_QS({g1CUg69DBNL+eKF?EJX1^Vr_OB}6@fP_W*)HQgTO^plb+DQNPa2@HTR z%LWD`60@Gp_d_NSa5DtW!Y+bd%Mh%ua%fq*ECa3FB=uoZE&z@F)%Q%Izy&{R;N$ + + + + + + + Seker die tweede mees psigedeliese sluimerskerm ooit + ربما شاشة التوقف الثانية الأكثر هدوء على الإطلاق + Напэўна, другі найбольш псіхадэлічны ахоўнік экрану + Вероятно вторият най-халюциногенен скрийнсейвър + Probablement el segon estalvi de pantalla més psicodèlic mai creat + Pravděpodobně druhý nejdivočejší šetřič obrazovky všech dob + Mwy na thebyg yr ail arbedwr sgrin mwyaf seicadelig + Formodentlig den anden mest psykedeliske pauseskærm nogensinde + Wahrscheinlich der zweit-psychodelischste Bildschirmschoner überhaupt + Πιθανότατα η δεύτερη πιο ψυχεδελική προφύλαξη οθόνης που έγινε ποτέ + Spiralling screensaver + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probablemente el segundo salvapantallas más psicodélico jamás creado + Probablemente el segundo protector de pantalla más psicodélico jamás creado + Probablemente el segundo protector de pantalla más psicodélico + Arvatavasti teine kõige psühhedeelsem ekraanisäästja, mis iial tehtud + Ziurrenik inoizko bigarren pantaila-babesle psikodelikoena + Todennäköisesti toiseksi psykedeelisin näytönsäästäjä koskaan + Probablement le deuxième économiseur d'écran le plus psychédélique jamais créé + Probablement le deuxième économiseur d'écran le plus psychédélique + Probabelmente o segundo protector de pantalla máis psicodélico. + כנראה שומר המסך השני בדירוג הפסיכדליות + Vjerojatno drugi najveći psihodelični čuvar zaslona ikad + A második legpszihedelikusabb képernyővédő + Mungkin screensaver paling psikedelik nomor dua yang pernah ada + Líklega í öðru sæti yfir klikkuðustu skjáhvíluna + Probabilmente il secondo salvaschermo più psichedelico di sempre + 世界で2番目にサイケなスクリーンセーバー + 아마도 지금까지 두번째로 가장 환상적인 화면보호기 + Tikriausiai antra labiausiai psichodelinė ekrano užsklanda pasaulyje. + Iespējams viens no vispsihodēliskākajiem ekrānsaudzētājiem pasaulē + Можеби втора нај психоделична заштита на екран + Waarschijnlijk de op één na meest psychedelische schermbeveiliging ooit + Helt sikkert den nest mest psykedeliske skjermspareren som finnes + Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie + Este é provavelmente o segundo melhor protector de ecrã psicadélico de sempre + Provavelmente a segunda mais psicodélica proteção de tela já vista + Probabil al doilea cel mai năucitor screensaver care a existat vreodată + Наверное, вторая из самых психоделических заставок в мире + Förmodligen den näst psykedeliska skärmsläckaren + පෙනෙන විදියට සදා දෙවන මහත් අධිචිත්ත වේගී තිරමෙහෙකරු + Pravdepodobne druhý najviac hypnotizujúci šetrič obrazovky vôbec + Gotovo drugi najbolj psihadelični ohranjevalnik zaslona na svetu + Troligen den näst mest psykedeliska skärmsläckaren någonsin. + Эҳтимол аст, ки имрӯз дар тамоми ҷаҳон ин пардаи экран ҷои дуюмро мегирад + Muhtemelen insanı hayallere sürükleyen en iyi ikinci ekran koruyucu + Напевно, друга серед найбільш психоделічних заставок + Xứng đáng làm trình bảo vệ màn hình gây ảo giác mạnh thứ hai + 或许是排名第二的迷幻效果屏幕保护程序 + 可能是有史以來第二最夢幻的螢幕保護程式保護程式 + Seker die tweede mees psigedeliese sluimerskerm wat bestaan. Verbeel jou net al daai kleure wat rond beweeg. + ربما شاشة التوقف الثانية الأكثر هدوء في الوجود. فقط حاول تصوير هذه الألوان المتحركة . + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + Вероятно вторият по сила халюциногенен скрийнсейвър създаван някога. Просто се опитайте да съзрете всички тези цветове. + Probablement el segon estalvi de pantalla més psicodèlic que existeix. Intenta imaginar tots aquests colors movent-se. + Pravděpodobně druhý nejdivočejší šetřič obrazovky všech dob. Zkuste si představit všechny ty poletující barvy. + Mwy na thebyg yr ail arbedwr sgrin mwyaf seicadelig sy'n bod. Ceisiwch ddychmygu'r holl liwiau na'n symud o gwmpas. + Formodentlig den anden mest psykedeliske pauseskærm, der eksisterer. Forestil dig alle de farver, der bevæger sig omkring. + Wahrscheinlich der zweit-psychodelischste Bildschirmschoner, den es gibt. Versuche doch alle diese Farben, die sich umher bewegen, festzuhalten. + Πιθανότατα η δεύτερη πιο ψυχεδελική προφύλαξη οθόνης που υπάρχει. Απλά προσπαθήστε να φανταστείτε όλα αυτά τα χρώματα σε κίνηση. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + Probablemente el segundo salvapantallas más psicodélico que existe. Intente imaginarse todos esos colores moviéndose. + Probablemente el segundo protector de pantalla más psicodélico que existe. Solo intente imaginarse todos esos colores moviéndose. + Probablemente el segundo protector de pantallas más psicodélico. Solo trate de captar todos los colores moviéndose alrededor. + Arvatavasti ajaloo teine kõige psühhedeelsem ekraanisäästja. Püüa lihtsalt kujutleda kõiki neid värve, mis ringi liiguvad. + Ziurrenik existitzen den bigarren pantaila-babesle psikodelikoena. Saiatu kolore guzti horiek mugitzen irudikatzen. + Todennäköisesti toiseksi psykedeelisin olemassa oleva näytönsäästäjä. Kuvittelepa vain kaikki nuo värit lentelemässä ympäriinsä. + Probablement le deuxième économiseur d'écran le plus psychédélique de l'histoire. Essayez seulement d'imaginer toutes ces couleurs en mouvement. + Probablement le deuxième économiseur d'écran le plus psychédélique de l'histoire. Essayez seulement d'imaginer toutes ces couleurs en mouvement. + Probabelmente o segundo protector de pantalla máis psicodélico do mundo. Tan só probe a imaxinarse todas esas cores movéndose ó redor. + כנראה שומר המסך השני בדירוג הפסיכדליות שקיים כיום. פשוט נסו לדמיין את כל הצבעים האלו נעים ממקום למקום. + Vjerojatno drugi najveći psihodelični čuvar zaslona koji postoji. Samo pokušajte zamisliti sve te boje koje se gibaju okolo. + Valószínüleg a második legpszihedelikusabb képernyővédő ami létezik. Csak képzeld el mindezt a színkavalkádot mozogni. + Mungkin screensaver paling psikedelik nomor dua yang pernah ada. Coba bayangkan warna-warni itu bergerak ke sana kemari. + Líklega í öðru sæti yfir klikkuðustu skjáhvíluna sem til er. Reyndi bara að ímynda þér alla þessa liti á hreyfingu. + Probabilmente il secondo salvaschermo più psichedelico di sempre. Prova semplicemente a guardare tutti quei colori che si muovono. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + 아마도 존재하는 두번째로 가장 환상적인 화면보호기. 모든 색깔들이 움직이는 것을 상상해보세요. + Turbūt antra labiausiai psichodelinė ekrano užsklanda pasaulyje. Išbandykite ją ir pamatysite judančių spalvų šventę. + Iespējams viens no vispsihodēliskākajiem ekrānsaudzētājiem pasaulē. Pamēģiniet, lai gūtu priekšstatu par krāsu kustību un plūsmu visapkārt. + Можеби втора нај психоделична заштита на екран. Само обидете се да ги согледате сите тие бои кои се движат. + Waarschlijnlijk de op één na meest psychedelische schermbeveliging ooit. Probeer u het voor te stellen: al die kleuren die door elkaar lopen. + Helt sikkert den nest mest psykadeliske skjermsparern i verden. Bare prøv å se for deg alle de fargene som beveger seg rundt. + Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie. Spróbuj i zobacz ferie poruszających się barw. + Provavelmente, o segundo melhor protector de ecrã psicadélico de sempre. Experimente visualizar todas as cores a moverem-se. + Provavelmente a segundo mais psicodélica proteção de tela existente. Experimente ver todas essas cores se movimentando ao redor da tela. + Probabil al doilea cel mai năucitor screensaver care a existat vreodată. Doar încercați să vă imaginați toate acele culori mișcându-se. + Просто попробуйте представить себе все цвета в движении. + Förmodligen den näst psykedeliska skärmsläckaren som finns. Försök bara att uppfatta alla färger som rör sig runt och runt. + පෙනෙන විදියට සදා පවතින දෙවන මහත් අධිචිත්ත වේගී තිරමෙහෙකරු.වටේ තිබෙන එම සියළු වර්ණ ඡායාරූප කිරීමට උත්සාහ කිරීම පමණයි. + Pravdepodobne druhý najviac hypnotizujúci šetrič obrazovky aký vôbec existuje. Iba si skúste predstaviť všetky tie farby pohybujúc sa okolo. + Gotovo drugi najbolj psihadelični ohranjevalnik zaslona na svetu. Samo predstavljajte si vse te barve, ki letijo naokrog. + Troligen den näst mest psykedeliska skärmsläckaren som existerar. Bara tänk dig alla färgerna som rör på sig. + Эҳтимол аст, ки имрӯз дар тамоми ҷаҳон ин пардаи экран ҷои дуюмро мегирад. Танҳо тасаввур кунед, ки чӣ қадар зебо ҳамаи рангҳояш бозӣ мекунанд. + Muhtemelen insanı hayallere sürükleyen en iyi ikinci ekran koruyucu. Ekranda dolaşan tüm renkleri seyretmeye çalışın. + Напевно, друга серед найбільш психоделічних заставок. Лише уявіть усі ці переливи кольорів. + Đây có thể là trình bảo vệ màn hình gây ảo giác mạnh thứ hai tại thời điểm này. Hãy thử xem các hình ảnh tạo nên từ các màu sắc di chuyển khắp nơi + 或许是排名第二的迷幻效果屏幕保护程序。你将看到所有颜色满处乱飞。 + 可能是現存第二最夢幻的螢幕保護程式。快來嘗試想像一下所有移動中的色彩變化。 + all + + diff --git a/addons/screensaver.gles.spiral/icon.png b/addons/screensaver.gles.spiral/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a6784afc53d95a655742f9b7db247471fc52a105 GIT binary patch literal 5657 zcmd5=%_yf)hI}rNdW+$&`^i!0RZ0Z5f2~+-G*^$ zdC}XzSS?I;T#Z?V*$oLUxq6 zE9lIcr+wgK*+sd{`L^(P-8a3lYQ&E}UA|67z<}ug9WVyQrWc4}FGAmYqBl>1bONzv zC+?Ez!vf2~`U3PpH94L~S5!~e3>{ftnwqYDHkO#%!3Eds-f-vU<#x3ok^P!#c&&Mj zzqU{)hEWAAwchi(#n$&f83OU#4u794xU3pF;=hiq3z=Iyzy>gw6Z9jc|#L>RDEfDP^{ zw1VZPJzaiK3d}>fS&jI4kUS-TdMLJX#O%vmQUu7;ka*&oPz;Dus2GWytedNb0VVFo z=kC>iea=I}ER0DJ)^vpcb6$-b?rJ8LX9^5>nJ}Xg6!55(@FZlJA9&Z2c z!+;}TZ4V{di+qq?Xf=8;-O}LTGYj|nvT$g|IzXn0C-KCg_?NN3#>vI=#XWhw?Wi^+ z^5c(n?^!b~o5{zi??H}^N`*^@ANh^k1$*V8eb%ysgxv^$Gs<9_i2oVtX{VnGo`hq+ zylhDS*9eiVK!Mjpe5VF{IPTn9Mgq4AI)Ep>o|344+WxA@`KN8z(B22(wE%zr&1Wb(!JYd`bl)I`2oCbOeV)*7eJt@Rok8|jq%ZHWu5Ak2x( z`UFt5tE>DaycfyOpHB3v>FWnYB4&^~-QE=wrbh62 zn@A$`0LoZf#ctGs9~hCsirP#OM22xhr~DjQh$2s$IAh95$xVO& zcI->QTatShXtbcLfgS3SfEPF^93rtz6YI-*0?-UuSjH{Z8 z>at!RLM1%!4T?6mr+tW3;$0ZF^9h1MSU+qSkfN+qVan0pj3C9$(Z zjg$p*`xnG=-UpXTg`QTr$bZ+KkmkjM7f<<(oJvf&LnN6o5O;~iCm}~b@LEPWSb~QN zJvrf{&fR@?rCsTVW+tuPtR{j_|4_OdieB5wpOErln*d&^`xYqJB}54VP*d3 z&)HR_0%}>q-`}5IKKOF?%tuz&P=uHyk2`%>v1o6vPOEdVi%Kw@Nh zsjWuVK={$ASC{xw0)zYuzvdKk^U%<6W5MG3WD#Ejd`MLp9;CT{9CUmC2jO!ymsF@> zEJt^3H~ZaVHI7i*i^D?A^p=+9^>{;x7xfK)b&!IRtzcI_RMEO>f}0;4fI<;(ly1&N$3` z-lic`n(t!wdUcV5JB2Ggdf&nj!kCklV<1M7J})(5`kK99*4W%!E?~c>2~v?P3~@C^ zlX#f*?4#Xl7f;*0*W9*Ap;Hk+8EhNdv&>DKEVtG>FH{2TPBet|=osjln*M%-LGu2z zL6!@uFSC7y!qJ0oM~konMa2pq-U#1Mp!gd_SWhtcc~8c~oTsDdcMQ?2n~~swL^X!1 zU11*XYJom55TMsw%_BXl>M{}2WD-1$=>I;lpg%S*dMmaX&mWYf)OX8wAK-SRl0BBP zzA@l068Eb=Je9%tc+6~qLwaHz#^ta7gMzMGf#fH4fLLsE5pRxwC2(Mzkx5C zw7vTiDbg1x93}BMYY{lp9EWlJymk`-D?Ba)BQ@35Zb40#md}y7xw&?h46NCd_GU-K zGI~0z+h?G82a$RIW$drvbmGF!xHz=yk>lgp$C4bf5naT>bUzfw1ow%)-r>PKoE9&}$SiH|ip)kt z;9-&()<{0ja4c^nGqS!$e$9FYSWnjAN}suVph5bo_MONsLq)<;i7%VV7Q}SCuAH%d zLMNI{m@*=+WwbE;v7kzShVaF25xR7xjPwUtI0G~gn z)vub}A?$;;u$@>@qWUID4EfMbSJ~S<9##^~>E0UgzwDtmQB>KgKoZAQcw_K(e7vcq zAA7nD>s5sh!>rjK9pa~8^1;Z=yzbSpAbkkHfEcxOJG3z+EaTK?Zugxnoo=pt88IRB zXqvOYzUEJJ`affS{VZyCta=bM;-fvk!OecIa2$I<`9PXsUL-1va znVb_V!RY8z_|?}$RmTLdcr4+t_)jMmam~}=)=*0G5i;mb3z(sIDqT#g^%Ni&E%1^D zxmd*BDX1hwOAMqQ53VV{l$S%))EB}$4@SA~I-!oT#l{MVq=`x0^J*IAm&Bj#lmoks zsV3eYGvXiAJ>LhsR?z0xok{K}D)7F!cKRJEn;w2ma^s(W&8C&fUJ#wIu}K~9{;iJ` zH7V+;&Y07SBe>e*SRwOfDaLdW{3^W~N-9ey+i^AYPtSZ%MR5$%^s!g*9}f92+4qdU zez3N;p8D=)dq_%2<#NPf2#I<+J+C|eXf$>91vam*um4Wbhle2)I7PA;|LpHiEyS2+ z=j4oqCV!Td)_@;X4_U4Oj#b?X%r!MNt5P24S5Hr-&PB2^I~EDQrzJ+LQ&5`Il-XqA zuPV&m*P{AVpREo2^EpZEM`;L!95dy8$Mhr>ZR`JAw+l%=9y=oc`d5Sq#zg$6@4gW{ z2J=(+Iw<&DyGE3XZv*u-;i2_K*ra6KfXziFGQ=tdW*-Hc?S!T z(NpC~VI@4sDC&1sExFsz464|E@h0e$ua0-Dt!X(IIl9ep#S#4 ziX_7C_Rwm6c+sOxLET(7w&Mi~12b1084)Wtt!@OS^rGpGU|KAwfC_4UJLiEX- zP`(_BpzXDZiIo+7*@&FrpGQMaqM;1=LM!ADmdGOXw>T%bmFXZD(eQ@JJ|fnb5VLu5 zb`{27Qz|WDnf1K0Rd@c|MnmaMfcVQ*h%NeMy||&xOt^)Gq&t%=ToEASU8UE@Lw({m z4XkPQtA}WH?{uD zu}%YCK0+eEf^RhsA38sOxh^Q36O9&O_Cq5^pCX91hLi|sfAi6d|0(@-?p7Gol(9%!s zvY~TS4YaVaeOvM}tuHPtaoMo1d>ro9JuIGDBm`C*K@G{@^;9WeMbmm--&IwXc%;Q$ zCfQs-`80gFaeusrHtBSLqpqfoERlkOa_VBcQcsNF&|l$_YZ`k9)Q7EWFEuUO?>RO8 zZc#P#_4PHvz~AcWb!587$e10A4Am*-kP}$Z20e7PzEV4`&8RkGm)84!64;uwgc!_h$W6()k z+XeP?;6rc!)b!Lki}m?P#=3eRH;9~%wr0n7NdmW7>EG|!)PRA-6JV?TPd&Z!P+q~_nc0`O(Gln;7?+~vWa z9EAJ&$1D-bYbAvTRQDr-{^X$gl!lh&9{p#HlQ&zi> z%d#}SnT(Bm+UwCf5|9O2kMo-~vY0D>&1azzOQK4JoWg7bqhL_-6O>^_qJ-&7T_GMj z&{d}|SV4R#g$6OCj9Guk9IafN*Omq1tb70J6fDI@qR+Q5DJ(XTrAhV<9 zS$!p$kqdI#O=pMB`T#}l9RoIvVqD6&1d2=@kM+LQ715}8Bn(JQkX0{`V9(zx1fvQ; zLG|V1HwOHSWI;D)2(NeGt2)&jro$XR0{L1zP= z(Vzk#3)E)mYu99*qIUeQ{2mxFoJ<6K!`!b51|E~bO{oc%jQ*Z=cD0+mi(C`MMT0y& zDC-@3JN>5bmJk&HW~BF-+Jur!@-Eek-Yssfek=jz-{kztOH>tKV9wm-0h^W%l+UX#F1wq)~lB}t= z?q*_bk5um3PfOJ!l*tAZcCqlvt&{XP5Vt*Dr5W_LD%_^7-s zYA0b$eB?hfI~#Po8zht-#UVXAX*l`+i-JObQMW$o3SDZ)@RXJgyF8tlnI4wEi5^(n`yI&J!$OQ-?PPl&1onO?v7%w5DiNX?gHkZcFcyYdis#Jjc`uhBPF|)X_QRaG8pMk^SK6`ZccI4)=xw!1i zgz-@$tZ{jd87k=-{S*C-SaKmZ^VjTRn9Nd6`EXgh;Hf}{FzM?g zQ=$AGrF&jWLqkLJmzUVp0jp1^ai;^}eU!p4jI0J`f~*5HOc;F&IvYRsG4^m0jOL)A zRzwL2I@pk)gCw~u#t2+~&tc|m;!H{Xgt0<{7d8$V3HA3}_jk8s!>{#C0KRMe=h{zV#)M?A0%Nm zm&YzUE+WEh_9|U*&NO~Ke{@A2%}T>8i@f`pnt(gyG%PBKrhY_T+BHC6WcqEx{7A;z z!JzAw{%qkFuVfj$UR0DNoQpDo@6guWeIeL7$5@_ViJ7L@QfuK_9?h7|m7Sum|1xw| zSCZ@QKgM4sg>jwMZc%F86Au{a1L|LVn>HC*+q0CCx?6qOepVeaq2!F04`EgE@DOH= ztoPuL5&g(SFdDs-{<=h^^5jAm+JafPKiMVei8_xQmkNmgH48Lsw>#-wc@0Jer zmJP=mO)18Ia~P(_NLrvl{q-J=*5!rwdg<}h<>eh$R%X@^HdC(F{oR=Z*%>B3L3VE= z*f^ymXhlBDyly0ag~=I<7}SRt|^E{(nylbLBVkn|D0 zj%fwa9nNK)bt=O*@!_fHIRECsLEasi83=a>2*d&wwy@At#D6?cQct0p1dtrO6D)D& ztMQTMk9MI>yywmJyhdg#D~fN|%#VmACR!=EVLDieC+0uZ5(H5CpM>|;SqpFnC>g0) V_ay9mdAsWcG*q;qwMtfz{|8C@VfFw3 literal 0 HcmV?d00001 diff --git a/addons/screensaver.gles.stellar/addon.xml b/addons/screensaver.gles.stellar/addon.xml new file mode 100644 index 0000000..c345d87 --- /dev/null +++ b/addons/screensaver.gles.stellar/addon.xml @@ -0,0 +1,121 @@ + + + + + + + + Seker die tweede mees psigedeliese sluimerskerm ooit + ربما شاشة التوقف الثانية الأكثر هدوء على الإطلاق + Напэўна, другі найбольш псіхадэлічны ахоўнік экрану + Вероятно вторият най-халюциногенен скрийнсейвър + Probablement el segon estalvi de pantalla més psicodèlic mai creat + Pravděpodobně druhý nejdivočejší šetřič obrazovky všech dob + Mwy na thebyg yr ail arbedwr sgrin mwyaf seicadelig + Formodentlig den anden mest psykedeliske pauseskærm nogensinde + Wahrscheinlich der zweit-psychodelischste Bildschirmschoner überhaupt + Πιθανότατα η δεύτερη πιο ψυχεδελική προφύλαξη οθόνης που έγινε ποτέ + An interstellar journey + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probably the second most psychedelic screensaver ever + Probablemente el segundo salvapantallas más psicodélico jamás creado + Probablemente el segundo protector de pantalla más psicodélico jamás creado + Probablemente el segundo protector de pantalla más psicodélico + Arvatavasti teine kõige psühhedeelsem ekraanisäästja, mis iial tehtud + Ziurrenik inoizko bigarren pantaila-babesle psikodelikoena + Todennäköisesti toiseksi psykedeelisin näytönsäästäjä koskaan + Probablement le deuxième économiseur d'écran le plus psychédélique jamais créé + Probablement le deuxième économiseur d'écran le plus psychédélique + Probabelmente o segundo protector de pantalla máis psicodélico. + כנראה שומר המסך השני בדירוג הפסיכדליות + Vjerojatno drugi najveći psihodelični čuvar zaslona ikad + A második legpszihedelikusabb képernyővédő + Mungkin screensaver paling psikedelik nomor dua yang pernah ada + Líklega í öðru sæti yfir klikkuðustu skjáhvíluna + Probabilmente il secondo salvaschermo più psichedelico di sempre + 世界で2番目にサイケなスクリーンセーバー + 아마도 지금까지 두번째로 가장 환상적인 화면보호기 + Tikriausiai antra labiausiai psichodelinė ekrano užsklanda pasaulyje. + Iespējams viens no vispsihodēliskākajiem ekrānsaudzētājiem pasaulē + Можеби втора нај психоделична заштита на екран + Waarschijnlijk de op één na meest psychedelische schermbeveiliging ooit + Helt sikkert den nest mest psykedeliske skjermspareren som finnes + Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie + Este é provavelmente o segundo melhor protector de ecrã psicadélico de sempre + Provavelmente a segunda mais psicodélica proteção de tela já vista + Probabil al doilea cel mai năucitor screensaver care a existat vreodată + Наверное, вторая из самых психоделических заставок в мире + Förmodligen den näst psykedeliska skärmsläckaren + පෙනෙන විදියට සදා දෙවන මහත් අධිචිත්ත වේගී තිරමෙහෙකරු + Pravdepodobne druhý najviac hypnotizujúci šetrič obrazovky vôbec + Gotovo drugi najbolj psihadelični ohranjevalnik zaslona na svetu + Troligen den näst mest psykedeliska skärmsläckaren någonsin. + Эҳтимол аст, ки имрӯз дар тамоми ҷаҳон ин пардаи экран ҷои дуюмро мегирад + Muhtemelen insanı hayallere sürükleyen en iyi ikinci ekran koruyucu + Напевно, друга серед найбільш психоделічних заставок + Xứng đáng làm trình bảo vệ màn hình gây ảo giác mạnh thứ hai + 或许是排名第二的迷幻效果屏幕保护程序 + 可能是有史以來第二最夢幻的螢幕保護程式保護程式 + Seker die tweede mees psigedeliese sluimerskerm wat bestaan. Verbeel jou net al daai kleure wat rond beweeg. + ربما شاشة التوقف الثانية الأكثر هدوء في الوجود. فقط حاول تصوير هذه الألوان المتحركة . + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + Вероятно вторият по сила халюциногенен скрийнсейвър създаван някога. Просто се опитайте да съзрете всички тези цветове. + Probablement el segon estalvi de pantalla més psicodèlic que existeix. Intenta imaginar tots aquests colors movent-se. + Pravděpodobně druhý nejdivočejší šetřič obrazovky všech dob. Zkuste si představit všechny ty poletující barvy. + Mwy na thebyg yr ail arbedwr sgrin mwyaf seicadelig sy'n bod. Ceisiwch ddychmygu'r holl liwiau na'n symud o gwmpas. + Formodentlig den anden mest psykedeliske pauseskærm, der eksisterer. Forestil dig alle de farver, der bevæger sig omkring. + Wahrscheinlich der zweit-psychodelischste Bildschirmschoner, den es gibt. Versuche doch alle diese Farben, die sich umher bewegen, festzuhalten. + Πιθανότατα η δεύτερη πιο ψυχεδελική προφύλαξη οθόνης που υπάρχει. Απλά προσπαθήστε να φανταστείτε όλα αυτά τα χρώματα σε κίνηση. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colours moving around. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + Probablemente el segundo salvapantallas más psicodélico que existe. Intente imaginarse todos esos colores moviéndose. + Probablemente el segundo protector de pantalla más psicodélico que existe. Solo intente imaginarse todos esos colores moviéndose. + Probablemente el segundo protector de pantallas más psicodélico. Solo trate de captar todos los colores moviéndose alrededor. + Arvatavasti ajaloo teine kõige psühhedeelsem ekraanisäästja. Püüa lihtsalt kujutleda kõiki neid värve, mis ringi liiguvad. + Ziurrenik existitzen den bigarren pantaila-babesle psikodelikoena. Saiatu kolore guzti horiek mugitzen irudikatzen. + Todennäköisesti toiseksi psykedeelisin olemassa oleva näytönsäästäjä. Kuvittelepa vain kaikki nuo värit lentelemässä ympäriinsä. + Probablement le deuxième économiseur d'écran le plus psychédélique de l'histoire. Essayez seulement d'imaginer toutes ces couleurs en mouvement. + Probablement le deuxième économiseur d'écran le plus psychédélique de l'histoire. Essayez seulement d'imaginer toutes ces couleurs en mouvement. + Probabelmente o segundo protector de pantalla máis psicodélico do mundo. Tan só probe a imaxinarse todas esas cores movéndose ó redor. + כנראה שומר המסך השני בדירוג הפסיכדליות שקיים כיום. פשוט נסו לדמיין את כל הצבעים האלו נעים ממקום למקום. + Vjerojatno drugi najveći psihodelični čuvar zaslona koji postoji. Samo pokušajte zamisliti sve te boje koje se gibaju okolo. + Valószínüleg a második legpszihedelikusabb képernyővédő ami létezik. Csak képzeld el mindezt a színkavalkádot mozogni. + Mungkin screensaver paling psikedelik nomor dua yang pernah ada. Coba bayangkan warna-warni itu bergerak ke sana kemari. + Líklega í öðru sæti yfir klikkuðustu skjáhvíluna sem til er. Reyndi bara að ímynda þér alla þessa liti á hreyfingu. + Probabilmente il secondo salvaschermo più psichedelico di sempre. Prova semplicemente a guardare tutti quei colori che si muovono. + Probably the second most psychedelic screensaver in existence. Just try to picture all those colors moving around. + 아마도 존재하는 두번째로 가장 환상적인 화면보호기. 모든 색깔들이 움직이는 것을 상상해보세요. + Turbūt antra labiausiai psichodelinė ekrano užsklanda pasaulyje. Išbandykite ją ir pamatysite judančių spalvų šventę. + Iespējams viens no vispsihodēliskākajiem ekrānsaudzētājiem pasaulē. Pamēģiniet, lai gūtu priekšstatu par krāsu kustību un plūsmu visapkārt. + Можеби втора нај психоделична заштита на екран. Само обидете се да ги согледате сите тие бои кои се движат. + Waarschlijnlijk de op één na meest psychedelische schermbeveliging ooit. Probeer u het voor te stellen: al die kleuren die door elkaar lopen. + Helt sikkert den nest mest psykadeliske skjermsparern i verden. Bare prøv å se for deg alle de fargene som beveger seg rundt. + Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie. Spróbuj i zobacz ferie poruszających się barw. + Provavelmente, o segundo melhor protector de ecrã psicadélico de sempre. Experimente visualizar todas as cores a moverem-se. + Provavelmente a segundo mais psicodélica proteção de tela existente. Experimente ver todas essas cores se movimentando ao redor da tela. + Probabil al doilea cel mai năucitor screensaver care a existat vreodată. Doar încercați să vă imaginați toate acele culori mișcându-se. + Просто попробуйте представить себе все цвета в движении. + Förmodligen den näst psykedeliska skärmsläckaren som finns. Försök bara att uppfatta alla färger som rör sig runt och runt. + පෙනෙන විදියට සදා පවතින දෙවන මහත් අධිචිත්ත වේගී තිරමෙහෙකරු.වටේ තිබෙන එම සියළු වර්ණ ඡායාරූප කිරීමට උත්සාහ කිරීම පමණයි. + Pravdepodobne druhý najviac hypnotizujúci šetrič obrazovky aký vôbec existuje. Iba si skúste predstaviť všetky tie farby pohybujúc sa okolo. + Gotovo drugi najbolj psihadelični ohranjevalnik zaslona na svetu. Samo predstavljajte si vse te barve, ki letijo naokrog. + Troligen den näst mest psykedeliska skärmsläckaren som existerar. Bara tänk dig alla färgerna som rör på sig. + Эҳтимол аст, ки имрӯз дар тамоми ҷаҳон ин пардаи экран ҷои дуюмро мегирад. Танҳо тасаввур кунед, ки чӣ қадар зебо ҳамаи рангҳояш бозӣ мекунанд. + Muhtemelen insanı hayallere sürükleyen en iyi ikinci ekran koruyucu. Ekranda dolaşan tüm renkleri seyretmeye çalışın. + Напевно, друга серед найбільш психоделічних заставок. Лише уявіть усі ці переливи кольорів. + Đây có thể là trình bảo vệ màn hình gây ảo giác mạnh thứ hai tại thời điểm này. Hãy thử xem các hình ảnh tạo nên từ các màu sắc di chuyển khắp nơi + 或许是排名第二的迷幻效果屏幕保护程序。你将看到所有颜色满处乱飞。 + 可能是現存第二最夢幻的螢幕保護程式。快來嘗試想像一下所有移動中的色彩變化。 + all + + diff --git a/addons/screensaver.gles.stellar/icon.png b/addons/screensaver.gles.stellar/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a6784afc53d95a655742f9b7db247471fc52a105 GIT binary patch literal 5657 zcmd5=%_yf)hI}rNdW+$&`^i!0RZ0Z5f2~+-G*^$ zdC}XzSS?I;T#Z?V*$oLUxq6 zE9lIcr+wgK*+sd{`L^(P-8a3lYQ&E}UA|67z<}ug9WVyQrWc4}FGAmYqBl>1bONzv zC+?Ez!vf2~`U3PpH94L~S5!~e3>{ftnwqYDHkO#%!3Eds-f-vU<#x3ok^P!#c&&Mj zzqU{)hEWAAwchi(#n$&f83OU#4u794xU3pF;=hiq3z=Iyzy>gw6Z9jc|#L>RDEfDP^{ zw1VZPJzaiK3d}>fS&jI4kUS-TdMLJX#O%vmQUu7;ka*&oPz;Dus2GWytedNb0VVFo z=kC>iea=I}ER0DJ)^vpcb6$-b?rJ8LX9^5>nJ}Xg6!55(@FZlJA9&Z2c z!+;}TZ4V{di+qq?Xf=8;-O}LTGYj|nvT$g|IzXn0C-KCg_?NN3#>vI=#XWhw?Wi^+ z^5c(n?^!b~o5{zi??H}^N`*^@ANh^k1$*V8eb%ysgxv^$Gs<9_i2oVtX{VnGo`hq+ zylhDS*9eiVK!Mjpe5VF{IPTn9Mgq4AI)Ep>o|344+WxA@`KN8z(B22(wE%zr&1Wb(!JYd`bl)I`2oCbOeV)*7eJt@Rok8|jq%ZHWu5Ak2x( z`UFt5tE>DaycfyOpHB3v>FWnYB4&^~-QE=wrbh62 zn@A$`0LoZf#ctGs9~hCsirP#OM22xhr~DjQh$2s$IAh95$xVO& zcI->QTatShXtbcLfgS3SfEPF^93rtz6YI-*0?-UuSjH{Z8 z>at!RLM1%!4T?6mr+tW3;$0ZF^9h1MSU+qSkfN+qVan0pj3C9$(Z zjg$p*`xnG=-UpXTg`QTr$bZ+KkmkjM7f<<(oJvf&LnN6o5O;~iCm}~b@LEPWSb~QN zJvrf{&fR@?rCsTVW+tuPtR{j_|4_OdieB5wpOErln*d&^`xYqJB}54VP*d3 z&)HR_0%}>q-`}5IKKOF?%tuz&P=uHyk2`%>v1o6vPOEdVi%Kw@Nh zsjWuVK={$ASC{xw0)zYuzvdKk^U%<6W5MG3WD#Ejd`MLp9;CT{9CUmC2jO!ymsF@> zEJt^3H~ZaVHI7i*i^D?A^p=+9^>{;x7xfK)b&!IRtzcI_RMEO>f}0;4fI<;(ly1&N$3` z-lic`n(t!wdUcV5JB2Ggdf&nj!kCklV<1M7J})(5`kK99*4W%!E?~c>2~v?P3~@C^ zlX#f*?4#Xl7f;*0*W9*Ap;Hk+8EhNdv&>DKEVtG>FH{2TPBet|=osjln*M%-LGu2z zL6!@uFSC7y!qJ0oM~konMa2pq-U#1Mp!gd_SWhtcc~8c~oTsDdcMQ?2n~~swL^X!1 zU11*XYJom55TMsw%_BXl>M{}2WD-1$=>I;lpg%S*dMmaX&mWYf)OX8wAK-SRl0BBP zzA@l068Eb=Je9%tc+6~qLwaHz#^ta7gMzMGf#fH4fLLsE5pRxwC2(Mzkx5C zw7vTiDbg1x93}BMYY{lp9EWlJymk`-D?Ba)BQ@35Zb40#md}y7xw&?h46NCd_GU-K zGI~0z+h?G82a$RIW$drvbmGF!xHz=yk>lgp$C4bf5naT>bUzfw1ow%)-r>PKoE9&}$SiH|ip)kt z;9-&()<{0ja4c^nGqS!$e$9FYSWnjAN}suVph5bo_MONsLq)<;i7%VV7Q}SCuAH%d zLMNI{m@*=+WwbE;v7kzShVaF25xR7xjPwUtI0G~gn z)vub}A?$;;u$@>@qWUID4EfMbSJ~S<9##^~>E0UgzwDtmQB>KgKoZAQcw_K(e7vcq zAA7nD>s5sh!>rjK9pa~8^1;Z=yzbSpAbkkHfEcxOJG3z+EaTK?Zugxnoo=pt88IRB zXqvOYzUEJJ`affS{VZyCta=bM;-fvk!OecIa2$I<`9PXsUL-1va znVb_V!RY8z_|?}$RmTLdcr4+t_)jMmam~}=)=*0G5i;mb3z(sIDqT#g^%Ni&E%1^D zxmd*BDX1hwOAMqQ53VV{l$S%))EB}$4@SA~I-!oT#l{MVq=`x0^J*IAm&Bj#lmoks zsV3eYGvXiAJ>LhsR?z0xok{K}D)7F!cKRJEn;w2ma^s(W&8C&fUJ#wIu}K~9{;iJ` zH7V+;&Y07SBe>e*SRwOfDaLdW{3^W~N-9ey+i^AYPtSZ%MR5$%^s!g*9}f92+4qdU zez3N;p8D=)dq_%2<#NPf2#I<+J+C|eXf$>91vam*um4Wbhle2)I7PA;|LpHiEyS2+ z=j4oqCV!Td)_@;X4_U4Oj#b?X%r!MNt5P24S5Hr-&PB2^I~EDQrzJ+LQ&5`Il-XqA zuPV&m*P{AVpREo2^EpZEM`;L!95dy8$Mhr>ZR`JAw+l%=9y=oc`d5Sq#zg$6@4gW{ z2J=(+Iw<&DyGE3XZv*u-;i2_K*ra6KfXziFGQ=tdW*-Hc?S!T z(NpC~VI@4sDC&1sExFsz464|E@h0e$ua0-Dt!X(IIl9ep#S#4 ziX_7C_Rwm6c+sOxLET(7w&Mi~12b1084)Wtt!@OS^rGpGU|KAwfC_4UJLiEX- zP`(_BpzXDZiIo+7*@&FrpGQMaqM;1=LM!ADmdGOXw>T%bmFXZD(eQ@JJ|fnb5VLu5 zb`{27Qz|WDnf1K0Rd@c|MnmaMfcVQ*h%NeMy||&xOt^)Gq&t%=ToEASU8UE@Lw({m z4XkPQtA}WH?{uD zu}%YCK0+eEf^RhsA38sOxh^Q36O9&O_Cq5^pCX91hLi|sfAi6d|0(@-?p7Gol(9%!s zvY~TS4YaVaeOvM}tuHPtaoMo1d>ro9JuIGDBm`C*K@G{@^;9WeMbmm--&IwXc%;Q$ zCfQs-`80gFaeusrHtBSLqpqfoERlkOa_VBcQcsNF&|l$_YZ`k9)Q7EWFEuUO?>RO8 zZc#P#_4PHvz~AcWb!587$e10A4Am*-kP}$Z20e7PzEV4`&8RkGm)84!64;uwgc!_h$W6()k z+XeP?;6rc!)b!Lki}m?P#=3eRH;9~%wr0n7NdmW7>EG|!)PRA-6JV?TPd&Z!P+q~_nc0`O(Gln;7?+~vWa z9EAJ&$1D-bYbAvTRQDr-{^X$gl!lh&9{p#HlQ&zi> z%d#}SnT(Bm+UwCf5|9O2kMo-~vY0D>&1azzOQK4JoWg7bqhL_-6O>^_qJ-&7T_GMj z&{d}|SV4R#g$6OCj9Guk9IafN*Omq1tb70J6fDI@qR+Q5DJ(XTrAhV<9 zS$!p$kqdI#O=pMB`T#}l9RoIvVqD6&1d2=@kM+LQ715}8Bn(JQkX0{`V9(zx1fvQ; zLG|V1HwOHSWI;D)2(NeGt2)&jro$XR0{L1zP= z(Vzk#3)E)mYu99*qIUeQ{2mxFoJ<6K!`!b51|E~bO{oc%jQ*Z=cD0+mi(C`MMT0y& zDC-@3JN>5bmJk&HW~BF-+Jur!@-Eek-Yssfek=jz-{kztOH>tKV9wm-0h^W%l+UX#F1wq)~lB}t= z?q*_bk5um3PfOJ!l*tAZcCqlvt&{XP5Vt*Dr5W_LD%_^7-s zYA0b$eB?hfI~#Po8zht-#UVXAX*l`+i-JObQMW$o3SDZ)@RXJgyF8tlnI4wEi5^(n`yI&J!$OQ-?PPl&1onO?v7%w5DiNX?gHkZcFcyYdis#Jjc`uhBPF|)X_QRaG8pMk^SK6`ZccI4)=xw!1i zgz-@$tZ{jd87k=-{S*C-SaKmZ^VjTRn9Nd6`EXgh;Hf}{FzM?g zQ=$AGrF&jWLqkLJmzUVp0jp1^ai;^}eU!p4jI0J`f~*5HOc;F&IvYRsG4^m0jOL)A zRzwL2I@pk)gCw~u#t2+~&tc|m;!H{Xgt0<{7d8$V3HA3}_jk8s!>{#C0KRMe=h{zV#)M?A0%Nm zm&YzUE+WEh_9|U*&NO~Ke{@A2%}T>8i@f`pnt(gyG%PBKrhY_T+BHC6WcqEx{7A;z z!JzAw{%qkFuVfj$UR0DNoQpDo@6guWeIeL7$5@_ViJ7L@QfuK_9?h7|m7Sum|1xw| zSCZ@QKgM4sg>jwMZc%F86Au{a1L|LVn>HC*+q0CCx?6qOepVeaq2!F04`EgE@DOH= ztoPuL5&g(SFdDs-{<=h^^5jAm+JafPKiMVei8_xQmkNmgH48Lsw>#-wc@0Jer zmJP=mO)18Ia~P(_NLrvl{q-J=*5!rwdg<}h<>eh$R%X@^HdC(F{oR=Z*%>B3L3VE= z*f^ymXhlBDyly0ag~=I<7}SRt|^E{(nylbLBVkn|D0 zj%fwa9nNK)bt=O*@!_fHIRECsLEasi83=a>2*d&wwy@At#D6?cQct0p1dtrO6D)D& ztMQTMk9MI>yywmJyhdg#D~fN|%#VmACR!=EVLDieC+0uZ5(H5CpM>|;SqpFnC>g0) V_ay9mdAsWcG*q;qwMtfz{|8C@VfFw3 literal 0 HcmV?d00001 diff --git a/addons/screensaver.gles.warp/addon.xml b/addons/screensaver.gles.warp/addon.xml new file mode 100644 index 0000000..b39c5f6 --- /dev/null +++ b/addons/screensaver.gles.warp/addon.xml @@ -0,0 +1,119 @@ + + + + + + + + Omtrent so psigedelies soos sluimerskerm kan kom + حول الحصول على مهدء كشاشة التوقف + Падобны на псіхадэлічны ахоўнік экрану + Колкото халюциногенен може да бъде един скрийнсейвър + Quant al més psicodèlic dels estalvis de pantalla + Nejdivočejší šetřič obrazovky všech dob + Mor seicadelig ag y mae modd bod + Omtrent så psykedelisk som en pauseskærm kan blive. + So psychedelisch wie ein Bildschirmschoner nur sein kann + Όσο πιο ψυχεδελική μπορεί να είναι μία προφύλαξη οθόνης + Screenbending screensaver + About as psychedelic as screensavers get + About as psychedelic as screensavers get + About as psychedelic as screensavers get + El más psicodélico de los salvapantallas + Tan psicodélico como un protector de pantalla pueda serlo + Tan psicodélico como cualquier protector de pantalla debería + Nii psühhedeelne kui üks ekraanisäästja olla saab + Pantaila-babesleetatik psikodelikoena + Mahdollisesti kaikkein psykedeelisin näytönsäästäjä + Difficilement plus psychédélique comme économiseur d'écran + Il y a pas d'économiseur d'écran plus psychédélique + Máis ou menos tan psicodélico como o pode ser un protector de pantalla + זהו שומר המסך הפסיכדלי ביותר שיכול להיות + Psihodeličan koliko čuvar zaslona može biti + A legpszihedelikusabb képernyővédő + Sepsikedelik mungkin dari sebuah screensaver + Eins geggjuð og skjáhvíla getur orðið + Quanto di più psichedelico possa essere un salvaschermo + スクリーンセーバーはここまでサイケになれる + 싸이키델릭 화면보호기 + Psihodelinė užsklanda nunešanti stoga + Cik nu vien psihodēlisks ekrānsaudzētājs var būt + Најпсиходелична заштита на екран + Een meer psychedelische schermbeveiliging vindt u niet + Så psykadelisk som en skjermsparer kan bli + Tak psychodeliczny jak tylko się da + Um protector de ecrã mais psicadélico do que este? Impossível. + Protetor de Tela Psicodélico + Un protector ecran cât se poate de năucitor + Самая психоделическая в мире заставка + Ungefär så psykedelisk som en skärmsläckare kan bli + Tak psychodelický ako to len ide + Najbolj psihadelični ohranjevalnik zaslona + Ungefär så psykedelisk som en skärmsläckare kan bli + Дар тамоми ҷаҳон ин пардаи экран аз ҳама беҳтарин аст + İnsanı hayallere sürükleyen bir ekran koruyucu + Настільки психоделічна наскільки можливо для заставки + Tạo ra ảo giác mạnh nhất mà trình bảo vệ màn hình có thể có được + 最具迷幻效果的屏幕保护程序 + 最具夢幻效果的螢幕保護程式 + Die is omtrent so psigedelies soos sluimerskerm kan kom. mogumbo het gedink sy Plasma beskermer was heel voor in die koor, maar die een sal jou maag selfs meer laat draai. Jy beter een van daardie vlug siekte sakke kry voor jy te lank na hierdie een staar. + هذا حول الحصول على مهدء كشاشة التوقف. اعتقد موغمبو أن شاشة توقف البلازمة خاصته في قمة الجدول, لكن هذا مقرف أكثر. الأفضل أن تجد أحد أكياس الغثيان قبل أن تنظر لهذا لوقت طويل. + This is about as psychedelic as screensavers get. mogumbo thought his Plasma saver was at the top of the scale, but this one is even more nauseating. You'd better find one of those air sickness bags before you stare at this one for too long. + Точно колкото може един скрийнсейвър. mogumbo смяташе, че неговият "Plasma saver" е върхът, но този е по-смущаващ. Препоръчвам Ви да вземете една торбичка/леген, преди да зазяпате в скрийнсейвъра по-дълго отколкото трябва. + Aquest és probablement el més psicodèlic dels estalvis de pantalla. mogumbo va pensar que el seu estalvi Plasma estava al capdamunt, però aquest és més nauseabund. Serà millor que agafis una bossa per als marejos si has d'estar molta estona mirant-lo. + Asi nejdivočejší šetřič obrazovky všech dob. Použití plazmového šetřiče bývalo vrcholem, ale tento spořič je ještě více zneklidňující. Připravte si pytlíky na zvracení pokud se jej rozhodnete sledovat příliš dlouho. + Mor seicadelig ag y mae modd bod. Roedd mogumbo'n meddwl fod ei arbedwr Plasma ar frig y rhestr, ond mae hwn hyd yn oed yn fwy troëdig. Gwell dod o hyd i fag salwch cyn edrych ar hwn yn rhy hir. + Dette er omtrent så psykedelisk som en pauseskærm kan blive. Mogumbo troede hans Plasma-pauseskærm var i toppen af skalaen, men denne er endnu mere kvalmende. Du må hellere finde en papirpose, inden du kigger alt for længe på denne. + In etwa so ​​psychedelisch wie ein Bildschirmschoner nur sein kann. mogumbo dachte, sein Plasma-Bildschirmschoner wäre bereits abstoßend, aber dieser hier ist noch verabscheuenswürdiger. Kram' besser schon mal eine Kotztüte hervor, bevor Du diesen Bildschirmschoner zu lange anstarrst. + Αυτή είναι η πιο ψυχεδελική προφύλαξη οθόνης που υπάρχει. Ο mogumbo νόμιζε ότι η Plasma προφ. οθόνης του ήταν η κορυφαία, αλλά αυτή είναι ακόμα πιο μπερδεμένη. Καλύτερα να βρείτε μία από εκείνες τις σακούλες για τη ναυτία προτού την κοιτάξετε για πολλή ώρα. + This is about as psychedelic as screensavers get. mogumbo thought his Plasma saver was at the top of the scale, but this one is even more nauseating. You'd better find one of those air sickness bags before you stare at this one for too long. + This is about as psychedelic as screensavers get. mogumbo thought his Plasma saver was at the top of the scale, but this one is even more nauseating. You'd better find one of those air sickness bags before you stare at this one for too long. + This is about as psychedelic as screensavers get. mogumbo thought his Plasma saver was at the top of the scale, but this one is even more nauseating. You'd better find one of those air sickness bags before you stare at this one for too long. + This is about as psychedelic as screensavers get. mogumbo thought his Plasma saver was at the top of the scale, but this one is even more nauseating. You'd better find one of those air sickness bags before you stare at this one for too long. + Este es probablemente el más psicodélico de los salvapantallas. Mogumbo -el autor- pensó que su protector 'Plasma' estaba en lo más alto, pero éste es más repugnante. Será mejor que cojas una bolsa para los mareos si vas a estar mucho tiempo viéndolo. + Este es probablemente el más psicodélico de los protectores de pantalla. mogumbo pensó que su protector de Plasma estaba en lo mas alto, pero éste es más repugnante. Será mejor que busques una bolsa para los mareos si vas a estar mucho tiempo viéndolo. + Esto es tan psicodélico como un protector de pantalla debe ser, mogumbo pensó que su protector Plasma estaba en la cima del mundo, pero éste es aún más nauseabundo. Deberías conseguir una bolsa para mareos antes de quedarte observando por mucho tiempo. + See on nii psühhedeelne kui üks ekraanisäästja olla saab. mogumbo arvas, et tema Plasma säästja oli tippude tipp, aga see on isegi rohkem iiveldama ajav. Parem otsi endale üks neist lennuki oksekottidest enne kui liiga kauaks seda siin vaatama jääd. + Hau ziurrenik inoiz sortu den pantaila-babesle psikodelikoena da. Mogunbo sortzaileak bere Plasma babeslea garaiena zuela uste zuen baina hau oraindik nazkagarriago da. Ikusten denbora asko egon behar bazara hobe zorabiorako poltsa bat edukitzea. + Tämä on mahdollisesti niin psykedeelinen kuin vain näytönsäästäjä voi olla. mogumbo luuli, että hänen Plasma-näytönäästäjänsä oli asteikon huipulla, mutta tämä ohittaa senkin. Oksennuspussin hakeminen on suositeltavaa ennen pitkäaikaista tuijottamista. + En terme d'économiseur, on fait difficilement plus psychédélique. Mogumbo pensait son économiseur Plasma tout en haut de l'échelle mais, celui-ci donne encore plus la nausée. Mieux vaut se munir d'un de ces sachets pour le mal de l'air avant de le regarder trop longtemps. + On fait difficilement plus psychédélique comme économiseur d'écran. mogumbo pensait que son économiseur Plasma était tout en haut de l'échelle mais, celui-ci donne encore plus la nausée. Vous devriez trouver un de ces sacs pour le mal de l'air avant de le fixer trop longtemps. + Este é máis ou menos tan psicodélico como pode selo un protector de pantalla. mogumbo pensou que o seu protector de pantalla Plasma era do mello, pero este é aínda máis mareante. Será mellor que colla unha bolsa contra o mareo antes de quedar pampo mirando para el. + זהו שומר מסך הכי פסיכדלי שניתן להיות. mogumbo חשב ששומר מסך הפלזמה שלו הגיע לראש הטבלה, אך שומר זה יגרום לתחושת סחרחורת גדולה יותר. מוטב להצטייד במספר שקיות הקאה בטרם בהיה ממושכת. + Psihodeličan koliko čuvar zaslona može biti. Mogumbo kroz svoj plazma čuvar zaslona je bio vrh, ali od ovog vam je još više loše. Bilo bi vam bolje da pronađete jednu od onih vrećica za mučninu što dijele u avionima prije nego počnete zuriti u ovaj. + Ez a legpszihedelikusabb képernyővédő. mogumbo úgy gondolta, hogy a Plasma képernyővédő van a lista tetején,de ez még inkább kábító. Jobb ha keresel egy légibetegség zacskót mielőtt túl sokáig néznéd a képernyőt. + Ini adalah sepsikedelik mungkin dari sebuah screensaver. mogumbo mengira Plasma savernya berada di puncak, Tapi ini bahkan lebih memabukkan. Anda sebaiknya mencari kantung mabuk terlebih dahulu sebelum menatapnya terlalu lama. + Þetta er líklega eins geggjað og skjáhvílur geta orðið. mogumbo hélt að Plasma skjáhvílan væri á toppnum, en þessi gerir þig meira flökurt. Best fyrir þig að redda þér ælupoka áður en þú starir á þetta í einhvern tíma. + Questo è quanto di più psichedelico possa essere un salvaschermo. mogumbo pensava che il suo salvaschermo 'Plasma' fosse al massimo della psichedelicità, ma questo è anche più nauseante. Faresti meglio a cercare uno di quei sacchetti per il mal d'aria prima di fissarlo troppo a lungo. + This is about as psychedelic as screensavers get. mogumbo thought his Plasma saver was at the top of the scale, but this one is even more nauseating. You'd better find one of those air sickness bags before you stare at this one for too long. + 싸이키델릭한 화면보호기입니다. 거의 토나올 정도의 화면보호기로 오래 쳐다보려면 봉투를 준비하는것이 좋을겁니다. + Tai stogą nunešanti psichodelinė užsklanda. Mogumbo galvojo, kad jo Plasma užsklandos niekas neperšoks, tačiau ši užsklanda tai kažkas tokio. Geriau susiraskite vieną iš tų lėktuvo maišelių, jei supykintų, prieš spoksant į tai per ilgai.. + Ekrānsaudzētājs nevarētu būt vēl vairāk psihodēlisks. mogumbo domāja, ka viņa "Plasma saver" bija saraksta augšgalā, bet šis ir vēl šķebinošāks. Labāk apsēdies un sameklē kādu maisņu nelabai dūšai pirms skaties šo pārāk ilgi. + This is about as psychedelic as screensavers get. mogumbo thought his Plasma saver was at the top of the scale, but this one is even more nauseating. You'd better find one of those air sickness bags before you stare at this one for too long. + Ongetwijfeld de meest psychedelische screensaver. mogumbo dacht dat zijn Plasmascreensaver al bovenaan deze lijst stond, maar deze is nóg meer misselijkmakend. Houd uw braakzakje bij de hand, mocht u hier te lang naar staren. + Dette er så psykadelisk som en skjermsparer kan bli. Mogumbo trodde hans Plasma skjermsparer var på toppen av skalaen, men denne er enda mer kvalmende. Du bør skaffe deg en sånn spypose som de deler ut på fly før du stirrer på denne for lenge. + Tak psychodeliczny wygaszacz jak tylko się da. Lepiej zaopatrz się w worki na chorobę lokomocyjną. + Provavelmente o protector de ecrã mais psicadélico de sempre. O autor, mogumbo, julgava que a sua proteção 'Plasma' estava no topo da escala, mas este é ainda mais repugnante. É melhor encontrar um desses sacos de enjoo antes de ficar pregado nele durante muito tempo. + Esta é provavelmente a proteção de tela mais psicodélica de todos os tempos. O mogumbo, pensou que a sua proteção de tela 'Plasma' estava no topo da escala de proteções nauseantes mas esta parece ainda pior. Procure um saco de enjoo e sente-se, se vai ficar muito tempo a olhar para a tela. + Acesta este un screensaver cât se poate de năucitor. mogumbo credea că screensaverul creat de el, Plasma este pe primul loc, dar acest screensaver este și mai amețitor. Ar trebui să căutați o pungă să nu vi se facă rău înainte de a vă uita la acesta prea mult. + Самая психоделическая в мире заставка. mogumbo считал, что никто не сможет достичь эффекта его заставки Plasma, но от этой заставки укачивает ещё сильнее. Если будете смотреть на эту заставку слишком долго, вам очень скоро понадобится гигиенический пакет. + Det här är ungefär så psykedelisk skärmsläckare kan bli. mogumbo trodde hans plasma-skärmsläckare var toppen på skalan, men denna är till och med ännu mer kväljande. Du gör bäst i att leta upp en åksjukepåse innan du stirrar på denna för länge. + Tento šetrič je tak psychodelický ako to len ide. Mogumbo myslel, že Plasma šetrič je na vrchole rebríčka, ale tento je ešte viac zvrátený. Radšej si nájdite hygienické vrecko skôr než naň budete civieť pridlho. + Težko bi si zamislili bolj psihadeličen ohranjevalnik zaslona. mogumbo je menil, da je njegov ohranjevalnik Plasma na vrhu, to da ta še bolj vzbuja slabost. Bolje, da najdete eno izmed tistih vrečk za bruhanje, preden predolgo strmite vanj. + Detta är ungefär så psykedelisk som en skärmsläckare kan bli. mogumbo trodde att hans Plasma Saver var toppen på skalan, men denna gör dig ännu mer illamående. Det är nog bäst att du letar upp en påse för flygsjuka innan du sätter dig ned och stirrar på denna för länge. + Дар тамоми ҷаҳон ин пардаи экран аз ҳама беҳтарин буда дар рейтинги пардаҳои экран ҷои якумро бо пардаи плазмаи худ гирифт. Вақте ки истифодаи ин пардаи экранро сар мекунед, аз истифодаи он ҳеҷ гоҳ рад намекунед. + Bu, insanı hayallere sürükleyen bir ekran koruyucudur. mogumbo kendisine ait bu Plazma ekran koruyucunun skalanın en üstünde olduğunu düşünüyor, ancak daha ziyade insanın içini kaldırıyor. Bu ekran koruyucuyu uzun süre seyretmeden önce mide bulantınız için gerekli önlemleri almanız iyi olur. + Сама психоделічна в світі заставка. mogumbo вважав, що ніхто не зможе досягти ефекту його заставки плазми, але від цієї заставки заколисує ще сильніше. Якщо будете дивитися на цю заставку занадто довго, вам дуже скоро знадобиться гігієнічний пакет. + Chú trọng để tạo ra ảo giác mạnh nhất mà trình bảo vệ màn hình có thể có được. Mogumbo từng nghĩ trình bảo vệ Plasma của mình đã đỉnh, nhưng trình này còn kinh khủng hơn. Tốt hơn hết là bạn nên chuẩn bị một túi chống nôn cho mình trước khi bắt đầu nhìn vào nó quá lâu + 这大概是最具迷幻效果的屏幕保护程序了。mogumbo 以为他的 Plasma 屏保已经是数一数二了,但这个更令人犯晕。如果你要长时间盯视它最好先准备一个晕机袋。 + 這大概是最具夢幻效果的屏幕保護程序了。 mogumbo以為他的電漿螢幕保護程式已經是數一數二了,但這個更令人頭昏腦脹。如果你要長時間盯視它最好先準備一個夠用的暈機嘔吐袋。 + all + + diff --git a/addons/screensaver.gles.warp/icon.png b/addons/screensaver.gles.warp/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cc2beea958a46bf3d9ecec1a3205be641b1b4555 GIT binary patch literal 9424 zcmdUVRajg>v+ZCL1`qBG5+EeN;6Voq9$bSvK?4MLCj@tw5Znd{gy8NLY;bpXhco|q zyASui+?R8ndVhO&clB4jt7_G%`mU@fjg3K$0RRB7Wo0B)0RSY#BN6}|88J-aK{*fu z*|(3{-_#r|zPTAYnFGYk98Ao?vUbLn=Bnn#W*&|M=0X4fgOjYJn7aG?p*~1keWx+o z_$yNAn@?RVR-&Jhkd9k=Dag*%qvRy>ne7NwRlFwsuQd~DQW>rFem1b=axg|&C1)5- z)s?J9AjQw`fbwOnope4$<_6N)m}#gOAA5~Loj;6XK~S)`+HVS}!knKka{MfoZyuIU zpczvOmUY3Rq@}RDDt}RAFrEwm6&d6&3P!?1X8<4vpo)TH0qCgsfPnwWAOBzHhR7Jp z8+HIfK37;c{8D}EL&4xLHhRvMyx~Ja4)%xz09iJ!=Gfm)=)8gH@zv zQO^fKtc@hqXzMzx(@YJpPVkj176ZU0uQhe%{^X6&G!OgZd3!s6N0*_;FaGfnIeH{= zhYEGJRN@z2kO}Fa92iME@&0qok8!rggZ=&e?QLRG!rkNEj-{-Jh69m|j0|}>xl=}V z_O`}?#=2jGR$sov&CB%cDqu+{gH#=ICb~b$tG2bY=(}q)G>NQ}qoc01i9%YHT(xv` zKpLW$Xm@vdmAiOBQNDqs*8dR}d5?U7G%HOF(gZ@O$oF@4ERQ)hx3;!Q)zR+I3R2|r zkQ7mQLz5tcW}?V2@YTZUN#a{2$@hAsgoINs5~bzkswGYr=NDsHf<;xR)#NgOU=e0# zmtv^%cI57^)y=W34-}9jK^&Xqb9Zho2BPvDPo4=<1u+0>YYmI-#XK$C%fs&P`PXFb z<1!C3lXV+xZMo^jl@JpGL5G&z4jUyeyZNU01o-zIyEphbj(6au++2UHfT(C5as^H> zQtIqAEOupP#=^m}!EC^Rj*iZAt~NhE|G87Q!QPm}=lQLioLn@e?AXA-Ys$DNgGL2p zFlnXRoVQ5dQ++*0Oth?w45^LD>Z{qK!^6X)qcB{WXstAbnIpzepFRywHq_TIxB5_Y z?h+U#CSR+#y5i(uaT_gL;U)Gn0G!i&X|KmJIZU?(iJTf2Q%5>nNJvPOX{t;ED0Gq{`VxwZ2$4Nb{)+dI<$>zZH^cypFiLW>*^5m#jxjr%gxL`RdIYoZn-g;J6 z#T*MF!xCV7A0J`nAI!_9>vUg4U803@F=SrrPhad-8zMBWATK{OaHsb!07s2mlTgLYDJib2qGDosBcg0rG5{Y&K*!}m6lK~J)q}BoZzLHCacA=4AIJO@V2dR`(tHpp zxNSLdt+u>;s-=V~B;b0yLsS-x)6$aUr-LDJtDRj{^LY`Qq8(t(+sCJ+xf$=O%Af^f z`|3U52LI-GNuo2LsBbw>%FWG9(>He?Qj$~c>+8HT+A=xsnRgqw{dlOzHbaYqWpQm2 z2sOM?%n@n%@#g_<8WTmyUsGOwIRD#*IIk6_{dRtSetUcSHN8}OJS|gQeSJDNWV3o8 zf$3dR$H$%?=+k9F>a%LuEC7@n10TD93VHjQnVFGX2yOI61x@~OKQob+|DoZ72gy$A zDPC%6X^F#zcbA|FdFJOoh1YPtmX^scUHLTLRuCB7t(XtaiHm zbiJBdvX+jQ9Q^r!8F|Y|Lt6y}1yNB^DB|!{pHH8#dn4mEP|_2tVAGR%dGCqZ<*Pm6 z)<<}tTy~6=>w2x{%c5%2KG$B~TMRh0&DTdpAJKlIZ0hCS>1m>P$d?G>5~F_`F(f2J zE024HJPWk=qE*bDaHwiF4hK!OVDY)3AsaZ%n6Us^lL#!k{bZOu zJ&#zx-q|+u_&D}r%VXuMd=*W~v3|Zaq-k>>)!pKCW53)CLi*Fxl<}De6%7py2;AJ> z{#-=$(<|s&52+jwuK(KRRFY3xTKYrSJFQBrblfO)Wdj2?5#s@OZ12m7Fbuz!`iDgY z$EIx@fVE9HW+IZOq;Fzd^PLJaVVhy&zxG*{guB~Yy}#eSxN zg~ifJNJwDM(++JT;fpGDLHRD`vhipvPq*K+wzis^o8O$Q&?FiHC?~Q6-HgsY3EM`h zuO2+?@~wDxEzp+mSRt;k?6i$r;B#A4QIVyoY5s4j{r!uR4)tp;Fo#pEL{AT&!!tu` zetrSBD39pazM&bw1g@#?Jp%cCAWOwq23B!AMvX8N&Zq+c@SA z2dC z5FMn#%fqAp=d|Va@1XCsI0Hbf1=nq0h#vZK_k+E)cm?QU9K&8qo}Mb?QBzh{CRb3C z2;4m$XS4y#d9HP$-P_Rk-mcBhf4)yvKx?w_+!@s;SF<;r%pnIOU5cU{0jr#)kL0(D z8pva>8-V@DX@`E*wlWZg^U?+F7+uo8DIq3&9tkLzn7DSmeu_nv0WkK1waLm){C0;p z5?+6<+2pf6`i5r?z^u)Y6@9S}JB-)4j~EUJ4@dX%^7@_j9|5~q@|g>1IA3J8EHfOLzf|!T#HLf-ZWQlFwGpvzG9#= zyqJQ($LLdhVL%yx6a&(;pO_c}0JA+R!>y3Ky@q_(3?qCTH&*b2%&-S@BeotaD-&Gs#KL!Hbo#3EuqGb(Zk0ESmuS{i&{Dgz)M1bjmucIqD+<2%4E zkOeG}04ggh5wGa_hla{ZD&wrh$l5tMbLj!e;`0G0sz>>|1IRi*0m^DfMjV^lrEs-B zjeX-8N5~%dqAB>R>?pkML_!_qf7Dgu?MG3<&l-E=pI?~fIdc~gf}u^Ou-0a%qNCI3I9Z6W-a#`?;+K)Xf(uBJ zZnfFOKSo1N{%$bh?O(^@;fub|va>r(7LMp0S{^oVINUZ!A(0APDP1H#nc|S`E`}+% zKbEw#2xlQrIn?ju*VW}q$IQd~ZOu7Lj9$WIfOr=M3g0HmEHp!*{1py+>=TQre>Uzy z4#^;=&<@EF-*!tKomc;Grlw~4&FXpS_HVi>UfWd!-iX~ zCZo!?;{Q!^MfuV}aBwu|!dxjj9^eZ%CVz8`9; zzlxRQdZoxD41e1p)0I%Bir95}YAW!ezP?`QOi)OvZHZcc|A=c|_0TW&BJ%b~txy4J zBOJ(N*MD_M@PqUEZe5hMgFTGZ*p$y8?JVg zW{1hd3`}A+^eiH4VKJ=&)w4F-n}tMuR*8BR7Pf!H;9&;GBGB2FP=e4L8n+Suj#pu? zot$5vjcxDjXw9nED!+(MrO4cmTxc5rkRRr{>Jj*dIG8;=T-(a7FQcZWw$bB5ngY7w zI*3^_ed_5_%}!rG3{rO!Biakr0K-!f6SIZO2FKXPsYj7d!eo13lvk{#0g{KW?iLVG zpw_Vq_)ciHrl!Vv?%cedc}Nl&^1-s;W(TEK1E|rVpgx8{VI%dO7@-}Le>QER`ZMzH zpHgq1M*(zWV-tS8YFzjP1mzbE>LpH%bLbTk)7TV0>48$E>xwouDvpkpjDsB=%VQ4Z z!AsvNFwOjNcAQ^Y z+d85AZwIXXR(E#`TwGi@brm6*&t}GEV{{}N7sZ%cT?&03 zh&vf-AdZn}8XD8AtgKXeDMDWfLte&2{Ym`1G&{X8%>ZYaFR);( zqbCf1yg{D8-j1jYp-t|auHn1}Hg=shu&81>>+DlgGEYIYI`4?H`|*Q{46W1b1cx=f z(@YwWmgi+0I_R|X{n0QxEA9y8D<6OFO~>_DYD|PcA``>JenV2;?8O1FIGbw6rdfw7 z($11AkQfdLYsYo+W)AJ0Yn-_gzWLnik{`-RllJ!Kr&x0&%}EV<`4b-#!$g^H%RR0) zWIX>SLUC10Mh_s7W-($Omr|_4)C1tvzi-gS&la?wgk3rRaoOGv@EiiEN51!~z>`SmZVCA0_X3%@AwZx`jFZWK|7?f7DUdsr3H>F%kwOsW z;VFX1NQBp0@Sg7y2u8dp0!7LT!&^~g0iVgfcH@usH~hIcJ3TEfF2)P-tGL(;ep*-4 zrfIg%^J?ACxvgj$W?ueb;1XT#f@unr;_=ss!jrCQZuUNF?B3{$q2Vx*^ziV2LcfkK zEHqVCMz>h5t;{615&lj%U2%kKdPNngWJf!Uke6H)qAGk1`KfPHX+*5w_nw0ro29is zDoU(^k1KC7`!|^Y4(x>s;O6wn)wTWumY{$D4vh$9y!-81*n=GdoWzw?Mv>y#P5|?T zYIdNZ!OO#=ljnEC?}06+<6rh8lR^t<;kaH6m=xAy$Wz%E{a545Y|Hxrc7l~S_($n> zC1n0qZu7>l5IX|K$H1shlU4Pv99OJcxp?uFl$5ga5&***D1a1pLt;I=mnWNS9$|}N zQWBDs=j!L%fjDP)jvv%1*zF}N)Q^LH%PH)zyqwSVC>>(lIcw;1by(#$lFDV=+5Me> zado6OilVu>8P!!W?Y#TSW~(#jq~*pyZ;^&-^PHx&4Q4Z2SzrHPcXP5q@ikFUkC`pI z{ieN`nq1&uQ71{87JTr4n15K?*6L9!!XzjU=UMm_b>cl+nML5sLCYlgaFXL2kylf3 z`ZBIl%SK2dMx=laN0y(seY#oc62A<^-Rf_kQ8nmCCiBlS@?a3w*Vfk8XKfAxwkta8 zzD(pxYiVdKwRmZD(%e7Yw)asbK(m_sVmJ22#~oUq|H5F(CF;IsJv&=l=1p#G)dx}f z+8VJr&^PXbQ4t5&*x2Te{6gBPSy^awqp2JOCsb5hXO51>wU$hb3}(M*99>-}|1m#2R!IF9c|4P7)DS%-;i54Xwf!S4$Ulo2G<=WhdWpM_S^B`t zdNgyStG^f`6&|h_eI6X_j;B>|b&>ntAS)~L!@7U~n?W7A-@Vf1?7!j`ST3GCF{{C5 z@JAds5IGF9-JEicL zzR#ybW#bkP(Nyp+fHwa7j(P&7ds8jA*XDYUoH;r$XzOBo4Ek*s5_-S(;_ENWZgBbD z0GCRD+w1zUC6dHREWfN zL_-EdyGeSd1AH%?ji>Zgw*2w^hiffuT^2t@@?+CJ6IA% ziHcze1HZSuUjO(*g`K{&QnvxeJ1XjX$HRF|P03_ol}>GM-vUKerjU#Ea`Rn35qsNX zO@6{;z1>1JhU5L_0734~_0dAL)~T1Y>OVvxH$e-hp=!C@;<15H+df|}I0Q5oDQ1at zitX$&2?;Is^-(zZ-VK%XQ&%%K9{so8R>sRgWm z%0D{Xf=Ta6)Y5EbD}o}3&o~RQjCvW`cK|wKVzlv`x&|sLjt4WW)zYujMml__TKk2> zJ3TBNO52~0ah^(ND|BO4JrCg=5PVcSE2~WIy|c-*B7MC~vB{~aDRyV)7z;Chz*qF* z8}HV;H-saogmf;>$=x%c<)4$v1Rlbm<;Y7!5&px&!@Z%QusP!u-v?IGm|_2A1c-~K z5d?k?x?gCpb8~X-q^>4@)VzI2NlG!cm5#9hcZu>wVMocQuu5!H=+;w;c;6-{;izF7 zJ*R=6<;oHh3AMl0-|kPB3Dk1Gm%d?rIP2o$;Q?*$3?>cn&SwyO;{&}7D7#(@Bg6yX z{%oi73qkH^%4R5bO!8D!5rs zgf{wi_n9f_FNk|M?2yIUUk{6-lBPvmt5Xk>!921>6bQudLo)|lWPr0>AS<%61GfB} z{t(u#)&2c>ErR^WCq&E-oE4|Oz1@fr9FBQi1Z|gx0O@UMpuV<1`r6+gL$-bQox5Foh^ce8MfRgj`<~rGgTq2S_UNl1|k9lDlWtz06w-@x8(41NYmAJUWTPZf&NG^BgC7fl>8#Mev!n?QQ z4~~wGN@1Z9X)N|wZETd4`*WGNft2@>t8MOQbh_bnwN6_nHV6CgPufka0J!oN4o(W& z6SKi@Q)&EN^yL^TKAe%&+O>^@+`UagUtU?CvoM-JonUVyEl_u_?b2Tjcyfqc>aE-I z+>cbB(~X!Aja4>oM(&^u1o!BA2v>m-T7QLnf;|AQV+3tQ;EA7$Tru zp!&wqTPg1Rj2abrLWPXJTh6_!*7NFz)!mG)7oJTTrey{_g+h*qPe)(~99H}XeVtGf z$q&I~_Xq|~zkZr4=KuR{nsQ@nvak*YlUYQuti!;-+qhfr4ILN-gNvfuqYIAM*dD|I6V(1N831HE3Ib9X&{cIVzu$4EF-$!^F!mdZK z&W(@R2^}0<&j;ntK@|~K9%mm@g7CP_x&3ae-Gd$`OiWEbclfX|1?#jZ9 zGQ{-Uw&n3jg(QdiK$7PGyFaDXU?Hcv-5-~CEwyCNJ>(l;g z%P-aQ5BGsiSwEN2eJ9HeR@LNoLM`BJ)fI|;dd8%by(#2ltYU4=viKMQ*VYDCTF1+Y zysXm<$jXj)MgRJR3w?y}^75Lji5s^Y`rd6FFEyPkH@(}!wF^3?mx^q62Q&1a819S- z3JQLdloUm=`abBjP=A!$nvt;}=ymhcZ!Ou~EMV9^m=qT;rtNaz~O;(NJto#B$iQ_an{ZKnUJZU z#^Gnx92`bM>qR%kDt_9((?5M+xdlKuwv7npysYfqp@?R6AX0|m8m;Y*WnR1G_l2$B*FFtq))fj(FW2dl zQ3`oo+m8M)+z2PiRrWtKH`iKNmKRCxUdRpNf6xz}0R$gOF>IW~G3 zA7{~J35keIg|Cy+JTN>Qju#u<5h0uKmo)#6r{3;f|KF>^W*|S8ie^f6V36O-%F9SJ zWHgJ*a!l9DogyE&*Wo@zTb$})*zJQ1=d!<6OVZU-kF>oWmtfn{W5QPWr@E#C3L;N# zV~CFvb-v+AGegi^w|we?Z`D;)0)!x*msV#W@z{Pb6 zT_GD%rCmHQ@HV^&OliW3Yy(pT`JFw#I>~4MkRU! z0)ZcL6oazz59n_?N)n2U>SkL1*4Ndc{uFI61#a z<6A}L;t+)JA#j;kRJFs32o`Bjhw{t)fMJI(7Q=qy4h-{f_i}GiFZ!s;3mI#IT+|R{ z-cvm=0uL)&$b(bY>twkF!TrI=$ak+PX}M9ZstnuM*oa~^lwa5X{*4)91eti0(c#}6 z$#Db_1X}%t&>@RaY&ZS>eWmrft+b@#W6;IUn3q>f=R6sgMdr)wU4?Fgzw^ONm7n9) zK7y?wCMJrZ5G2;tY^BO6c6&j!RQ%JA#zH>r-xH>TG!kE^XPVesKckTp-`aGzZ z$(PxbO1S4%hUNL7!B++S*}@LK zXE9vL=--;W?`npJCm(Lwe$WUzIWo+IhJ-}b)e5>DQv%iW)VWPI!>7wMiAYG2PH%iE zFnIhm&{vVLPuWRYU!JAR&6SOEjhyhB5e(^B#9@r5;*M|DsxW>J4=lI&aWqS?^L%^T zg0TD*F7+ms=GaJ#D@ILqb@L;6#8OeVC&nm+WY_`VHT2<-D^Kf>hccOzRc~a`pojn0 zzG!M^7iUD4(S7I8_OV4*O}ERr(v-pNv+i1AcDjhq%k$HU&kYsva?8U0;pQ)O7DMm7 zg3pSqs@?*m)C|O_!o@f)=$V5B`Pr$dx@9{mekZfu2~*3_ z%#NEN4yAPNy)9^qo}S+OEmT)x^WlPc{70S7o@Dal2+p&-q(tONhj?K_8PC6mI(Fg; ziPLp;FD~arh?cgs?}j*RFYHUB_ZG&Ow+?$w3%y=8r}-d3qv7_kud^Hc5SCVJ5s)&E zB6T>?sh1IadrM+sa62}Tur`W7uNszPUnrNZY+{~FkZ)NEN#>O@KdjyDp;)A>`#x=xh zBlQ;*)te+I`B;1%92`Cn4+L>fe_5HEv;Fy0158J;vF-w;p&HR*7k^A4onKfO$>irU zF_vs-NR*g@#%GTfvkUnbRjsFuUOY0aXMlfvDC!cT`YHdhW}KEy>&q@yd<8yn1RExA zyUNo@)9&DIKKFkgm(V`MGW_?0$UX%rDIO^ygWFf5nee6J*3wdps?*=FPE}_Sk3l2t zqr)>q1_j<*k9bi0yT862rtemHae0y_b&T{LAZs}mJ0&8haRZLp)xnxM-F(|A8gR8t zuHs#^{wn9qga&DSJd@IEL?!M$%F(xGl?FM+eFETjfWQDyqU9Ss7Aq3o5Xd4B+XwCc zs~VqIwYIza$8jU{;^iLrA}_1ho3s8K!M^l$a=qLl+r-d7dF|%a-$%y8WbmDkJ>m|9 zNUzKO5xi0q_;zYqH>G2*fHK2$Z;1_KfBZ5Go?uFbX}~qzv5uWpR321s_UpRwo5}e} zpKz`4ZNKZHAXD(!lD@!iZ-avi3oTBS+{fRTLP?zw#ki;pUgL_QBI%E4Zc2B3y)mz< z3qNIfK6Zci%Yw2O&bInIB&fOmH22n{BzD4e@rm`z;t|b>xtQw4Kg7K3X@@mkc)#dl z;ZqniyPvJ*Nkm6G#S%58@7LwZ7=u?6vgD>4%t2u%uUi=ySJ3z{)LLZ#B zbMT+3r`9zp3hOTf$GEyE%u-$bmo{LD_w@ACXff#& zw^l%8kC}PMb)pB1dmhtgwpuUX8W~4D!eYOe%IlI22H@QfLth5&Ph27QG_k0V4*@Hr zZ9Y9w7~}GkI7&&WY>OA2yCZr-rHN7xB~a= zg@oAIZ&GL5u6^HNGBGh|7q>;$SRLsI3X7ysaDXczlS0CkWE5l-1N*EZY~$HOnIz0&Lf&SkY+6&g(1uSt}M;13QQCQt(-G5?Qg@ z_Q;_p5@Z4jofu1%fD*N$L3pbe&VrLgp9m=8J;sK){z-FWOl$y!DK_1guhBtb(46+& zd~9n_<=l4ypAV$??O-JOSMRvb?z?(uf;GZ$sCql$siaX2p^evm#UG4e?`A$wQ@;^W++}@ZUUY`oNoEt3lmg3PnJW{RIuQ56mO=(MDEK!;Ob+Br zT}#;2GIdriG~_22$kZAoYcH3L+-)KERZy_Fa!tm(u>(*7(OOar{J*rt{O@Uy`9Irv fB&c85+X3$}Uc>width = scrprops->width; + state->height = scrprops->height; + setup_screensaver_default(state); + NAME(setup_screensaver)(state); + screensaver_init(state); + screensaver_init_shaders(state); + + return ADDON_STATUS_OK; +} + +void Start() +{ +} + +void Render() +{ + screensaver_update(state); + screensaver_render(state); +} + +void ADDON_Stop() +{ + screensaver_deinit_shaders(state); +} + +void ADDON_Destroy() +{ +} + +ADDON_STATUS ADDON_GetStatus() +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +bool ADDON_HasSettings() +{ +puts(__func__); + return false; +} + +unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet) +{ +puts(__func__); + return 0; +} + +ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue) +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +void ADDON_FreeSettings() +{ +puts(__func__); +} + +void ADDON_Announce(const char *flag, const char *sender, const char *message, const void *data) +{ +puts(__func__); +} + +void GetInfo(SCR_INFO *info) +{ +puts(__func__); +} + +void Remove() +{ +puts(__func__); +} + +} + diff --git a/xbmc/screensavers/gles/noise/Makefile.in b/xbmc/screensavers/gles/noise/Makefile.in new file mode 100644 index 0000000..ef3287c --- /dev/null +++ b/xbmc/screensavers/gles/noise/Makefile.in @@ -0,0 +1,36 @@ +ARCH=@ARCH@ +CXXFLAGS=-fPIC +ifeq (@USE_ANDROID@,1) +SLIB = @abs_top_srcdir@/system/libnoise.so +else +SLIB = @abs_top_srcdir@/addons/screensaver.gles.noise/Noise.xbs +endif +OBJS = wrapper.o +DEFINES += -DSCREENSAVER=noise + +ifeq (@USE_OPENGLES@,1) + DEFINES += -DHAS_GLES=2 + INCLUDES+= -I@abs_top_srcdir@/xbmc/screensavers/gles + OBJS += @abs_top_srcdir@/xbmc/screensavers/gles/gleshelpers.a + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGLES + else + LDFLAGS += -lGLESv2 + endif +else + DEFINES += -DHAS_GL + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGL + else + LDFLAGS += -lGL + endif +endif + +$(SLIB): $(OBJS) +ifeq ($(findstring osx,$(ARCH)), osx) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -bundle -o $(SLIB) $(OBJS) +else + $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $(SLIB) $(OBJS) +endif + +include @abs_top_srcdir@/Makefile.include diff --git a/xbmc/screensavers/gles/noise/wrapper.cc b/xbmc/screensavers/gles/noise/wrapper.cc new file mode 100644 index 0000000..fd58b73 --- /dev/null +++ b/xbmc/screensavers/gles/noise/wrapper.cc @@ -0,0 +1,102 @@ +#include +#include +#include "Application.h" +#include "../../addons/include/xbmc_scr_dll.h" + +extern "C" { + +#include "triangle2.h" + +#define PASTER(x,y) x ## _ ## y +#define EVALUATOR(x,y) PASTER(x,y) +#define NAME(fun) EVALUATOR(fun, SCREENSAVER) + +static CUBE_STATE_T _state, *state=&_state; + +ADDON_STATUS ADDON_Create(void* hdl, void* props) +{ + if (!props) + return ADDON_STATUS_UNKNOWN; + + // Clear application state + memset( state, 0, sizeof( *state ) ); + // Start OGLES + assert( g_application.IsCurrentThread() ); + glGetError(); + + SCR_PROPS* scrprops = (SCR_PROPS*)props; + state->width = scrprops->width; + state->height = scrprops->height; + setup_screensaver_default(state); + NAME(setup_screensaver)(state); + screensaver_init(state); + screensaver_init_shaders(state); + + return ADDON_STATUS_OK; +} + +void Start() +{ +} + +void Render() +{ + screensaver_update(state); + screensaver_render(state); +} + +void ADDON_Stop() +{ + screensaver_deinit_shaders(state); +} + +void ADDON_Destroy() +{ +} + +ADDON_STATUS ADDON_GetStatus() +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +bool ADDON_HasSettings() +{ +puts(__func__); + return false; +} + +unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet) +{ +puts(__func__); + return 0; +} + +ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue) +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +void ADDON_FreeSettings() +{ +puts(__func__); +} + +void ADDON_Announce(const char *flag, const char *sender, const char *message, const void *data) +{ +puts(__func__); +} + +void GetInfo(SCR_INFO *info) +{ +puts(__func__); +} + +void Remove() +{ +puts(__func__); +} + +} + diff --git a/xbmc/screensavers/gles/plasma/Makefile.in b/xbmc/screensavers/gles/plasma/Makefile.in new file mode 100644 index 0000000..a69c159 --- /dev/null +++ b/xbmc/screensavers/gles/plasma/Makefile.in @@ -0,0 +1,36 @@ +ARCH=@ARCH@ +CXXFLAGS=-fPIC +ifeq (@USE_ANDROID@,1) +SLIB = @abs_top_srcdir@/system/libplasma.so +else +SLIB = @abs_top_srcdir@/addons/screensaver.gles.plasma/Plasma.xbs +endif +OBJS = wrapper.o +DEFINES += -DSCREENSAVER=plasma + +ifeq (@USE_OPENGLES@,1) + DEFINES += -DHAS_GLES=2 + INCLUDES+= -I@abs_top_srcdir@/xbmc/screensavers/gles + OBJS += @abs_top_srcdir@/xbmc/screensavers/gles/gleshelpers.a + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGLES + else + LDFLAGS += -lGLESv2 + endif +else + DEFINES += -DHAS_GL + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGL + else + LDFLAGS += -lGL + endif +endif + +$(SLIB): $(OBJS) +ifeq ($(findstring osx,$(ARCH)), osx) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -bundle -o $(SLIB) $(OBJS) +else + $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $(SLIB) $(OBJS) +endif + +include @abs_top_srcdir@/Makefile.include diff --git a/xbmc/screensavers/gles/plasma/wrapper.cc b/xbmc/screensavers/gles/plasma/wrapper.cc new file mode 100644 index 0000000..fd58b73 --- /dev/null +++ b/xbmc/screensavers/gles/plasma/wrapper.cc @@ -0,0 +1,102 @@ +#include +#include +#include "Application.h" +#include "../../addons/include/xbmc_scr_dll.h" + +extern "C" { + +#include "triangle2.h" + +#define PASTER(x,y) x ## _ ## y +#define EVALUATOR(x,y) PASTER(x,y) +#define NAME(fun) EVALUATOR(fun, SCREENSAVER) + +static CUBE_STATE_T _state, *state=&_state; + +ADDON_STATUS ADDON_Create(void* hdl, void* props) +{ + if (!props) + return ADDON_STATUS_UNKNOWN; + + // Clear application state + memset( state, 0, sizeof( *state ) ); + // Start OGLES + assert( g_application.IsCurrentThread() ); + glGetError(); + + SCR_PROPS* scrprops = (SCR_PROPS*)props; + state->width = scrprops->width; + state->height = scrprops->height; + setup_screensaver_default(state); + NAME(setup_screensaver)(state); + screensaver_init(state); + screensaver_init_shaders(state); + + return ADDON_STATUS_OK; +} + +void Start() +{ +} + +void Render() +{ + screensaver_update(state); + screensaver_render(state); +} + +void ADDON_Stop() +{ + screensaver_deinit_shaders(state); +} + +void ADDON_Destroy() +{ +} + +ADDON_STATUS ADDON_GetStatus() +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +bool ADDON_HasSettings() +{ +puts(__func__); + return false; +} + +unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet) +{ +puts(__func__); + return 0; +} + +ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue) +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +void ADDON_FreeSettings() +{ +puts(__func__); +} + +void ADDON_Announce(const char *flag, const char *sender, const char *message, const void *data) +{ +puts(__func__); +} + +void GetInfo(SCR_INFO *info) +{ +puts(__func__); +} + +void Remove() +{ +puts(__func__); +} + +} + diff --git a/xbmc/screensavers/gles/plasma2/Makefile.in b/xbmc/screensavers/gles/plasma2/Makefile.in new file mode 100644 index 0000000..264e576 --- /dev/null +++ b/xbmc/screensavers/gles/plasma2/Makefile.in @@ -0,0 +1,36 @@ +ARCH=@ARCH@ +CXXFLAGS=-fPIC +ifeq (@USE_ANDROID@,1) +SLIB = @abs_top_srcdir@/system/libplasma2.so +else +SLIB = @abs_top_srcdir@/addons/screensaver.gles.plasma2/Plasma2.xbs +endif +OBJS = wrapper.o +DEFINES += -DSCREENSAVER=plasma2 + +ifeq (@USE_OPENGLES@,1) + DEFINES += -DHAS_GLES=2 + INCLUDES+= -I@abs_top_srcdir@/xbmc/screensavers/gles + OBJS += @abs_top_srcdir@/xbmc/screensavers/gles/gleshelpers.a + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGLES + else + LDFLAGS += -lGLESv2 + endif +else + DEFINES += -DHAS_GL + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGL + else + LDFLAGS += -lGL + endif +endif + +$(SLIB): $(OBJS) +ifeq ($(findstring osx,$(ARCH)), osx) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -bundle -o $(SLIB) $(OBJS) +else + $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $(SLIB) $(OBJS) +endif + +include @abs_top_srcdir@/Makefile.include diff --git a/xbmc/screensavers/gles/plasma2/wrapper.cc b/xbmc/screensavers/gles/plasma2/wrapper.cc new file mode 100644 index 0000000..fd58b73 --- /dev/null +++ b/xbmc/screensavers/gles/plasma2/wrapper.cc @@ -0,0 +1,102 @@ +#include +#include +#include "Application.h" +#include "../../addons/include/xbmc_scr_dll.h" + +extern "C" { + +#include "triangle2.h" + +#define PASTER(x,y) x ## _ ## y +#define EVALUATOR(x,y) PASTER(x,y) +#define NAME(fun) EVALUATOR(fun, SCREENSAVER) + +static CUBE_STATE_T _state, *state=&_state; + +ADDON_STATUS ADDON_Create(void* hdl, void* props) +{ + if (!props) + return ADDON_STATUS_UNKNOWN; + + // Clear application state + memset( state, 0, sizeof( *state ) ); + // Start OGLES + assert( g_application.IsCurrentThread() ); + glGetError(); + + SCR_PROPS* scrprops = (SCR_PROPS*)props; + state->width = scrprops->width; + state->height = scrprops->height; + setup_screensaver_default(state); + NAME(setup_screensaver)(state); + screensaver_init(state); + screensaver_init_shaders(state); + + return ADDON_STATUS_OK; +} + +void Start() +{ +} + +void Render() +{ + screensaver_update(state); + screensaver_render(state); +} + +void ADDON_Stop() +{ + screensaver_deinit_shaders(state); +} + +void ADDON_Destroy() +{ +} + +ADDON_STATUS ADDON_GetStatus() +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +bool ADDON_HasSettings() +{ +puts(__func__); + return false; +} + +unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet) +{ +puts(__func__); + return 0; +} + +ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue) +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +void ADDON_FreeSettings() +{ +puts(__func__); +} + +void ADDON_Announce(const char *flag, const char *sender, const char *message, const void *data) +{ +puts(__func__); +} + +void GetInfo(SCR_INFO *info) +{ +puts(__func__); +} + +void Remove() +{ +puts(__func__); +} + +} + diff --git a/xbmc/screensavers/gles/solarwinds/Makefile.in b/xbmc/screensavers/gles/solarwinds/Makefile.in new file mode 100644 index 0000000..8d4e845 --- /dev/null +++ b/xbmc/screensavers/gles/solarwinds/Makefile.in @@ -0,0 +1,36 @@ +ARCH=@ARCH@ +CXXFLAGS=-fPIC +ifeq (@USE_ANDROID@,1) +SLIB = @abs_top_srcdir@/system/libsolarwinds.so +else +SLIB = @abs_top_srcdir@/addons/screensaver.gles.solarwinds/Solarwinds.xbs +endif +OBJS = wrapper.o solarwinds.o +DEFINES += -DSCREENSAVER=solarwinds + +ifeq (@USE_OPENGLES@,1) + DEFINES += -DHAS_GLES=2 + INCLUDES+= -I@abs_top_srcdir@/xbmc/screensavers/gles + OBJS += @abs_top_srcdir@/xbmc/screensavers/gles/gleshelpers.a + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGLES + else + LDFLAGS += -lGLESv2 + endif +else + DEFINES += -DHAS_GL + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGL + else + LDFLAGS += -lGL + endif +endif + +$(SLIB): $(OBJS) +ifeq ($(findstring osx,$(ARCH)), osx) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -bundle -o $(SLIB) $(OBJS) +else + $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $(SLIB) $(OBJS) +endif + +include @abs_top_srcdir@/Makefile.include diff --git a/xbmc/screensavers/gles/solarwinds/solarwinds.c b/xbmc/screensavers/gles/solarwinds/solarwinds.c new file mode 100644 index 0000000..da5bf21 --- /dev/null +++ b/xbmc/screensavers/gles/solarwinds/solarwinds.c @@ -0,0 +1,531 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// OpenGL|ES 2 demo using shader to compute particle/render sets +// Thanks to Peter de Rivas for original Python code + +#include +#include +#include +#include +#include +#include +#include + +#include "bcm_host.h" + +#include "solarwinds.h" + +#define PARTICLE_WIDTH 16 +#define PARTICLE_HEIGHT 16 + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)<(b)?(b):(a)) + +#define check() assert(glGetError() == 0) + +static void showlog(GLint shader) +{ + // Prints the compile log for a shader + char log[1024]; + glGetShaderInfoLog(shader,sizeof log,NULL,log); + printf("%d:shader:\n%s\n", shader, log); +} + +static void showprogramlog(GLint shader) +{ + // Prints the information log for a program object + char log[1024]; + glGetProgramInfoLog(shader,sizeof log,NULL,log); + printf("%d:program:\n%s\n", shader, log); +} + +static void *create_particle_tex(int width, int height) +{ + int i, j; + unsigned char *q = malloc(width * height * 4); + if (!q) + return NULL; + unsigned char *p = q; + for (j=0; jmvshader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(state->mvshader, 1, &particle_vshader_source, 0); + glCompileShader(state->mvshader); + check(); + + if (state->verbose) + showlog(state->mvshader); + + state->mshader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(state->mshader, 1, &particle_fshader_source, 0); + glCompileShader(state->mshader); + check(); + + if (state->verbose) + showlog(state->mshader); + + // particle + state->program_particle = glCreateProgram(); + glAttachShader(state->program_particle, state->mvshader); + glAttachShader(state->program_particle, state->mshader); + glLinkProgram(state->program_particle); + glDetachShader(state->program_particle, state->mvshader); + glDetachShader(state->program_particle, state->mshader); + glDeleteShader(state->mvshader); + glDeleteShader(state->mshader); + check(); + + if (state->verbose) + showprogramlog(state->program_particle); + + state->aPos = glGetAttribLocation(state->program_particle, "aPos"); + state->uProjectionMatrix = glGetUniformLocation(state->program_particle, "uProjectionMatrix"); + state->aShade = glGetAttribLocation(state->program_particle, "aShade"); + state->uTexture = glGetUniformLocation(state->program_particle, "uTexture"); + check(); + + glGenBuffers(1, &state->particleBuffer); + + check(); + + // Prepare a texture image + glGenTextures(1, &state->tex_particle); + check(); + glBindTexture(GL_TEXTURE_2D, state->tex_particle); + check(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + state->tex_particle_data = create_particle_tex(PARTICLE_WIDTH, PARTICLE_HEIGHT); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PARTICLE_WIDTH, PARTICLE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, state->tex_particle_data); + check(); + + // Upload vertex data to a buffer + glBindBuffer(GL_ARRAY_BUFFER, state->particleBuffer); + + // Create Vertex Buffer Object (VBO) + glBufferData( // Fill bound buffer with particles + GL_ARRAY_BUFFER, // Buffer target + sizeof(state->particles), // Buffer data size + state->particles, // Buffer data pointer + GL_DYNAMIC_DRAW); // Usage - Data never changes; used for drawing + check(); +} + +void solarwinds_deinit_shaders(CUBE_STATE_T *state) +{ + glDeleteProgram(state->program_particle); + check(); + + glDeleteBuffers(1, &state->particleBuffer); + check(); + + glDeleteTextures(1, &state->tex_particle); + check(); + + free(state->tex_particle_data); +} + +static void draw_particle_to_texture(CUBE_STATE_T *state) +{ + glClearColor ( 0.0, 0.0, 0.0, 1.0 ); + glClear(GL_COLOR_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, state->tex_particle); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glBindBuffer(GL_ARRAY_BUFFER, state->particleBuffer); + + int remaining = state->numParticles - state->whichParticle; + // Create Vertex Buffer Object (VBO) + glBufferSubData( // Fill bound buffer with particles + GL_ARRAY_BUFFER, // Buffer target + 0, + remaining * sizeof(state->particles[0]), // Buffer data size + state->particles + state->whichParticle // Buffer data pointer + ); // Usage - Data never changes; used for drawing + check(); + // Create Vertex Buffer Object (VBO) + glBufferSubData( // Fill bound buffer with particles + GL_ARRAY_BUFFER, // Buffer target + remaining * sizeof(state->particles[0]), + state->whichParticle * sizeof(state->particles[0]), // Buffer data size + state->particles // Buffer data pointer + ); // Usage - Data never changes; used for drawing + check(); + + glUseProgram ( state->program_particle ); + check(); + // uniforms + const GLfloat projectionMatrix[] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + glUniformMatrix4fv(state->uProjectionMatrix, 1, 0, projectionMatrix); + glUniform1i(state->uTexture, 0); // first currently bound texture "GL_TEXTURE0" + check(); + + // Attributes + glEnableVertexAttribArray(state->aPos); + glVertexAttribPointer(state->aPos, // Set pointer + 4, // One component per particle + GL_FLOAT, // Data is floating point type + GL_FALSE, // No fixed point scaling + sizeof(Particle), // No gaps in data + (void*)(offsetof(Particle, pos))); // Start from "theta" offset within bound buffer + + glEnableVertexAttribArray(state->aShade); + glVertexAttribPointer(state->aShade, // Set pointer + 4, // Three components per particle + GL_FLOAT, // Data is floating point type + GL_FALSE, // No fixed point scaling + sizeof(Particle), // No gaps in data + (void*)(offsetof(Particle, shade))); // Start from "shade" offset within bound buffer + + // Draw particles + glDrawArrays(GL_POINTS, 0, state->numParticles); + + glDisable(GL_BLEND); + glBindTexture(GL_TEXTURE_2D, 0); + + glDisableVertexAttribArray(state->aPos); + glDisableVertexAttribArray(state->aShade); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + check(); +} + +//============================================================================== + +static float randrange(float min, float max) +{ + return min + rand() * ((max-min) / RAND_MAX); +} + +void solarwinds_init(CUBE_STATE_T *state) +{ + int i; + state->numWinds = 1; + state->numEmitters = min(30, NUMEMITTERS); + state->numParticles = min(2000, NUM_PARTICLES); + state->size = 50.0f; + state->windSpeed = 20.0f; + state->emitterSpeed = 15.0f; + state->particleSpeed = 10.0f; + state->blur = 40.0f; + state->eVel = state->emitterSpeed * 0.01f; + + for (i = 0; i < NUMCONSTS; ++i) { + state->_ct[i] = randrange(0.0f, M_PI * 2.0f); + state->_cv[i] = randrange(0.0f, 0.00005f * state->windSpeed * state->windSpeed) + + 0.00001f * state->windSpeed * state->windSpeed; + } + for (i=0; iemitter[i].x = randrange(0.0f, 60.0f) - 30.0f; + state->emitter[i].y = randrange(0.0f, 60.0f) - 30.0f, + state->emitter[i].z = randrange(0.0f, 30.0f) - 15.0f; + } +} + +void solarwinds_update(CUBE_STATE_T *state) +{ + int i; + // update constants + for (i = 0; i < NUMCONSTS; ++i) { + state->_ct[i] += state->_cv[i]; + if (state->_ct[i] > M_PI * 2.0f) + state->_ct[i] -= M_PI * 2.0f; + state->_c[i] = cosf(state->_ct[i]); + } + + // calculate emissions + for (i = 0; i < state->numEmitters; ++i) { + // emitter moves toward viewer + state->emitter[i].z += state->eVel; + if (state->emitter[i].z > 15.0f) { // reset emitter + state->emitter[i].x = randrange(0.0f, 60.0f) - 30.0f; + state->emitter[i].y = randrange(0.0f, 60.0f) - 30.0f, + state->emitter[i].z = -15.0f; + } + Particle *p = state->particles + state->whichParticle; + p->pos[0] = state->emitter[i].x; + p->pos[1] = state->emitter[i].y; + p->pos[2] = state->emitter[i].z; + p->pos[3] = 1.0; + p->shade[3] = 1.0f; + + ++state->whichParticle; + if (state->whichParticle >= state->numParticles) + state->whichParticle = 0; + } + + // calculate particle positions and colors + // first modify constants that affect colors + state->_c[6] *= 9.0f / state->particleSpeed; + state->_c[7] *= 9.0f / state->particleSpeed; + state->_c[8] *= 9.0f / state->particleSpeed; + // then update each particle + float pVel = state->particleSpeed * 0.01f; + for (i = 0; i < state->numParticles; ++i) { + Particle *p = state->particles + i; + // store old positions + float x = p->pos[0]; + float y = p->pos[1]; + float z = p->pos[2]; + // make new positions + p->pos[0] = x + (state->_c[0] * y + state->_c[1] * z) * pVel; + p->pos[1] = y + (state->_c[2] * z + state->_c[3] * x) * pVel; + p->pos[2] = z + (state->_c[4] * x + state->_c[5] * y) * pVel; + // calculate colors + p->shade[0] = abs((p->pos[0] - x) * state->_c[6]); + p->shade[1] = abs((p->pos[1] - y) * state->_c[7]); + p->shade[2] = abs((p->pos[2] - z) * state->_c[8]); + } +} + +void solarwinds_render(CUBE_STATE_T *state) +{ + draw_particle_to_texture(state); +} + +#ifdef STANDALONE + +typedef struct +{ + uint32_t screen_width; + uint32_t screen_height; +// OpenGL|ES objects + EGLDisplay display; + EGLSurface surface; + EGLContext context; +} EGL_STATE_T; + +uint64_t GetTimeStamp() { + struct timeval tv; + gettimeofday(&tv,NULL); + return tv.tv_sec*(uint64_t)1000000+tv.tv_usec; +} + +/*********************************************************** + * Name: init_ogl + * + * Arguments: + * CUBE_STATE_T *state - holds OGLES model info + * + * Description: Sets the display, OpenGL|ES context and screen stuff + * + * Returns: void + * + ***********************************************************/ +static void init_ogl(EGL_STATE_T *state) +{ + int32_t success = 0; + EGLBoolean result; + EGLint num_config; + + static EGL_DISPMANX_WINDOW_T nativewindow; + + DISPMANX_ELEMENT_HANDLE_T dispman_element; + DISPMANX_DISPLAY_HANDLE_T dispman_display; + DISPMANX_UPDATE_HANDLE_T dispman_update; + VC_RECT_T dst_rect; + VC_RECT_T src_rect; + + static const EGLint attribute_list[] = + { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE + }; + + static const EGLint context_attributes[] = + { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + EGLConfig config; + + // get an EGL display connection + state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + assert(state->display!=EGL_NO_DISPLAY); + check(); + + // initialize the EGL display connection + result = eglInitialize(state->display, NULL, NULL); + assert(EGL_FALSE != result); + check(); + + // get an appropriate EGL frame buffer configuration + result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config); + assert(EGL_FALSE != result); + check(); + + // get an appropriate EGL frame buffer configuration + result = eglBindAPI(EGL_OPENGL_ES_API); + assert(EGL_FALSE != result); + check(); + + // create an EGL rendering context + state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes); + assert(state->context!=EGL_NO_CONTEXT); + check(); + + // create an EGL window surface + success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height); + assert( success >= 0 ); + + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = state->screen_width; + dst_rect.height = state->screen_height; + + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = state->screen_width << 16; + src_rect.height = state->screen_height << 16; + + dispman_display = vc_dispmanx_display_open( 0 /* LCD */); + dispman_update = vc_dispmanx_update_start( 0 ); + + dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display, + 0/*layer*/, &dst_rect, 0/*src*/, + &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/); + + nativewindow.element = dispman_element; + nativewindow.width = state->screen_width; + nativewindow.height = state->screen_height; + vc_dispmanx_update_submit_sync( dispman_update ); + + check(); + + state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL ); + assert(state->surface != EGL_NO_SURFACE); + check(); + + // connect the context to the surface + result = eglMakeCurrent(state->display, state->surface, state->surface, state->context); + assert(EGL_FALSE != result); + check(); +} + +int main () +{ + int terminate = 0; + CUBE_STATE_T _state, *state=&_state; + EGL_STATE_T _eglstate, *eglstate=&_eglstate; + + // Clear application state + memset( state, 0, sizeof( *state ) ); + memset( eglstate, 0, sizeof( *eglstate ) ); + state->verbose = 1; + bcm_host_init(); + // Start OGLES + init_ogl(eglstate); +again: + solarwinds_init(state); + solarwinds_init_shaders(state); + + int frames = 0; + uint64_t ts = GetTimeStamp(); + while (!terminate) + { + solarwinds_update(state); + solarwinds_render(state); + //glFlush(); + //glFinish(); + check(); + + eglSwapBuffers(eglstate->display, eglstate->surface); + check(); + + frames++; + uint64_t ts2 = GetTimeStamp(); + if (ts2 - ts > 1e6) + { + printf("%d fps\n", frames); + ts += 1e6; + frames = 0; + } + } + solarwinds_deinit_shaders(state); + goto again; + return 0; +} +#endif + diff --git a/xbmc/screensavers/gles/solarwinds/solarwinds.h b/xbmc/screensavers/gles/solarwinds/solarwinds.h new file mode 100644 index 0000000..1e9a761 --- /dev/null +++ b/xbmc/screensavers/gles/solarwinds/solarwinds.h @@ -0,0 +1,60 @@ +#pragma once + +#include "GLES2/gl2.h" +#include "EGL/egl.h" +#include "EGL/eglext.h" + +#define NUM_PARTICLES 2000 +#define NUMCONSTS 9 +#define NUMEMITTERS 30 + +typedef struct Particle +{ + GLfloat pos[4]; + GLfloat shade[4]; +} Particle; + +typedef struct Emitter +{ + GLfloat x, y, z; +} Emitter; + +typedef struct +{ + GLuint verbose; + GLuint mvshader; + GLuint mshader; + GLuint program_particle; + GLuint tex_particle; + GLuint particleBuffer; +// particle attribs + GLuint aPos, aShade, uProjectionMatrix, uTexture; + + Emitter emitter[NUMEMITTERS]; + Particle particles[NUM_PARTICLES]; + void *tex_particle_data; + + float _c[NUMCONSTS]; + float _ct[NUMCONSTS]; + float _cv[NUMCONSTS]; + + unsigned int numWinds; + unsigned int numEmitters; + unsigned int numParticles; + unsigned int whichParticle; + float size; + float windSpeed; + float emitterSpeed; + float particleSpeed; + float blur; + float eVel; +} CUBE_STATE_T; + + +void solarwinds_init_shaders(CUBE_STATE_T *state); +void solarwinds_init(CUBE_STATE_T *state); +void solarwinds_update(CUBE_STATE_T *state); +void solarwinds_render(CUBE_STATE_T *state); +void solarwinds_deinit_shaders(CUBE_STATE_T *state); + + diff --git a/xbmc/screensavers/gles/solarwinds/wrapper.cc b/xbmc/screensavers/gles/solarwinds/wrapper.cc new file mode 100644 index 0000000..edad7c7 --- /dev/null +++ b/xbmc/screensavers/gles/solarwinds/wrapper.cc @@ -0,0 +1,96 @@ +#include +#include +#include "Application.h" +#include "../../addons/include/xbmc_scr_dll.h" + +extern "C" { + +#include "solarwinds.h" + +static CUBE_STATE_T _state, *state=&_state; + +ADDON_STATUS ADDON_Create(void* hdl, void* props) +{ + if (!props) + return ADDON_STATUS_UNKNOWN; + + // Clear application state + memset( state, 0, sizeof( *state ) ); + // Start OGLES + assert( g_application.IsCurrentThread() ); + glGetError(); + + SCR_PROPS* scrprops = (SCR_PROPS*)props; + //state->width = scrprops->width; + //state->height = scrprops->height; + solarwinds_init(state); + solarwinds_init_shaders(state); + + return ADDON_STATUS_OK; +} + +void Start() +{ +} + +void Render() +{ + solarwinds_update(state); + solarwinds_render(state); +} + +void ADDON_Stop() +{ + solarwinds_deinit_shaders(state); +} + +void ADDON_Destroy() +{ +} + +ADDON_STATUS ADDON_GetStatus() +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +bool ADDON_HasSettings() +{ +puts(__func__); + return false; +} + +unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet) +{ +puts(__func__); + return 0; +} + +ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue) +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +void ADDON_FreeSettings() +{ +puts(__func__); +} + +void ADDON_Announce(const char *flag, const char *sender, const char *message, const void *data) +{ +puts(__func__); +} + +void GetInfo(SCR_INFO *info) +{ +puts(__func__); +} + +void Remove() +{ +puts(__func__); +} + +} + diff --git a/xbmc/screensavers/gles/spiral/Makefile.in b/xbmc/screensavers/gles/spiral/Makefile.in new file mode 100644 index 0000000..5f57c7d --- /dev/null +++ b/xbmc/screensavers/gles/spiral/Makefile.in @@ -0,0 +1,36 @@ +ARCH=@ARCH@ +CXXFLAGS=-fPIC +ifeq (@USE_ANDROID@,1) +SLIB = @abs_top_srcdir@/system/libspiral.so +else +SLIB = @abs_top_srcdir@/addons/screensaver.gles.spiral/Spiral.xbs +endif +OBJS = wrapper.o +DEFINES += -DSCREENSAVER=spiral + +ifeq (@USE_OPENGLES@,1) + DEFINES += -DHAS_GLES=2 + INCLUDES+= -I@abs_top_srcdir@/xbmc/screensavers/gles + OBJS += @abs_top_srcdir@/xbmc/screensavers/gles/gleshelpers.a + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGLES + else + LDFLAGS += -lGLESv2 + endif +else + DEFINES += -DHAS_GL + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGL + else + LDFLAGS += -lGL + endif +endif + +$(SLIB): $(OBJS) +ifeq ($(findstring osx,$(ARCH)), osx) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -bundle -o $(SLIB) $(OBJS) +else + $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $(SLIB) $(OBJS) +endif + +include @abs_top_srcdir@/Makefile.include diff --git a/xbmc/screensavers/gles/spiral/wrapper.cc b/xbmc/screensavers/gles/spiral/wrapper.cc new file mode 100644 index 0000000..fd58b73 --- /dev/null +++ b/xbmc/screensavers/gles/spiral/wrapper.cc @@ -0,0 +1,102 @@ +#include +#include +#include "Application.h" +#include "../../addons/include/xbmc_scr_dll.h" + +extern "C" { + +#include "triangle2.h" + +#define PASTER(x,y) x ## _ ## y +#define EVALUATOR(x,y) PASTER(x,y) +#define NAME(fun) EVALUATOR(fun, SCREENSAVER) + +static CUBE_STATE_T _state, *state=&_state; + +ADDON_STATUS ADDON_Create(void* hdl, void* props) +{ + if (!props) + return ADDON_STATUS_UNKNOWN; + + // Clear application state + memset( state, 0, sizeof( *state ) ); + // Start OGLES + assert( g_application.IsCurrentThread() ); + glGetError(); + + SCR_PROPS* scrprops = (SCR_PROPS*)props; + state->width = scrprops->width; + state->height = scrprops->height; + setup_screensaver_default(state); + NAME(setup_screensaver)(state); + screensaver_init(state); + screensaver_init_shaders(state); + + return ADDON_STATUS_OK; +} + +void Start() +{ +} + +void Render() +{ + screensaver_update(state); + screensaver_render(state); +} + +void ADDON_Stop() +{ + screensaver_deinit_shaders(state); +} + +void ADDON_Destroy() +{ +} + +ADDON_STATUS ADDON_GetStatus() +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +bool ADDON_HasSettings() +{ +puts(__func__); + return false; +} + +unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet) +{ +puts(__func__); + return 0; +} + +ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue) +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +void ADDON_FreeSettings() +{ +puts(__func__); +} + +void ADDON_Announce(const char *flag, const char *sender, const char *message, const void *data) +{ +puts(__func__); +} + +void GetInfo(SCR_INFO *info) +{ +puts(__func__); +} + +void Remove() +{ +puts(__func__); +} + +} + diff --git a/xbmc/screensavers/gles/stellar/Makefile.in b/xbmc/screensavers/gles/stellar/Makefile.in new file mode 100644 index 0000000..ef8f5b1 --- /dev/null +++ b/xbmc/screensavers/gles/stellar/Makefile.in @@ -0,0 +1,36 @@ +ARCH=@ARCH@ +CXXFLAGS=-fPIC +ifeq (@USE_ANDROID@,1) +SLIB = @abs_top_srcdir@/system/libstellar.so +else +SLIB = @abs_top_srcdir@/addons/screensaver.gles.stellar/Stellar.xbs +endif +OBJS = wrapper.o +DEFINES += -DSCREENSAVER=stellar + +ifeq (@USE_OPENGLES@,1) + DEFINES += -DHAS_GLES=2 + INCLUDES+= -I@abs_top_srcdir@/xbmc/screensavers/gles + OBJS += @abs_top_srcdir@/xbmc/screensavers/gles/gleshelpers.a + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGLES + else + LDFLAGS += -lGLESv2 + endif +else + DEFINES += -DHAS_GL + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGL + else + LDFLAGS += -lGL + endif +endif + +$(SLIB): $(OBJS) +ifeq ($(findstring osx,$(ARCH)), osx) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -bundle -o $(SLIB) $(OBJS) +else + $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $(SLIB) $(OBJS) +endif + +include @abs_top_srcdir@/Makefile.include diff --git a/xbmc/screensavers/gles/stellar/wrapper.cc b/xbmc/screensavers/gles/stellar/wrapper.cc new file mode 100644 index 0000000..fd58b73 --- /dev/null +++ b/xbmc/screensavers/gles/stellar/wrapper.cc @@ -0,0 +1,102 @@ +#include +#include +#include "Application.h" +#include "../../addons/include/xbmc_scr_dll.h" + +extern "C" { + +#include "triangle2.h" + +#define PASTER(x,y) x ## _ ## y +#define EVALUATOR(x,y) PASTER(x,y) +#define NAME(fun) EVALUATOR(fun, SCREENSAVER) + +static CUBE_STATE_T _state, *state=&_state; + +ADDON_STATUS ADDON_Create(void* hdl, void* props) +{ + if (!props) + return ADDON_STATUS_UNKNOWN; + + // Clear application state + memset( state, 0, sizeof( *state ) ); + // Start OGLES + assert( g_application.IsCurrentThread() ); + glGetError(); + + SCR_PROPS* scrprops = (SCR_PROPS*)props; + state->width = scrprops->width; + state->height = scrprops->height; + setup_screensaver_default(state); + NAME(setup_screensaver)(state); + screensaver_init(state); + screensaver_init_shaders(state); + + return ADDON_STATUS_OK; +} + +void Start() +{ +} + +void Render() +{ + screensaver_update(state); + screensaver_render(state); +} + +void ADDON_Stop() +{ + screensaver_deinit_shaders(state); +} + +void ADDON_Destroy() +{ +} + +ADDON_STATUS ADDON_GetStatus() +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +bool ADDON_HasSettings() +{ +puts(__func__); + return false; +} + +unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet) +{ +puts(__func__); + return 0; +} + +ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue) +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +void ADDON_FreeSettings() +{ +puts(__func__); +} + +void ADDON_Announce(const char *flag, const char *sender, const char *message, const void *data) +{ +puts(__func__); +} + +void GetInfo(SCR_INFO *info) +{ +puts(__func__); +} + +void Remove() +{ +puts(__func__); +} + +} + diff --git a/xbmc/screensavers/gles/triangle2.c b/xbmc/screensavers/gles/triangle2.c new file mode 100644 index 0000000..16c918f --- /dev/null +++ b/xbmc/screensavers/gles/triangle2.c @@ -0,0 +1,990 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// OpenGL|ES 2 demo using shader to compute plasma/render sets +// Thanks to Peter de Rivas for original Python code + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bcm_host.h" + +#include "triangle2.h" + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)<(b)?(b):(a)) +#define TO_STRING(...) #__VA_ARGS__ + +#define check() assert(glGetError() == 0) + +static void showlog(GLint shader) +{ + // Prints the compile log for a shader + char log[1024]; + glGetShaderInfoLog(shader, sizeof log, NULL, log); + printf("%d:shader:\n%s\n", shader, log); +} + +static void showprogramlog(GLint shader) +{ + // Prints the information log for a program object + char log[1024]; + glGetProgramInfoLog(shader, sizeof log, NULL, log); + printf("%d:program:\n%s\n", shader, log); +} + +static void *create_particle_tex(int width, int height) +{ + int i, j; + unsigned char *q = malloc(width * height * 4); + if (!q) + return NULL; + unsigned char *p = q; + for (j=0; j> 16) & 0xff; + *p++ = (rand() >> 16) & 0xff; + *p++ = (rand() >> 16) & 0xff; + *p++ = 255; + } + } + return q; +} + +static void *create_framebuffer_tex(int width, int height) +{ +#ifdef STANDALONE + return create_border_tex(width, height); +#else + unsigned char *q = malloc(width * height * 4); + if (!q) + return NULL; + + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, q); + check(); + return q; +#endif +} + +void screensaver_init_shaders(CUBE_STATE_T *state) +{ + static const GLfloat vertex_data[] = { + -1.0,1.0,1.0,1.0, + 1.0,1.0,1.0,1.0, + 1.0,-1.0,1.0,1.0, + -1.0,-1.0,1.0,1.0, + }; + // effect + state->effect_vshader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(state->effect_vshader, 1, &state->effect_vshader_source, 0); + glCompileShader(state->effect_vshader); + check(); + + if (state->verbose) + showlog(state->effect_vshader); + + state->effect_fshader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(state->effect_fshader, 1, &state->effect_fshader_source, 0); + glCompileShader(state->effect_fshader); + check(); + + if (state->verbose) + showlog(state->effect_fshader); + + state->effect_program = glCreateProgram(); + glAttachShader(state->effect_program, state->effect_vshader); + glAttachShader(state->effect_program, state->effect_fshader); + glLinkProgram(state->effect_program); + glDetachShader(state->effect_program, state->effect_vshader); + glDetachShader(state->effect_program, state->effect_fshader); + glDeleteShader(state->effect_vshader); + glDeleteShader(state->effect_fshader); + check(); + + if (state->verbose) + showprogramlog(state->effect_program); + + state->attr_vertex = glGetAttribLocation(state->effect_program, "vertex"); + state->uResolution = glGetUniformLocation(state->effect_program, "iResolution"); + state->uMouse = glGetUniformLocation(state->effect_program, "iMouse"); + state->uTime = glGetUniformLocation(state->effect_program, "iGlobalTime"); + state->uChannel0 = glGetUniformLocation(state->effect_program, "iChannel0"); + state->uScale = glGetUniformLocation(state->effect_program, "uScale"); + check(); + + // render + state->render_vshader = glCreateShader(GL_VERTEX_SHADER); + check(); + glShaderSource(state->render_vshader, 1, &state->render_vshader_source, 0); + check(); + glCompileShader(state->render_vshader); + check(); + + if (state->verbose) + showlog(state->render_vshader); + + state->render_fshader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(state->render_fshader, 1, &state->render_fshader_source, 0); + glCompileShader(state->render_fshader); + check(); + + if (state->verbose) + showlog(state->render_fshader); + + state->render_program = glCreateProgram(); + glAttachShader(state->render_program, state->render_vshader); + glAttachShader(state->render_program, state->render_fshader); + glLinkProgram(state->render_program); + glDetachShader(state->render_program, state->render_vshader); + glDetachShader(state->render_program, state->render_fshader); + glDeleteShader(state->render_vshader); + glDeleteShader(state->render_fshader); + check(); + + if (state->verbose) + showprogramlog(state->render_program); + + state->uTexture = glGetUniformLocation(state->render_program, "uTexture"); + check(); + + if (state->fbwidth && state->fbheight) + { + // Prepare a texture to render to + glGenTextures(1, &state->framebuffer_texture); + check(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, state->framebuffer_texture); + check(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, state->fbwidth, state->fbheight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + check(); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + check(); + // Prepare a framebuffer for rendering + glGenFramebuffers(1, &state->effect_fb); + check(); + glBindFramebuffer(GL_FRAMEBUFFER, state->effect_fb); + check(); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, state->framebuffer_texture, 0); + check(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + check(); + } + // Prepare a texture image + if (state->effect_texture_data) + { + glGenTextures(1, &state->effect_texture); + check(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, state->effect_texture); + check(); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, state->texwidth, state->texheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, state->effect_texture_data); + check(); + } + // Upload vertex data to a buffer + glGenBuffers(1, &state->vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, state->vertex_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + check(); +} + +void screensaver_deinit_shaders(CUBE_STATE_T *state) +{ + glDeleteProgram(state->render_program); + glDeleteProgram(state->effect_program); + check(); + + glDeleteBuffers(1, &state->vertex_buffer); + if (state->framebuffer_texture) + { + glDeleteTextures(1, &state->framebuffer_texture); + check(); + } + if (state->effect_fb) + { + glDeleteFramebuffers(1, &state->effect_fb); + check(); + } + if (state->effect_texture) + { + glDeleteTextures(1, &state->effect_texture); + check(); + } + if (state->effect_texture_data) + free(state->effect_texture_data); +} + +static void draw_effect_to_texture(CUBE_STATE_T *state) +{ + // Draw the effect to a texture + if (state->effect_fb) + glBindFramebuffer(GL_FRAMEBUFFER, state->effect_fb); + else + glBindFramebuffer(GL_FRAMEBUFFER, 0); + check(); + + glBindBuffer(GL_ARRAY_BUFFER, state->vertex_buffer); + check(); + glUseProgram( state->effect_program ); + check(); + if (state->effect_texture) + { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, state->effect_texture); + check(); + //glEnable(GL_BLEND); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + glUniform3f(state->uResolution, state->width, state->height, 1.0f); + glUniform2f(state->uMouse, state->mousex, state->mousey); + glUniform1f(state->uTime, state->time); + glUniform1i(state->uChannel0, 0); // first currently bound texture "GL_TEXTURE0" + if (state->effect_fb) + glUniform2f(state->uScale, (GLfloat)state->width/state->fbwidth, (GLfloat)state->height/state->fbheight); + else + glUniform2f(state->uScale, 1.0, 1.0); + check(); + + glVertexAttribPointer(state->attr_vertex, 4, GL_FLOAT, 0, 16, 0); + glEnableVertexAttribArray(state->attr_vertex); + + glDrawArrays( GL_TRIANGLE_FAN, 0, 4 ); + check(); + + glDisableVertexAttribArray(state->attr_vertex); + glBindTexture(GL_TEXTURE_2D, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + check(); +} + +static void draw_triangles(CUBE_STATE_T *state) +{ + // already on framebuffer + if (!state->framebuffer_texture) + return; + // Now render to the main frame buffer + glBindFramebuffer(GL_FRAMEBUFFER, 0); + check(); + + glBindBuffer(GL_ARRAY_BUFFER, state->vertex_buffer); + check(); + glUseProgram ( state->render_program ); + check(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, state->framebuffer_texture); + check(); + glUniform1i(state->uTexture, 0); // first currently bound texture "GL_TEXTURE0" + check(); + + glVertexAttribPointer(state->attr_vertex, 4, GL_FLOAT, 0, 16, 0); + glEnableVertexAttribArray(state->attr_vertex); + check(); + + glDrawArrays( GL_TRIANGLE_FAN, 0, 4 ); + check(); + + glDisableVertexAttribArray(state->attr_vertex); + glBindTexture(GL_TEXTURE_2D, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + check(); +} + +//============================================================================== + +static float randrange(float min, float max) +{ + return min + rand() * ((max-min) / RAND_MAX); +} + +void screensaver_init(CUBE_STATE_T *state) +{ + int i; + for (i = 0; i < NUMCONSTS; ++i) { + state->_ct[i] = randrange(0.0f, M_PI * 2.0f); + state->_cv[i] = randrange(0.0f, 0.00005f) + + 0.00001f; + } +} + +uint64_t GetTimeStamp() { + struct timeval tv; + gettimeofday(&tv,NULL); + return tv.tv_sec*(uint64_t)1000000+tv.tv_usec; +} + +void screensaver_update(CUBE_STATE_T *state) +{ + int i; + // update constants + for (i = 0; i < NUMCONSTS; ++i) { + state->_ct[i] += state->_cv[i]; + if (state->_ct[i] > M_PI * 2.0f) + state->_ct[i] -= M_PI * 2.0f; + state->_c[i] = cosf(state->_ct[i]); + } + uint64_t t = GetTimeStamp(); + if (state->last_time) + state->time += (t-state->last_time) * 1e-6; + state->last_time = t; + //if (state->time > 12.0f + M_PI) + // state->time -= 12.0f * M_PI; +} + +void screensaver_render(CUBE_STATE_T *state) +{ + draw_effect_to_texture(state); + draw_triangles(state); +} + +void setup_screensaver_default(CUBE_STATE_T *state) +{ + state->effect_vshader_source = TO_STRING( + attribute vec4 vertex; + varying vec2 vTextureCoord; + uniform vec2 uScale; + void main(void) + { + gl_Position = vertex; + vTextureCoord = vertex.xy*0.5+0.5; + vTextureCoord.x = vTextureCoord.x * uScale.x; + vTextureCoord.y = vTextureCoord.y * uScale.y; + } + ); + state->effect_fshader_source = TO_STRING( + varying vec2 vTextureCoord; + uniform float iGlobalTime; + uniform vec3 iResolution; + uniform vec2 iMouse; + uniform sampler2D iChannel0; + ); + state->render_vshader_source = TO_STRING( + attribute vec4 vertex; + varying vec2 vTextureCoord; + void main(void) + { + gl_Position = vertex; + vTextureCoord = vertex.xy*0.5+0.5; + } + ); + state->render_fshader_source = TO_STRING( + varying vec2 vTextureCoord; + uniform sampler2D uTexture; + void main(void) + { + gl_FragColor = texture2D(uTexture, vTextureCoord); + //gl_FragColor = vec4(vTextureCoord.x, vTextureCoord.y, 0.0, 1.0); + } + ); +} + +void setup_screensaver_plasma(CUBE_STATE_T *state) +{ + state->fbwidth = 960; state->fbheight = 540; + state->effect_fshader_source = TO_STRING( + precision lowp float; + varying vec2 vTextureCoord; + uniform highp float iGlobalTime; + uniform vec3 iResolution; + uniform vec2 iMouse; + uniform sampler2D iChannel0; + + float u_time=iGlobalTime*0.2; + vec2 u_k = vec2(32.0, 32.0); + precision mediump float; + const float PI=3.1415926535897932384626433832795; + void main() + { + float v = 0.0; + vec2 c = vTextureCoord * u_k - u_k/2.0; + v += sin((c.x+u_time)); + v += sin((c.y+u_time)/2.0); + v += sin((c.x+c.y+u_time)/2.0); + c += u_k/2.0 * vec2(sin(u_time/3.0), cos(u_time/2.0)); + v += sin(sqrt(c.x*c.x+c.y*c.y+1.0)+u_time); + v = v/2.0; + vec3 col = vec3(1.0, sin(PI*v), cos(PI*v)); + gl_FragColor = vec4(col*0.5 + 0.5, 1.0); + } + ); +} + + +void setup_screensaver_plasma2(CUBE_STATE_T *state) +{ + state->fbwidth = 640; state->fbheight = 360; + state->effect_fshader_source = TO_STRING( + precision lowp float; + varying vec2 vTextureCoord; + uniform highp float iGlobalTime; + uniform vec3 iResolution; + uniform vec2 iMouse; + uniform sampler2D iChannel0; + + float u_time=iGlobalTime*0.2; + vec2 u_k = vec2(32.0, 32.0); + precision mediump float; + const float PI=3.1415926535897932384626433832795; + + void mainImage( out vec4 fragColor, in vec2 fragCoord ) + { + vec2 p = -1.0 + 2.0 * fragCoord.xy / iResolution.xy; + + // main code, *original shader by: 'Plasma' by Viktor Korsun (2011) + float x = p.x; + float y = p.y; + float mov0 = x+y+cos(sin(iGlobalTime)*2.0)*100.+sin(x/100.)*1000.; + float mov1 = y / 0.9 + iGlobalTime; + float mov2 = x / 0.2; + float c1 = abs(sin(mov1+iGlobalTime)/2.+mov2/2.-mov1-mov2+iGlobalTime); + float c2 = abs(sin(c1+sin(mov0/1000.+iGlobalTime)+sin(y/40.+iGlobalTime)+sin((x+y)/100.)*3.)); + float c3 = abs(sin(c2+cos(mov1+mov2+c2)+cos(mov2)+sin(x/1000.))); + fragColor = vec4(c1,c2,c3,1.0); + + } + + void main () { + vec4 fragColor; + vec2 fragCoord = vTextureCoord * vec2(iResolution.x, iResolution.y); + mainImage(fragColor, fragCoord); + gl_FragColor = fragColor; + gl_FragColor.a = 1.0; + } + ); +} + + +void setup_screensaver_border(CUBE_STATE_T *state) +{ + state->texwidth = state->texheight = 256; + state->fbwidth = state->fbheight = 256; + state->effect_texture_data = create_border_tex(state->texwidth, state->texheight); + state->effect_fshader_source = TO_STRING( + varying vec2 vTextureCoord; + uniform float iGlobalTime; + uniform vec3 iResolution; + uniform vec2 iMouse; + uniform sampler2D iChannel0; + + void main(void) + { + vec2 v = vTextureCoord; + vec4 texture = texture2D(iChannel0, v); + gl_FragColor = texture; + } + ); +} + + +void setup_screensaver_spiral(CUBE_STATE_T *state) +{ + state->fbwidth = 800; state->fbheight = 450; + state->effect_fshader_source = TO_STRING( + precision lowp float; + varying vec2 vTextureCoord; + uniform highp float iGlobalTime; + uniform vec3 iResolution; + uniform vec2 iMouse; + uniform sampler2D iChannel0; + + float u_time=iGlobalTime*0.2; + vec2 u_k = vec2(32.0, 32.0); + precision mediump float; + const float PI=3.1415926535897932384626433832795; + const float TAU=6.283185307179586; + + void mainImage( out vec4 fragColor, in vec2 fragCoord ) + { + vec2 p = 2.0*(0.5 * iResolution.xy - fragCoord.xy) / iResolution.xx; + float angle = atan(p.y, p.x); + float turn = (angle + PI) / TAU; + float radius = sqrt(p.x*p.x + p.y*p.y); + + float rotation = 0.04 * TAU * iGlobalTime; + float turn_1 = turn + rotation; + + float n_sub = 2.0; + + float turn_sub = mod(float(n_sub) * turn_1, float(n_sub)); + + float k_sine = 0.1 * sin(3.0 * iGlobalTime); + float sine = k_sine * sin(50.0 * (pow(radius, 0.1) - 0.4 * iGlobalTime)); + float turn_sine = turn_sub + sine; + + int n_colors = 5; + int i_turn = int(mod(float(n_colors) * turn_sine, float(n_colors))); + + int i_radius = int(1.5/pow(radius*0.5, 0.6) + 5.0 * iGlobalTime); + + int i_color = int(mod(float(i_turn + i_radius), float(n_colors))); + + vec3 color; + if(i_color == 0) { + color = vec3(1.0, 1.0, 1.0); + } else if(i_color == 1) { + color = vec3(0.0, 0.0, 0.0); + } else if(i_color == 2) { + color = vec3(1.0, 0.0, 0.0); + } else if(i_color == 3) { + color = vec3(1.0, 0.5, 0.0); + } else if(i_color == 4) { + color = vec3(1.0, 1.0, 0.0); + } + + color *= pow(radius, 0.5)*1.0; + + fragColor = vec4(color, 1.0); + } + + void main () { + vec4 fragColor; + vec2 fragCoord = vTextureCoord * vec2(iResolution.x, iResolution.y); + mainImage(fragColor, fragCoord); + gl_FragColor = fragColor; + gl_FragColor.a = 1.0; + } + ); +} + +void setup_screensaver_ball(CUBE_STATE_T *state) +{ + state->texwidth = state->width; + state->texheight = state->height; + state->fbwidth = 960; + state->fbheight = 540; + state->effect_texture_data = create_framebuffer_tex(state->texwidth, state->texheight); + + state->effect_fshader_source = TO_STRING( + precision lowp float; + varying vec2 vTextureCoord; + uniform highp float iGlobalTime; + uniform vec3 iResolution; + uniform vec2 iMouse; + uniform sampler2D iChannel0; + + float u_time=iGlobalTime*0.2; + vec2 u_k = vec2(32.0, 32.0); + precision mediump float; + const float PI=3.1415926535897932384626433832795; + + // by maq/floppy + const float R=0.2; // to play + void mainImage( out vec4 fragColor, in vec2 fragCoord ) + { + vec3 col; + vec2 uv = -0.5+fragCoord.xy / iResolution.xy; + uv.y*=0.66; // hack to get ar nice on 16:10 + vec2 p = uv; + float d=sqrt(dot(p,p)); + float fac,fac2; + if(dtexwidth = 256; state->texheight = 256; + state->effect_texture_data = create_noise_tex(state->texwidth, state->texheight); + state->fbwidth = 640; state->fbheight = 360; + + state->effect_fshader_source = TO_STRING( + precision lowp float; + varying vec2 vTextureCoord; + uniform highp float iGlobalTime; + uniform vec3 iResolution; + uniform vec2 iMouse; + uniform sampler2D iChannel0; + + const float tau = 6.28318530717958647692; + vec4 Noise( in ivec2 x ) + { + return texture2D( iChannel0, (vec2(x)+0.5)/256.0, -100.0 ); + } + void main() + { + vec3 ray = vec3(vTextureCoord - vec2(0.5), 1.0); + float offset = iGlobalTime*.5; + float speed2 = (cos(offset)+1.0)*2.0; + float speed = speed2+.1; + float ispeed = 1.0/speed; + offset += sin(offset)*.96; + offset *= 2.0; + vec3 col = vec3(0); + vec3 stp = ray/max(abs(ray.x),abs(ray.y)); + vec3 pos = 2.0*stp+.5; + for ( int i=0; i < 10; i++ ) + { + float z = Noise(ivec2(pos.xy)).x; + z = fract(z-offset); + float d = 50.0*z-pos.z; + float w = max(0.0, 1.0-8.0*length(fract(pos.xy)-.5)); + vec3 c = max(vec3(0), vec3(1.0-abs(d+speed2*.5)*ispeed,1.0-abs(d)*ispeed,1.0-abs(d-speed2*.5)*ispeed)); + col += 1.5*(1.0-z)*c*w*w; + pos += stp; + } + gl_FragColor = vec4(col,1.0); + } + ); +} + +void setup_screensaver_noise(CUBE_STATE_T *state) +{ + state->fbwidth = 960; state->fbheight = 540; + state->effect_fshader_source = TO_STRING( + precision lowp float; + varying vec2 vTextureCoord; + uniform highp float iGlobalTime; + uniform vec3 iResolution; + uniform vec2 iMouse; + uniform sampler2D iChannel0; + + float time=iGlobalTime*0.1; + float pi = 3.14159265; + + float rand(vec2 co) + { + return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453); + } + + void main() + { + float r = rand(vec2(1.0*iGlobalTime+vTextureCoord.x, 3.0*iGlobalTime+vTextureCoord.y)); + float g = rand(vec2(2.0*iGlobalTime+vTextureCoord.x, 2.0*iGlobalTime+vTextureCoord.y)); + float b = rand(vec2(3.0*iGlobalTime+vTextureCoord.x, 1.0*iGlobalTime+vTextureCoord.y)); + gl_FragColor = vec4(r, g, b, 1.0); + } + ); +} + +void setup_screensaver_warp(CUBE_STATE_T *state) +{ + state->texwidth = state->width; + state->texheight = state->height; + state->fbwidth = 800; + state->fbheight = 450; + state->effect_texture_data = create_framebuffer_tex(state->texwidth, state->texheight); + + state->effect_fshader_source = TO_STRING( + precision lowp float; + varying vec2 vTextureCoord; + uniform highp float iGlobalTime; + uniform vec3 iResolution; + uniform vec2 iMouse; + uniform sampler2D iChannel0; + + float time=iGlobalTime*0.1; + const float pi = 3.14159265; + const float sin_4000 = 0.6427876097; + const float cos_4000 = 0.7660444431; + const float sin_6000 = -0.8660254038; + const float cos_6000 = -0.5; + + void main() + { + float s = sin(time); + float c = cos(time); + float s2 = 2.0*s*c; + float c2 = 1.0-2.0*s*s; + float s3 = s2*c + c2*s; + float c3 = c2*c - s2*s; + float ss = s2*cos_4000 + c2*sin_4000; + float cc = c3*cos_6000 - s3*sin_6000; + vec2 offset2 = vec2(6.0*sin(time*1.1), 3.0*cos(time*1.1)); + vec2 oldPos = vTextureCoord.xy - vec2(0.5, 0.5); + vec2 newPos = vec2(oldPos.x * c2 - oldPos.y * s2, + oldPos.y * c2 + oldPos.x * s2); + newPos = newPos*(1.0+0.2*s3) - offset2; + vec2 temp = newPos; + float beta = sin(temp.y*2.0 + time*8.0); + newPos.x = temp.x + 0.4*beta; + newPos.y = temp.y - 0.4*beta; + gl_FragColor = texture2D(iChannel0, newPos); + } + ); +} + +#ifdef STANDALONE + +typedef struct +{ + uint32_t screen_width; + uint32_t screen_height; +// OpenGL|ES objects + EGLDisplay display; + EGLSurface surface; + EGLContext context; +} EGL_STATE_T; + +/*********************************************************** + * Name: init_ogl + * + * Arguments: + * CUBE_STATE_T *state - holds OGLES model info + * + * Description: Sets the display, OpenGL|ES context and screen stuff + * + * Returns: void + * + ***********************************************************/ +static void init_ogl(EGL_STATE_T *state) +{ + int32_t success = 0; + EGLBoolean result; + EGLint num_config; + + static EGL_DISPMANX_WINDOW_T nativewindow; + + DISPMANX_ELEMENT_HANDLE_T dispman_element; + DISPMANX_DISPLAY_HANDLE_T dispman_display; + DISPMANX_UPDATE_HANDLE_T dispman_update; + VC_RECT_T dst_rect; + VC_RECT_T src_rect; + + static const EGLint attribute_list[] = + { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE + }; + + static const EGLint context_attributes[] = + { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + EGLConfig config; + + // get an EGL display connection + state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + assert(state->display!=EGL_NO_DISPLAY); + check(); + + // initialize the EGL display connection + result = eglInitialize(state->display, NULL, NULL); + assert(EGL_FALSE != result); + check(); + + // get an appropriate EGL frame buffer configuration + result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config); + assert(EGL_FALSE != result); + check(); + + // get an appropriate EGL frame buffer configuration + result = eglBindAPI(EGL_OPENGL_ES_API); + assert(EGL_FALSE != result); + check(); + + // create an EGL rendering context + state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes); + assert(state->context!=EGL_NO_CONTEXT); + check(); + + // create an EGL window surface + success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height); + assert( success >= 0 ); + + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = state->screen_width; + dst_rect.height = state->screen_height; + + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = state->screen_width << 16; + src_rect.height = state->screen_height << 16; + + dispman_display = vc_dispmanx_display_open( 0 /* LCD */); + dispman_update = vc_dispmanx_update_start( 0 ); + + dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display, + 0/*layer*/, &dst_rect, 0/*src*/, + &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/); + + nativewindow.element = dispman_element; + nativewindow.width = state->screen_width; + nativewindow.height = state->screen_height; + vc_dispmanx_update_submit_sync( dispman_update ); + + check(); + + state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL ); + assert(state->surface != EGL_NO_SURFACE); + check(); + + // connect the context to the surface + result = eglMakeCurrent(state->display, state->surface, state->surface, state->context); + assert(EGL_FALSE != result); + check(); +} + +int main () +{ + int terminate = 0; + CUBE_STATE_T _state, *state=&_state; + EGL_STATE_T _eglstate, *eglstate=&_eglstate; + + // Clear application state + memset( eglstate, 0, sizeof( *eglstate ) ); + bcm_host_init(); + // Start OGLES + init_ogl(eglstate); +again: + memset( state, 0, sizeof( *state ) ); + state->verbose = 1; + state->width = eglstate->screen_width; + state->height = eglstate->screen_height; + setup_screensaver_default(state); + setup_screensaver_warp(state); + screensaver_init(state); + screensaver_init_shaders(state); + + int frames = 0; + uint64_t ts = GetTimeStamp(); + while (!terminate) + { + screensaver_update(state); + screensaver_render(state); + eglSwapBuffers(eglstate->display, eglstate->surface); + check(); + + frames++; + uint64_t ts2 = GetTimeStamp(); + if (ts2 - ts > 1e6) + { + printf("%d fps (%.3f)\n", frames, state->time); + ts += 1e6; + frames = 0; + //break; + } + } + screensaver_deinit_shaders(state); + goto again; + return 0; +} +#endif + diff --git a/xbmc/screensavers/gles/triangle2.h b/xbmc/screensavers/gles/triangle2.h new file mode 100644 index 0000000..6088203 --- /dev/null +++ b/xbmc/screensavers/gles/triangle2.h @@ -0,0 +1,64 @@ +#pragma once + +#include "GLES2/gl2.h" +#include "EGL/egl.h" +#include "EGL/eglext.h" + +#define NUMCONSTS 9 + +typedef struct +{ + GLuint verbose; + GLuint effect_vshader; + GLuint effect_fshader; + GLuint render_vshader; + GLuint render_fshader; + GLuint effect_program; + GLuint render_program; + GLuint effect_fb; + GLuint framebuffer_texture; + GLuint vertex_buffer; + GLuint effect_texture; + void *effect_texture_data; +// effect attribs + GLuint uTime, uScale, uResolution, uMouse; + GLuint uChannel0; +// render attribs + GLuint attr_vertex, uTexture; + uint64_t last_time; + float _c[NUMCONSTS]; + float _ct[NUMCONSTS]; + float _cv[NUMCONSTS]; + +// config settings + int width, height; + int texwidth, texheight; + int fbwidth, fbheight; + int mousex, mousey; + float time; + const GLchar *effect_vshader_source; + const GLchar *effect_fshader_source; + const GLchar *render_vshader_source; + const GLchar *render_fshader_source; + +} CUBE_STATE_T; + + +void screensaver_init_shaders(CUBE_STATE_T *state); +void screensaver_init(CUBE_STATE_T *state); +void screensaver_update(CUBE_STATE_T *state); +void screensaver_render(CUBE_STATE_T *state); +void screensaver_deinit_shaders(CUBE_STATE_T *state); + +void setup_screensaver_default(CUBE_STATE_T *state); +void setup_screensaver_warp(CUBE_STATE_T *state); +void setup_screensaver_plasma(CUBE_STATE_T *state); +void setup_screensaver_plasma2(CUBE_STATE_T *state); +void setup_screensaver_noise(CUBE_STATE_T *state); +void setup_screensaver_border(CUBE_STATE_T *state); +void setup_screensaver_stellar(CUBE_STATE_T *state); +void setup_screensaver_spiral(CUBE_STATE_T *state); +void setup_screensaver_ball(CUBE_STATE_T *state); + + + diff --git a/xbmc/screensavers/gles/warp/Makefile.in b/xbmc/screensavers/gles/warp/Makefile.in new file mode 100644 index 0000000..4406b4a --- /dev/null +++ b/xbmc/screensavers/gles/warp/Makefile.in @@ -0,0 +1,36 @@ +ARCH=@ARCH@ +CXXFLAGS=-fPIC +ifeq (@USE_ANDROID@,1) +SLIB = @abs_top_srcdir@/system/libwarp.so +else +SLIB = @abs_top_srcdir@/addons/screensaver.gles.warp/Warp.xbs +endif +OBJS = wrapper.o +DEFINES += -DSCREENSAVER=warp + +ifeq (@USE_OPENGLES@,1) + DEFINES += -DHAS_GLES=2 + INCLUDES+= -I@abs_top_srcdir@/xbmc/screensavers/gles + OBJS += @abs_top_srcdir@/xbmc/screensavers/gles/gleshelpers.a + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGLES + else + LDFLAGS += -lGLESv2 + endif +else + DEFINES += -DHAS_GL + ifeq ($(findstring osx,$(ARCH)), osx) + LDFLAGS += -framework OpenGL + else + LDFLAGS += -lGL + endif +endif + +$(SLIB): $(OBJS) +ifeq ($(findstring osx,$(ARCH)), osx) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -bundle -o $(SLIB) $(OBJS) +else + $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -o $(SLIB) $(OBJS) +endif + +include @abs_top_srcdir@/Makefile.include diff --git a/xbmc/screensavers/gles/warp/wrapper.cc b/xbmc/screensavers/gles/warp/wrapper.cc new file mode 100644 index 0000000..fd58b73 --- /dev/null +++ b/xbmc/screensavers/gles/warp/wrapper.cc @@ -0,0 +1,102 @@ +#include +#include +#include "Application.h" +#include "../../addons/include/xbmc_scr_dll.h" + +extern "C" { + +#include "triangle2.h" + +#define PASTER(x,y) x ## _ ## y +#define EVALUATOR(x,y) PASTER(x,y) +#define NAME(fun) EVALUATOR(fun, SCREENSAVER) + +static CUBE_STATE_T _state, *state=&_state; + +ADDON_STATUS ADDON_Create(void* hdl, void* props) +{ + if (!props) + return ADDON_STATUS_UNKNOWN; + + // Clear application state + memset( state, 0, sizeof( *state ) ); + // Start OGLES + assert( g_application.IsCurrentThread() ); + glGetError(); + + SCR_PROPS* scrprops = (SCR_PROPS*)props; + state->width = scrprops->width; + state->height = scrprops->height; + setup_screensaver_default(state); + NAME(setup_screensaver)(state); + screensaver_init(state); + screensaver_init_shaders(state); + + return ADDON_STATUS_OK; +} + +void Start() +{ +} + +void Render() +{ + screensaver_update(state); + screensaver_render(state); +} + +void ADDON_Stop() +{ + screensaver_deinit_shaders(state); +} + +void ADDON_Destroy() +{ +} + +ADDON_STATUS ADDON_GetStatus() +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +bool ADDON_HasSettings() +{ +puts(__func__); + return false; +} + +unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet) +{ +puts(__func__); + return 0; +} + +ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue) +{ +puts(__func__); + return ADDON_STATUS_OK; +} + +void ADDON_FreeSettings() +{ +puts(__func__); +} + +void ADDON_Announce(const char *flag, const char *sender, const char *message, const void *data) +{ +puts(__func__); +} + +void GetInfo(SCR_INFO *info) +{ +puts(__func__); +} + +void Remove() +{ +puts(__func__); +} + +} + -- 2.7.1 From ca572db123a49f176aa2d759e318bff3847c59dc Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 10 May 2015 11:31:27 +0200 Subject: [PATCH 059/250] Disable bcm_xxx.h dependent code in the new gles screensavers if no RPI is build Upstream-commit: 9d471bb84543d2850b930f0de74b8d61b7be61ea --- xbmc/screensavers/gles/Makefile.in | 2 ++ xbmc/screensavers/gles/solarwinds/Makefile.in | 2 ++ 2 files changed, 4 insertions(+) diff --git a/xbmc/screensavers/gles/Makefile.in b/xbmc/screensavers/gles/Makefile.in index b83237d..0c15687 100644 --- a/xbmc/screensavers/gles/Makefile.in +++ b/xbmc/screensavers/gles/Makefile.in @@ -1,4 +1,6 @@ +ifeq (@TARGET_RASPBERRY_PI@,1) SRCS=triangle2.cpp +endif LIB=gleshelpers.a diff --git a/xbmc/screensavers/gles/solarwinds/Makefile.in b/xbmc/screensavers/gles/solarwinds/Makefile.in index 8d4e845..e14d31d 100644 --- a/xbmc/screensavers/gles/solarwinds/Makefile.in +++ b/xbmc/screensavers/gles/solarwinds/Makefile.in @@ -5,8 +5,10 @@ SLIB = @abs_top_srcdir@/system/libsolarwinds.so else SLIB = @abs_top_srcdir@/addons/screensaver.gles.solarwinds/Solarwinds.xbs endif +ifeq (@TARGET_RASPBERRY_PI@,1) OBJS = wrapper.o solarwinds.o DEFINES += -DSCREENSAVER=solarwinds +endif ifeq (@USE_OPENGLES@,1) DEFINES += -DHAS_GLES=2 -- 2.7.1 From 5bed972555b8a9a2d924e40c10ef79d15d3fbf60 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 10 May 2015 14:32:54 +0200 Subject: [PATCH 060/250] Parse detailed timing modes too. Upstream-commit: 5f6b38caecce67baf6e565126121f144c1abe448 (kernel MUST correctly support modes matching and res. changing) --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 777d8c2..68299b4 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -360,7 +360,7 @@ bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutio for (size_t i = 0; i < probe_str.size(); i++) { if(!StringUtils::StartsWith(probe_str[i], "S:") && !StringUtils::StartsWith(probe_str[i], "U:") && - !StringUtils::StartsWith(probe_str[i], "V:") && + !StringUtils::StartsWith(probe_str[i], "V:") && !StringUtils::StartsWith(probe_str[i], "D:") && !StringUtils::StartsWith(probe_str[i], "H:") && !StringUtils::StartsWith(probe_str[i], "T:")) continue; -- 2.7.1 From 85a2c6970e676a6223957a40f336667f90a14085 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 10 May 2015 14:33:44 +0200 Subject: [PATCH 061/250] Don't handle U: differently anymore Upstream-commit: 79791499ed747a97693604ad3b5d255167055bca (see comment from 802102fb19710ea775a62bec4ebaf184612be63d) --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 68299b4..ad77d78 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -485,9 +485,7 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->dwFlags = 0; res->fPixelRatio = 1.0f; - if (StringUtils::StartsWith(mode, "U:")) { - res->dwFlags |= D3DPRESENTFLAG_WIDESCREEN; - } else if (StringUtils::StartsWith(mode, "H:")) { + if (StringUtils::StartsWith(mode, "H:")) { res->dwFlags |= D3DPRESENTFLAG_MODE3DSBS; res->fPixelRatio = 2.0f; } else if (StringUtils::StartsWith(mode, "T:")) { -- 2.7.1 From f16e46b3b91291068dce3d5a8787ba8cefb6f541 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 5 Mar 2015 20:00:59 +0000 Subject: [PATCH 062/250] Discard data before VO/VOL in mpeg-4 over mpegts Upstream-commit: d730befe80a3885deded9a37732dfcaf885e2f38 (cherry picked from commit 8aaaeb225f28b4f784b9ae15b2718e894b4359a9) Signed-off-by: Matus Kral --- ...-data-before-VO-VOL-in-mpeg-4-over-mpegts.patch | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 tools/depends/target/ffmpeg/0001-Discard-data-before-VO-VOL-in-mpeg-4-over-mpegts.patch diff --git a/tools/depends/target/ffmpeg/0001-Discard-data-before-VO-VOL-in-mpeg-4-over-mpegts.patch b/tools/depends/target/ffmpeg/0001-Discard-data-before-VO-VOL-in-mpeg-4-over-mpegts.patch new file mode 100644 index 0000000..eef7385 --- /dev/null +++ b/tools/depends/target/ffmpeg/0001-Discard-data-before-VO-VOL-in-mpeg-4-over-mpegts.patch @@ -0,0 +1,69 @@ +From ff289b3678b3b102f76c0fc0ffc802e3c8026fdb Mon Sep 17 00:00:00 2001 +From: Deborah Crook +Date: Thu, 5 Mar 2015 19:48:43 +0000 +Subject: [PATCH] Discard data before VO/VOL in mpeg-4 over mpegts + +--- + libavcodec/mpeg4video_parser.c | 26 ++++++++++++++++++++++---- + 1 file changed, 22 insertions(+), 4 deletions(-) + +diff --git a/libavcodec/mpeg4video_parser.c b/libavcodec/mpeg4video_parser.c +index aa5e87a..0d8b15a 100644 +--- a/libavcodec/mpeg4video_parser.c ++++ b/libavcodec/mpeg4video_parser.c +@@ -43,18 +43,32 @@ int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) + state = pc->state; + + i = 0; +- if (!vop_found) { ++ if (vop_found < 0) { ++ for (i = 0; i < buf_size; i++) { ++ state = (state << 8) | buf[i]; ++ if (state >= 0x100 && state <= 0x12f) { ++ i++; ++ vop_found = 0; ++ break; ++ } ++ } ++ } ++ ++ if (vop_found == 0) ++ vop_found = 1; ++ ++ if (vop_found == 1) { + for (i = 0; i < buf_size; i++) { + state = (state << 8) | buf[i]; + if (state == 0x1B6) { + i++; +- vop_found = 1; ++ vop_found = 2; + break; + } + } + } + +- if (vop_found) { ++ if (vop_found == 2) { + /* EOF considered as end of frame */ + if (buf_size == 0) + return 0; +@@ -133,12 +147,16 @@ static int mpeg4video_parse(AVCodecParserContext *s, + ParseContext *pc = s->priv_data; + int next; + ++ if (pc->frame_start_found == 0 && !avctx->extradata) ++ pc->frame_start_found = -1; ++ + if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { + next = buf_size; + } else { + next = ff_mpeg4_find_frame_end(pc, buf, buf_size); + +- if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { ++ if (pc->frame_start_found < 0 || ++ ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; +-- +2.1.4 -- 2.7.1 From 01c8abc6851ff45d84295fe4e2df4f3dfc2105f0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 20 Feb 2015 14:11:57 +0000 Subject: [PATCH 063/250] libavformat: add mvcC handling in .mov/.mp4 Upstream-commit: 4fe80ffb3dfac541a3aeebc8a7eb9ea700527d33 (cherry picked from commit 6b0dc3f106973b44c003813c464324578b51f9f3) Signed-off-by: Matus Kral --- ...ibavformat-add-mvcC-handling-in-.mov-.mp4.patch | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tools/depends/target/ffmpeg/0001-libavformat-add-mvcC-handling-in-.mov-.mp4.patch diff --git a/tools/depends/target/ffmpeg/0001-libavformat-add-mvcC-handling-in-.mov-.mp4.patch b/tools/depends/target/ffmpeg/0001-libavformat-add-mvcC-handling-in-.mov-.mp4.patch new file mode 100644 index 0000000..72fbcb9 --- /dev/null +++ b/tools/depends/target/ffmpeg/0001-libavformat-add-mvcC-handling-in-.mov-.mp4.patch @@ -0,0 +1,57 @@ +From 40bca2ae81bb9cd131b90bf262e976674ca6fab8 Mon Sep 17 00:00:00 2001 +From: Deborah Crook +Date: Fri, 16 Jan 2015 14:24:17 +0000 +Subject: [PATCH] libavformat: add mvcC handling in .mov/.mp4 + +--- + libavformat/mov.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/libavformat/mov.c b/libavformat/mov.c +index 7455e3b..29bfec9 100644 +--- a/libavformat/mov.c ++++ b/libavformat/mov.c +@@ -1201,6 +1201,33 @@ static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom) + return 0; + } + ++static int mov_read_mvcc(MOVContext *c, AVIOContext *pb, MOVAtom atom) ++{ ++ int extradata_size; ++ int ret, i; ++ uint32_t n; ++ AVStream *st; ++ ++ if (c->fc->nb_streams < 1) ++ return 0; ++ st = c->fc->streams[c->fc->nb_streams-1]; ++ extradata_size = st->codec->extradata_size; ++ ++ if ((uint64_t)atom.size > (1<<30)) ++ return AVERROR_INVALIDDATA; ++ ++ if (extradata_size == 0) ++ return 0; ++ if ((ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_H264)) < 0) ++ return ret; ++ for (i = 0, n = 0; i < 4; i++) ++ n = (n << 8) | st->codec->extradata[extradata_size+i]; ++ n -= 4; ++ for (i = 0; i < 4; i++) ++ st->codec->extradata[extradata_size+i] = (n >> ((3 - i) << 3)) & 0xff; ++ return 0; ++} ++ + static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom) + { + AVStream *st; +@@ -3383,6 +3410,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { + { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 }, + { MKTAG('f','r','e','e'), mov_read_free }, + { MKTAG('-','-','-','-'), mov_read_custom }, ++{ MKTAG('m','v','c','C'), mov_read_mvcc }, + { 0, NULL } + }; + +-- +1.7.10.4 -- 2.7.1 From bc2af38da69ab2cb3e1b001ca5523f76d798bf83 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 10 May 2015 22:48:52 +0200 Subject: [PATCH 064/250] Build ffmpeg with supplied patches Upstream-commit: de21ce70bf2190f0cb00bfa6812f4f7f8341dc3d --- tools/depends/target/ffmpeg/Makefile | 17 ++++++++++------- tools/depends/target/ffmpeg/autobuild.sh | 5 +++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile index ae932ce..127ee9c 100644 --- a/tools/depends/target/ffmpeg/Makefile +++ b/tools/depends/target/ffmpeg/Makefile @@ -1,10 +1,11 @@ -include ../../Makefile.include include FFMPEG-VERSION -DEPS= ../../Makefile.include FFMPEG-VERSION Makefile +DEPS= ../../Makefile.include FFMPEG-VERSION Makefile ffmpeg_Speed_up_wtv_index_creation.patch \ + 0001-avcodec-add-libdcadec-decoder.patch 0002-avcodec-Fix-libdcadec-include-dir.patch 0003-avcodec-add-profile-define-for-DTS-Express.patch \ + 0001-mpeg4video-Signal-unsupported-GMC-with-more-than-one.patch # set to "yes" to enable patching # we don't apply patches until we move to a vanilla ffmpeg tarball -APPLY_PATCHES=no +APPLY_PATCHES=yes # configuration settings ffmpg_config = --prefix=$(PREFIX) --extra-version="kodi-$(VERSION)" @@ -59,9 +60,11 @@ ifeq ($(Configuration), Release) endif +ffmpg_config += $(CONFFLAGS) + CLEAN_FILES=$(ARCHIVE) $(PLATFORM) -all: .installed-$(PLATFORM) +all: .ffmpeg-installed $(TARBALLS_LOCATION)/$(ARCHIVE): cd $(TARBALLS_LOCATION); $(RETRIEVE_TOOL) -Ls --create-dirs -f -o $(TARBALLS_LOCATION)/$(ARCHIVE) $(BASE_URL)/$(VERSION).tar.gz @@ -77,14 +80,14 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) build: $(PLATFORM) $(MAKE) -C $(PLATFORM) -.installed-$(PLATFORM): build +.ffmpeg-installed: build $(MAKE) -C $(PLATFORM) install touch $@ clean: $(MAKE) -C $(PLATFORM) clean - rm -f .installed-$(PLATFORM) + rm -f .ffmpeg-installed distclean:: - rm -rf $(PLATFORM) .installed-$(PLATFORM) + rm -rf $(PLATFORM) .ffmpeg-installed diff --git a/tools/depends/target/ffmpeg/autobuild.sh b/tools/depends/target/ffmpeg/autobuild.sh index b9bfd57..e0161b5 100755 --- a/tools/depends/target/ffmpeg/autobuild.sh +++ b/tools/depends/target/ffmpeg/autobuild.sh @@ -100,6 +100,8 @@ do esac done +FLAGS="$FLAGS --target-os=linux" + BUILDTHREADS=${BUILDTHREADS:-$(grep -c "^processor" /proc/cpuinfo)} [ ${BUILDTHREADS} -eq 0 ] && BUILDTHREADS=1 @@ -110,6 +112,9 @@ then [ "$VERSION" == "$CURVER" ] && exit 0 fi +CFLAG="$CFLAGS" CXXFLAGS="$CXXFLAGS" LDFLAGS="$LDFLAGS" PLATFORM=ffmpeg-${VERSION} CONFFLAGS=${FLAGS} PREFIX=${FFMPEG_PREFIX} make -j ${BUILDTHREADS} +exit $? + [ -f ${ARCHIVE} ] || curl -Ls --create-dirs -f -o ${ARCHIVE} ${BASE_URL}/${VERSION}.tar.gz [ $downloadonly ] && exit 0 -- 2.7.1 From 3d48bd7401b2971a43d4419afed8071843334f45 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 17 May 2015 15:18:15 +0200 Subject: [PATCH 065/250] remove unneeded bcm_host.h and allow compilation for GLES2 platforms Upstream-commit: e9f5f45d685da4233404c34a18e354afae6a3b3e --- xbmc/screensavers/gles/Makefile.in | 2 -- xbmc/screensavers/gles/solarwinds/Makefile.in | 2 -- xbmc/screensavers/gles/solarwinds/solarwinds.c | 11 +++++------ xbmc/screensavers/gles/triangle2.c | 2 -- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/xbmc/screensavers/gles/Makefile.in b/xbmc/screensavers/gles/Makefile.in index 0c15687..b83237d 100644 --- a/xbmc/screensavers/gles/Makefile.in +++ b/xbmc/screensavers/gles/Makefile.in @@ -1,6 +1,4 @@ -ifeq (@TARGET_RASPBERRY_PI@,1) SRCS=triangle2.cpp -endif LIB=gleshelpers.a diff --git a/xbmc/screensavers/gles/solarwinds/Makefile.in b/xbmc/screensavers/gles/solarwinds/Makefile.in index e14d31d..8d4e845 100644 --- a/xbmc/screensavers/gles/solarwinds/Makefile.in +++ b/xbmc/screensavers/gles/solarwinds/Makefile.in @@ -5,10 +5,8 @@ SLIB = @abs_top_srcdir@/system/libsolarwinds.so else SLIB = @abs_top_srcdir@/addons/screensaver.gles.solarwinds/Solarwinds.xbs endif -ifeq (@TARGET_RASPBERRY_PI@,1) OBJS = wrapper.o solarwinds.o DEFINES += -DSCREENSAVER=solarwinds -endif ifeq (@USE_OPENGLES@,1) DEFINES += -DHAS_GLES=2 diff --git a/xbmc/screensavers/gles/solarwinds/solarwinds.c b/xbmc/screensavers/gles/solarwinds/solarwinds.c index da5bf21..a1125cf 100644 --- a/xbmc/screensavers/gles/solarwinds/solarwinds.c +++ b/xbmc/screensavers/gles/solarwinds/solarwinds.c @@ -35,8 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include - -#include "bcm_host.h" +#include #include "solarwinds.h" @@ -243,16 +242,16 @@ static void draw_particle_to_texture(CUBE_STATE_T *state) 4, // One component per particle GL_FLOAT, // Data is floating point type GL_FALSE, // No fixed point scaling - sizeof(Particle), // No gaps in data - (void*)(offsetof(Particle, pos))); // Start from "theta" offset within bound buffer + sizeof(struct Particle), // No gaps in data + (void*)(offsetof(struct Particle, pos))); // Start from "theta" offset within bound buffer glEnableVertexAttribArray(state->aShade); glVertexAttribPointer(state->aShade, // Set pointer 4, // Three components per particle GL_FLOAT, // Data is floating point type GL_FALSE, // No fixed point scaling - sizeof(Particle), // No gaps in data - (void*)(offsetof(Particle, shade))); // Start from "shade" offset within bound buffer + sizeof(struct Particle), // No gaps in data + (void*)(offsetof(struct Particle, shade))); // Start from "shade" offset within bound buffer // Draw particles glDrawArrays(GL_POINTS, 0, state->numParticles); diff --git a/xbmc/screensavers/gles/triangle2.c b/xbmc/screensavers/gles/triangle2.c index 16c918f..6fe1155 100644 --- a/xbmc/screensavers/gles/triangle2.c +++ b/xbmc/screensavers/gles/triangle2.c @@ -37,8 +37,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#include "bcm_host.h" - #include "triangle2.h" #define min(a,b) ((a)<(b)?(a):(b)) -- 2.7.1 From 35ec9c30dd05ccdbc48ed9c8b3abe065d88edab1 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 18 May 2015 08:44:00 +0200 Subject: [PATCH 066/250] Parse screen dimensions from Detailed timing section first. This section (should) contain WxH in [mm]. Upstream-commit: 2f14140c23e7a9009e4421bb7a191c79e2e08412 (if not defined, revert back to standard info [cm], then as before revert to 1.0f) --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 53 +++++++++++++++++++++++---------- xbmc/windowing/egl/EGLNativeTypeIMX.h | 13 ++++++-- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index ad77d78..8386f42 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -145,7 +145,6 @@ void CEGLNativeTypeIMX::Initialize() if (!m_readonly) GetNativeResolution(&m_init); - m_sar = GetMonitorSAR(); close(fd); #endif return; @@ -342,6 +341,8 @@ bool CEGLNativeTypeIMX::FindMatchingResolution(const RESOLUTION_INFO &res, const bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutions) { #ifdef HAS_IMXVPU + GetMonitorSAR(); + if (m_readonly) return false; @@ -406,7 +407,24 @@ bool CEGLNativeTypeIMX::ShowWindow(bool show) } #ifdef HAS_IMXVPU -float CEGLNativeTypeIMX::GetMonitorSAR() +float CEGLNativeTypeIMX::ValidateSAR(struct dt_dim *dtm, bool mb) +{ + int Height = dtm->Height | (mb ? (dtm->msbits & 0x0f) << 8 : 0); + if (Height < 1) + return .0f; + + int Width = dtm->Width | (mb ? (dtm->msbits & 0xf0) << 4 : 0); + float t_sar = (float) Width / Height; + + if (t_sar < 0.33 || t_sar > 3.00) + t_sar = .0f; + else + CLog::Log(LOGDEBUG, "%s: Screen SAR: %.3f (from detailed: %s, %dx%d)",__FUNCTION__, t_sar, mb ? "yes" : "no", Width, Height); + + return t_sar; +} + +void CEGLNativeTypeIMX::GetMonitorSAR() { FILE *f_edid; char *str = NULL; @@ -416,12 +434,13 @@ float CEGLNativeTypeIMX::GetMonitorSAR() // kernels <= 3.18 use ./soc0/soc.1 in official imx kernel // kernels > 3.18 use ./soc0/soc + m_sar = 0; f_edid = fopen("/sys/devices/soc0/soc/20e0000.hdmi_video/edid", "r"); if(!f_edid) f_edid = fopen("/sys/devices/soc0/soc.1/20e0000.hdmi_video/edid", "r"); if(!f_edid) - return 0; + return; // we need to convert mxc_hdmi output format to binary array // mxc_hdmi provides the EDID as space delimited 1bytes blocks @@ -452,20 +471,22 @@ float CEGLNativeTypeIMX::GetMonitorSAR() } fclose(f_edid); - // info related to 'Basic display parameters.' is at offset 0x14-0x18. - // where W is 2nd byte, H 3rd. - int cmWidth = (int)*(m_edid +EDID_STRUCT_DISPLAY +1); - int cmHeight = (int)*(m_edid +EDID_STRUCT_DISPLAY +2); - if (cmHeight > 0) - { - float t_sar = (float) cmWidth / cmHeight; - if (t_sar >= 0.33 && t_sar <= 3.0) - return t_sar; - } + // enumerate through (max four) detailed timing info blocks + // specs and lookup WxH [mm / in]. W and H are in 3 bytes, + // where 1st = W, 2nd = H, 3rd byte is 4bit/4bit. + for (int i = EDID_DTM_START; i < 126 && m_sar == 0; i += 18) + m_sar = ValidateSAR((struct dt_dim *)(m_edid +i +EDID_DTM_OFFSET_DIMENSION), true); - // if we end up here, H/W values or final SAR are useless - // return 0 and use 1.0f as PR for all resolutions - return 0; + // fallback - info related to 'Basic display parameters.' is at offset 0x14-0x18. + // where W is 2nd byte, H 3rd. + if (m_sar == 0) + m_sar = ValidateSAR((struct dt_dim *)(m_edid +EDID_STRUCT_DISPLAY +1)); + + // if m_sar != 0, final SAR is usefull + // if it is 0, EDID info was missing or calculated + // SAR value wasn't sane + if (m_sar == 0) + CLog::Log(LOGDEBUG, "%s: Screen SAR - not usable info",__FUNCTION__); } bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) const diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.h b/xbmc/windowing/egl/EGLNativeTypeIMX.h index 7101bcc..940196f 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.h +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.h @@ -24,10 +24,18 @@ #include #include "EGLNativeType.h" -#define EDID_STRUCT_DISPLAY 0x14 +#define EDID_STRUCT_DISPLAY 0x14 +#define EDID_DTM_START 0x36 +#define EDID_DTM_OFFSET_DIMENSION 0x0c class CEGLNativeTypeIMX : public CEGLNativeType { + struct dt_dim { + uint8_t Width; + uint8_t Height; + uint8_t msbits; + }; + public: CEGLNativeTypeIMX(); virtual ~CEGLNativeTypeIMX(); @@ -60,7 +68,8 @@ protected: RESOLUTION_INFO m_init; bool ModeToResolution(std::string mode, RESOLUTION_INFO *res) const; bool FindMatchingResolution(const RESOLUTION_INFO &res, const std::vector &resolutions); - float GetMonitorSAR(); + void GetMonitorSAR(); + float ValidateSAR(struct dt_dim *dtm, bool mb = false); EGLNativeDisplayType m_display; EGLNativeWindowType m_window; -- 2.7.1 From 7aadd95a147a07bc02adb17c67a2463a55b0d3c9 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 6 Jun 2015 21:49:10 +0200 Subject: [PATCH 067/250] Add vsync ReferenceClock Upstream-commit: 30b39ac1cb0f6cbc38c71d49733729e15109a354 --- xbmc/video/VideoReferenceClock.cpp | 4 ++ xbmc/video/VideoReferenceClock.h | 1 + xbmc/video/videosync/Makefile | 3 +- xbmc/video/videosync/VideoSyncIMX.cpp | 117 ++++++++++++++++++++++++++++++++++ xbmc/video/videosync/VideoSyncIMX.h | 42 ++++++++++++ 5 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 xbmc/video/videosync/VideoSyncIMX.cpp create mode 100644 xbmc/video/videosync/VideoSyncIMX.h diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp index b840f97..bb36b78 100644 --- a/xbmc/video/VideoReferenceClock.cpp +++ b/xbmc/video/VideoReferenceClock.cpp @@ -36,6 +36,8 @@ #include "windowing/WindowingFactory.h" #elif defined(TARGET_RASPBERRY_PI) #include "video/videosync/VideoSyncPi.h" +#elif defined(HAS_IMXVPU) +#include "video/videosync/VideoSyncIMX.h" #endif #if defined(TARGET_WINDOWS) #include "video/videosync/VideoSyncD3D.h" @@ -120,6 +122,8 @@ void CVideoReferenceClock::Process() m_pVideoSync = new CVideoSyncIos(); #elif defined(TARGET_RASPBERRY_PI) m_pVideoSync = new CVideoSyncPi(); +#elif defined(HAS_IMXVPU) + m_pVideoSync = new CVideoSyncIMX(); #endif if (m_pVideoSync) diff --git a/xbmc/video/VideoReferenceClock.h b/xbmc/video/VideoReferenceClock.h index d0a9c3f..6ced2ce 100644 --- a/xbmc/video/VideoReferenceClock.h +++ b/xbmc/video/VideoReferenceClock.h @@ -21,6 +21,7 @@ #include "threads/Thread.h" #include "threads/CriticalSection.h" +#include "settings/Settings.h" class CVideoSync; diff --git a/xbmc/video/videosync/Makefile b/xbmc/video/videosync/Makefile index 04184a9..a4fb395 100644 --- a/xbmc/video/videosync/Makefile +++ b/xbmc/video/videosync/Makefile @@ -3,8 +3,9 @@ SRCS=VideoSyncGLX.cpp \ VideoSyncIos.cpp \ VideoSyncDRM.cpp \ VideoSyncPi.cpp \ + VideoSyncIMX.cpp \ LIB=videosync.a include ../../../Makefile.include --include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) \ No newline at end of file +-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) diff --git a/xbmc/video/videosync/VideoSyncIMX.cpp b/xbmc/video/videosync/VideoSyncIMX.cpp new file mode 100644 index 0000000..3e106d8 --- /dev/null +++ b/xbmc/video/videosync/VideoSyncIMX.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "system.h" + +#if defined(HAS_IMXVPU) + +#include "video/videosync/VideoSyncIMX.h" +#include "guilib/GraphicContext.h" +#include "windowing/WindowingFactory.h" +#include "utils/TimeUtils.h" +#include "utils/log.h" +#include + +// TODO - once mxc_dcic driver integrated in kernel +// mxc_dcic.h is exported as part of linux-libc-dev pkg +// for now ease the compilation process by those +// hard defined ioctls() +//#include +#define DCIC_IOC_CONFIG_DCIC _IO('D', 12) +#define DCIC_IOC_START_VSYNC _IO('D', 15) +#define DCIC_IOC_STOP_VSYNC _IO('D', 16) +// end TODO + +#include + +CVideoSyncIMX::CVideoSyncIMX() +{ + m_fddcic = open("/dev/mxc_dcic0", O_RDWR); +} + +CVideoSyncIMX::~CVideoSyncIMX() +{ + if (m_fddcic > 0) + close(m_fddcic); +} + +bool CVideoSyncIMX::Setup(PUPDATECLOCK func) +{ + struct fb_var_screeninfo screen_info; + + UpdateClock = func; + m_abort = false; + + if (m_fddcic < 0) + return false; + + int fb0 = open("/dev/fb0", O_RDONLY | O_NONBLOCK); + if (fb0 < 0) + return false; + + bool bContinue = !ioctl(fb0, FBIOGET_VSCREENINFO, &screen_info); + if (bContinue) + bContinue = !ioctl(m_fddcic, DCIC_IOC_CONFIG_DCIC, &screen_info.sync); + + close(fb0); + if (!bContinue) + return false; + + g_Windowing.Register(this); + CLog::Log(LOGDEBUG, "CVideoReferenceClock: setting up IMX"); + return true; +} + +void CVideoSyncIMX::Run(volatile bool& stop) +{ + unsigned long counter; + unsigned long last = 0; + + ioctl(m_fddcic, DCIC_IOC_START_VSYNC, 0); + while (!stop && !m_abort) + { + read(m_fddcic, &counter, sizeof(unsigned long)); + uint64_t now = CurrentHostCounter(); + + UpdateClock((unsigned int)(counter - last), now); + last = counter; + } + ioctl(m_fddcic, DCIC_IOC_STOP_VSYNC, 0); +} + +void CVideoSyncIMX::Cleanup() +{ + CLog::Log(LOGDEBUG, "CVideoReferenceClock: cleaning up IMX"); + g_Windowing.Unregister(this); +} + +float CVideoSyncIMX::GetFps() +{ + m_fps = g_graphicsContext.GetFPS(); + CLog::Log(LOGDEBUG, "CVideoReferenceClock: fps: %.3f", m_fps); + return m_fps; +} + +void CVideoSyncIMX::OnResetDevice() +{ + m_abort = true; +} + +#endif diff --git a/xbmc/video/videosync/VideoSyncIMX.h b/xbmc/video/videosync/VideoSyncIMX.h new file mode 100644 index 0000000..1355f78 --- /dev/null +++ b/xbmc/video/videosync/VideoSyncIMX.h @@ -0,0 +1,42 @@ +#pragma once +/* + * Copyright (C) 2005-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#if defined(HAS_IMXVPU) + +#include "video/videosync/VideoSync.h" +#include "guilib/DispResource.h" + +class CVideoSyncIMX : public CVideoSync, IDispResource +{ +public: + CVideoSyncIMX(); + virtual ~CVideoSyncIMX(); + virtual bool Setup(PUPDATECLOCK func); + virtual void Run(volatile bool& stop); + virtual void Cleanup(); + virtual float GetFps(); + virtual void OnResetDevice(); +private: + volatile bool m_abort; + int m_fddcic; +}; + +#endif -- 2.7.1 From 337576b6b2eda77acaa9c32bb5c181c03e5348a2 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Wed, 25 Jun 2014 23:08:09 +0200 Subject: [PATCH 068/250] get rid of CStdString in peripherals Upstream-commit: 108ab62ae5617c15342c5725af4c97cd5bb5b736 (cherry picked from commit a3377451c5276e8ad71ae01618c35fd824d14015) Signed-off-by: Matus Kral Conflicts: xbmc/peripherals/PeripheralTypes.h xbmc/peripherals/devices/PeripheralCecAdapter.cpp --- xbmc/peripherals/PeripheralTypes.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xbmc/peripherals/PeripheralTypes.h b/xbmc/peripherals/PeripheralTypes.h index d45153a..0cc9013 100644 --- a/xbmc/peripherals/PeripheralTypes.h +++ b/xbmc/peripherals/PeripheralTypes.h @@ -144,7 +144,7 @@ namespace PERIPHERALS return PERIPHERAL_TUNER; else if (strTypeLowerCase == "imon") return PERIPHERAL_IMON; - else if (strTypeLowerCase.Equals("video")) + else if (strTypeLowerCase == "video") return PERIPHERAL_VIDEO; return PERIPHERAL_UNKNOWN; @@ -186,7 +186,7 @@ namespace PERIPHERALS return PERIPHERAL_BUS_IMX; else if (strTypeLowerCase == "cec") return PERIPHERAL_BUS_CEC; - else if (strTypeLowerCase.Equals("platform")) + else if (strTypeLowerCase == "platform") return PERIPHERAL_BUS_PLATFORM; return PERIPHERAL_BUS_UNKNOWN; @@ -209,13 +209,13 @@ namespace PERIPHERALS strHexString = StringUtils::Format("%04X", iVal); }; - static void UeventToName(CStdString &uevent, CStdString &name) + static void UeventToName(std::string &uevent, std::string &name) { std::vector data = StringUtils::Split(uevent, "\n"); for (size_t i = 0; i < data.size(); i++) if (StringUtils::StartsWith(data[i], "OF_NAME=")) name = data[i].substr(8, data[i].length()); - } + }; }; class PeripheralScanResult -- 2.7.1 From ad7f515c20021f1d6ef2bd568e913fe4bf34c3be Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 13 Jun 2015 21:55:17 +0200 Subject: [PATCH 069/250] Fix m_seekSteps initialisation Upstream-commit: 41731d7b6e91f631a9ec445a648a52c101f07a02 --- xbmc/settings/AdvancedSettings.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index c17614e..e202cf8 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -121,7 +121,8 @@ void CAdvancedSettings::Initialize() m_limiterHold = 0.025f; m_limiterRelease = 0.1f; - m_seekSteps = { 10, 30, 60, 180, 300, 600, 1800 }; + int t[] = { 10, 30, 60, 180, 300, 600, 1800 }; + m_seekSteps.assign(t, t + sizeof(t)/sizeof(t[0])); m_omxHWAudioDecode = false; m_omxDecodeStartWithValidFrame = true; -- 2.7.1 From 673ba1e39924bdb60330dc00556fba17912fd21f Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 14 Jun 2015 00:47:26 +0200 Subject: [PATCH 070/250] #define updates in extra patches Upstream-commit: f1b4e80ed7368539ecbd8d2febb7eb4424b8985b --- tools/depends/target/ffmpeg/no_rpi.patch | 56 ++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 tools/depends/target/ffmpeg/no_rpi.patch diff --git a/tools/depends/target/ffmpeg/no_rpi.patch b/tools/depends/target/ffmpeg/no_rpi.patch new file mode 100644 index 0000000..845695d --- /dev/null +++ b/tools/depends/target/ffmpeg/no_rpi.patch @@ -0,0 +1,56 @@ +--- a/libavcodec/Makefile 2015-05-31 10:55:01.494795804 +0200 ++++ b/libavcodec/Makefile 2015-05-31 10:55:16.462530460 +0200 +@@ -4,10 +4,6 @@ + + HEADERS = avcodec.h \ + avfft.h \ +- rpi_qpu.h \ +- rpi_shader.h \ +- rpi_mailbox.h \ +- rpi_hevc_transform.h \ + dv_profile.h \ + dxva2.h \ + old_codec_ids.h \ +@@ -37,9 +33,6 @@ + resample.o \ + resample2.o \ + utils.o \ +- rpi_qpu.o \ +- rpi_shader.o \ +- rpi_mailbox.o \ + vorbis_parser.o \ + xiph.o \ + +--- a/libavcodec/hevc.h 2015-05-31 10:29:34.000000000 +0200 ++++ b/libavcodec/hevc.h 2015-05-31 11:04:26.486341721 +0200 +@@ -37,7 +37,7 @@ + #include "videodsp.h" + + // define RPI to split the CABAC/prediction/transform into separate stages +-#define RPI ++//#define RPI + + #ifdef RPI + +--- a/libavcodec/utils.c 2015-05-31 10:29:34.000000000 +0200 ++++ b/libavcodec/utils.c 2015-05-31 11:13:05.543108709 +0200 +@@ -26,7 +26,7 @@ + */ + + // Move video buffers to GPU memory +-#define RPI_GPU_BUFFERS ++//#define RPI_GPU_BUFFERS + + #include "config.h" + #include "libavutil/atomic.h" +--- a/libavcodec/rpi_qpu.c 2015-06-14 00:13:13.000000000 +0200 ++++ b/libavcodec/rpi_qpu.c 2015-06-14 00:44:50.203459910 +0200 +@@ -4,7 +4,7 @@ + // define RPI_TIME_TOTAL_VPU to print out how much time is spent in the VPI code + //#define RPI_TIME_TOTAL_VPU + // define RPI_ASYNC to run the VPU in a separate thread, need to make a separate call to check for completion +-#define RPI_ASYNC ++//#define RPI_ASYNC + + #include + #include -- 2.7.1 From 5e82b6dc53fa86a26afbfe1f72faf7eac7810b10 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 24 Jun 2015 08:46:06 +0200 Subject: [PATCH 071/250] Change CStdString -> std::string Upstream-commit: d87f1b55f54b54c0019f8a8f67d11e620ec6971f --- .../bus/linux/PeripheralBusPLATFORMLibUdev.cpp | 16 ++++++++-------- .../peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h | 8 ++++---- xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp | 2 +- xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.h | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp b/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp index 5f227bf..b7eaab8 100644 --- a/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp +++ b/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp @@ -29,7 +29,7 @@ extern "C" { using namespace PERIPHERALS; -CPeripheralBusPLATFORM::CPeripheralBusPLATFORM(CPeripherals *manager, const CStdString &threadname, PeripheralBusType type) : +CPeripheralBusPLATFORM::CPeripheralBusPLATFORM(CPeripherals *manager, const std::string &threadname, PeripheralBusType type) : CPeripheralBusUSB(manager, "PeripBusPLATFORMUdev", type) { udev_monitor_filter_add_match_subsystem_devtype(m_udevMon, "platform", NULL); @@ -51,12 +51,12 @@ bool CPeripheralBusPLATFORM::PerformDeviceScan(PeripheralScanResults &results) devices = udev_enumerate_get_list_entry(enumerate); bool bContinue(true); - CStdString strPath, t; + std::string strPath, t; udev_list_entry_foreach(dev_list_entry, devices) { strPath = udev_list_entry_get_name(dev_list_entry); - dev = udev_device_new_from_syspath(m_udev, strPath); - if (!strPath || !dev) + dev = udev_device_new_from_syspath(m_udev, strPath.c_str()); + if (strPath.empty() || !dev) bContinue = false; if (bContinue) @@ -93,13 +93,13 @@ bool CPeripheralBusPLATFORM::PerformDeviceScan(PeripheralScanResults &results) return true; } -int CPeripheralBusPLATFORM::GetCableState(const CStdString &strLocation) +int CPeripheralBusPLATFORM::GetCableState(const std::string &strLocation) { - struct udev_device *dev = udev_device_new_from_syspath(m_udev, strLocation); + struct udev_device *dev = udev_device_new_from_syspath(m_udev, strLocation.c_str()); std::string files[] = { "cable_state", "status", "state" }; std::vector cableState(files, files + 3); - CStdString t; + std::string t; int state = CABLE_UNKNOWN; if (!dev) @@ -130,7 +130,7 @@ void CPeripheralBusPLATFORM::Process(void) m_bIsStarted = false; } -void CPeripheralBusPLATFORM::OnDeviceChanged(const CStdString &strLocation) +void CPeripheralBusPLATFORM::OnDeviceChanged(const std::string &strLocation) { CSingleLock lock(m_critSection); CPeripheral *peripheral = GetPeripheral(strLocation); diff --git a/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h b/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h index 4d4a74c..9cfd064 100644 --- a/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h +++ b/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h @@ -30,16 +30,16 @@ namespace PERIPHERALS class CPeripheralBusPLATFORM : public CPeripheralBusUSB { public: - CPeripheralBusPLATFORM(CPeripherals *manager, const CStdString &threadname = "PeripBusPLATFORMUdev", PeripheralBusType type = PERIPHERAL_BUS_PLATFORM); + CPeripheralBusPLATFORM(CPeripherals *manager, const std::string &threadname = "PeripBusPLATFORMUdev", PeripheralBusType type = PERIPHERAL_BUS_PLATFORM); virtual ~CPeripheralBusPLATFORM(void) {}; virtual void Clear(void); bool PerformDeviceScan(PeripheralScanResults &results); - virtual void OnDeviceChanged(const CStdString &strLocation); - virtual void OnDeviceAdded(const CStdString &strLocation) {}; - int GetCableState(const CStdString &strLocation); + void OnDeviceChanged(const std::string &strLocation); + void OnDeviceAdded(const std::string &strLocation) {}; + int GetCableState(const std::string &strLocation); protected: virtual void Process(void); diff --git a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp index bb5f490..3a1e46c 100644 --- a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp +++ b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.cpp @@ -76,7 +76,7 @@ extern "C" { using namespace PERIPHERALS; -CPeripheralBusUSB::CPeripheralBusUSB(CPeripherals *manager, const CStdString &threadname, PeripheralBusType type) : +CPeripheralBusUSB::CPeripheralBusUSB(CPeripherals *manager, const std::string &threadname, PeripheralBusType type) : CPeripheralBus(threadname, manager, type) { /* the Process() method in this class overrides the one in CPeripheralBus, so leave this set to true */ diff --git a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.h b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.h index 6d4362d..eed2134 100644 --- a/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.h +++ b/xbmc/peripherals/bus/linux/PeripheralBusUSBLibUdev.h @@ -32,7 +32,7 @@ namespace PERIPHERALS class CPeripheralBusUSB : public CPeripheralBus { public: - CPeripheralBusUSB(CPeripherals *manager, const CStdString &threadname = "PeripBusUSBUdev", PeripheralBusType type = PERIPHERAL_BUS_USB); + CPeripheralBusUSB(CPeripherals *manager, const std::string &threadname = "PeripBusUSBUdev", PeripheralBusType type = PERIPHERAL_BUS_USB); virtual ~CPeripheralBusUSB(void); virtual void Clear(void); -- 2.7.1 From bcd8febf72ec8fe748c67347095b12b611ae89a1 Mon Sep 17 00:00:00 2001 From: Anton Fedchin Date: Mon, 6 Jul 2015 10:09:29 +0300 Subject: [PATCH 072/250] Bump version to 2.6.3-Isengard Upstream-commit: 7203840c7319fc8bba9d01ab571538ea2ba2e689 (cherry picked from commit 3cfed60502bd05812019fb53d24c346f3346e35e) Signed-off-by: Matus Kral --- tools/depends/target/ffmpeg/FFMPEG-VERSION | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/depends/target/ffmpeg/FFMPEG-VERSION b/tools/depends/target/ffmpeg/FFMPEG-VERSION index e899e02..6f8673a 100644 --- a/tools/depends/target/ffmpeg/FFMPEG-VERSION +++ b/tools/depends/target/ffmpeg/FFMPEG-VERSION @@ -2,4 +2,3 @@ LIBNAME=ffmpeg BASE_URL=https://github.com/xbmc/FFmpeg/archive VERSION=2.8.6-Jarvis-16.0 ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz - -- 2.7.1 From 51770a50148c3b5abf1d3ea826855ec5e4e5b49a Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 9 Jul 2015 02:07:09 +0200 Subject: [PATCH 073/250] Android SDK missing ifaddrs support. Upstream-commit: 3ea897f2dd0f777809dd80bc90ae77fc6468bdcb --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 88b5ab9..e5502ca 100644 --- a/Makefile.in +++ b/Makefile.in @@ -155,7 +155,7 @@ DIRECTORY_ARCHIVES += xbmc/network/linux/network_linux.a DIRECTORY_ARCHIVES += xbmc/powermanagement/android/powermanagement_android.a DIRECTORY_ARCHIVES += xbmc/storage/android/storage_android.a DIRECTORY_ARCHIVES += xbmc/windowing/X11/windowing_X11.a -DIRECTORY_ARCHIVES += xbmc/network/linux/android-ifaddrs/android-ifaddrs.a +DIRECTORY_ARCHIVES += xbmc/network/linux/android-ifaddrs/ifaddrs.a else DIRECTORY_ARCHIVES += xbmc/input/linux/input_linux.a DIRECTORY_ARCHIVES += xbmc/input/touch/input_touch.a -- 2.7.1 From 99d95b1ddc8246d40f4017926870c929cdb75ec7 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 9 Aug 2015 18:28:10 +0200 Subject: [PATCH 074/250] NFSFile: libNFS read/write chunk size (1M -> 256k) Upstream-commit: 82b40d7e5bde42ae720c11c655087b6c8b92af11 --- xbmc/filesystem/NFSFile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/filesystem/NFSFile.cpp b/xbmc/filesystem/NFSFile.cpp index 3a13369..09988ff 100644 --- a/xbmc/filesystem/NFSFile.cpp +++ b/xbmc/filesystem/NFSFile.cpp @@ -324,8 +324,8 @@ bool CNfsConnection::Connect(const CURL& url, std::string &relativePath) m_exportPath = exportPath; m_hostName = url.GetHostName(); //read chunksize only works after mount - m_readChunkSize = m_pLibNfs->nfs_get_readmax(m_pNfsContext); - m_writeChunkSize = m_pLibNfs->nfs_get_writemax(m_pNfsContext); + m_readChunkSize = 262144; /*m_pLibNfs->nfs_get_readmax(m_pNfsContext);*/ + m_writeChunkSize = 262144; /*m_pLibNfs->nfs_get_writemax(m_pNfsContext);*/ if(contextRet == CONTEXT_NEW) { -- 2.7.1 From cf33de455b85d2eb471b80a2290d53805af88b8f Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 20:40:53 +0200 Subject: [PATCH 075/250] use c++11 to compile Upstream-commit: c90108a71bd6d0dc018db556de715907b8810832 --- xbmc/network/Makefile.in | 1 + xbmc/network/linux/Makefile | 1 + 2 files changed, 2 insertions(+) diff --git a/xbmc/network/Makefile.in b/xbmc/network/Makefile.in index c80651c..4baa1ce 100644 --- a/xbmc/network/Makefile.in +++ b/xbmc/network/Makefile.in @@ -27,3 +27,4 @@ LIB = network.a include @abs_top_srcdir@/Makefile.include -include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) +CXXFLAGS += --std=c++11 -DHAVE_CHAR32_T -DHAVE_CHAR16_T diff --git a/xbmc/network/linux/Makefile b/xbmc/network/linux/Makefile index 207ecda..557c587 100644 --- a/xbmc/network/linux/Makefile +++ b/xbmc/network/linux/Makefile @@ -6,3 +6,4 @@ LIB=network_linux.a include ../../../Makefile.include -include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) +CXXFLAGS += --std=c++11 -DHAVE_CHAR32_T -DHAVE_CHAR16_T -- 2.7.1 From 801941a7af37f2995953a2969c2964d48ef35c48 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 10 Jul 2015 21:18:18 +0200 Subject: [PATCH 076/250] fix typo in Makefile.in Upstream-commit: 1167b13545c5fa8d1cb256e8e2eeefb8ea273b39 --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index e5502ca..88b5ab9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -155,7 +155,7 @@ DIRECTORY_ARCHIVES += xbmc/network/linux/network_linux.a DIRECTORY_ARCHIVES += xbmc/powermanagement/android/powermanagement_android.a DIRECTORY_ARCHIVES += xbmc/storage/android/storage_android.a DIRECTORY_ARCHIVES += xbmc/windowing/X11/windowing_X11.a -DIRECTORY_ARCHIVES += xbmc/network/linux/android-ifaddrs/ifaddrs.a +DIRECTORY_ARCHIVES += xbmc/network/linux/android-ifaddrs/android-ifaddrs.a else DIRECTORY_ARCHIVES += xbmc/input/linux/input_linux.a DIRECTORY_ARCHIVES += xbmc/input/touch/input_touch.a -- 2.7.1 From bdca21b11f92dd43a6a3071be11013031f0fae45 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 22 Jul 2015 06:47:26 +0200 Subject: [PATCH 077/250] Fractional modes support Upstream-commit: 1031ccb423ba6671cb118924e4e157a303f67a51 --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 8386f42..032c240 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -360,9 +360,9 @@ bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutio RESOLUTION_INFO res; for (size_t i = 0; i < probe_str.size(); i++) { - if(!StringUtils::StartsWith(probe_str[i], "S:") && !StringUtils::StartsWith(probe_str[i], "U:") && - !StringUtils::StartsWith(probe_str[i], "V:") && !StringUtils::StartsWith(probe_str[i], "D:") && - !StringUtils::StartsWith(probe_str[i], "H:") && !StringUtils::StartsWith(probe_str[i], "T:")) + if(!StringUtils::StartsWithNoCase(probe_str[i], "S:") && !StringUtils::StartsWithNoCase(probe_str[i], "U:") && + !StringUtils::StartsWithNoCase(probe_str[i], "V:") && !StringUtils::StartsWithNoCase(probe_str[i], "D:") && + !StringUtils::StartsWithNoCase(probe_str[i], "H:") && !StringUtils::StartsWithNoCase(probe_str[i], "T:")) continue; if(ModeToResolution(probe_str[i], &res)) @@ -530,7 +530,10 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->iHeight= h; res->iScreenWidth = w; res->iScreenHeight= h; - res->fRefreshRate = r; + if (StringUtils::isasciilowercaseletter(mode[0])) + res->fRefreshRate = (float)r * 1000 / 1001; + else + res->fRefreshRate = (float)r; res->dwFlags |= p[0] == 'p' ? D3DPRESENTFLAG_PROGRESSIVE : D3DPRESENTFLAG_INTERLACED; res->iScreen = 0; @@ -538,7 +541,7 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->iSubtitles = (int)(0.965 * res->iHeight); res->fPixelRatio *= !m_sar ? 1.0f : (float)m_sar / res->iScreenWidth * res->iScreenHeight; - res->strMode = StringUtils::Format("%4sx%4s @ %.2f%s - Full Screen (%.3f) %s", StringUtils::Format("%d", res->iScreenWidth).c_str(), + res->strMode = StringUtils::Format("%4sx%4s @ %.3f%s - Full Screen (%.3f) %s", StringUtils::Format("%d", res->iScreenWidth).c_str(), StringUtils::Format("%d", res->iScreenHeight).c_str(), res->fRefreshRate, res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : " ", res->fPixelRatio, res->dwFlags & D3DPRESENTFLAG_MODE3DSBS ? "- 3DSBS" : res->dwFlags & D3DPRESENTFLAG_MODE3DTB ? "- 3DTB" : ""); -- 2.7.1 From 21292b82a0d0140c98beeb66188257903a94ae9f Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 27 Jul 2015 15:03:39 +0200 Subject: [PATCH 078/250] call OnDeviceReset() before screen is unblanked. Upstream-commit: 652ab12127a3e53571f05d6073b03ec6e608f32a This way any other changes during OnDeviceReset() (of registered resources) will become activated on unblank (Show()). --- xbmc/windowing/egl/WinSystemEGL.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/xbmc/windowing/egl/WinSystemEGL.cpp b/xbmc/windowing/egl/WinSystemEGL.cpp index e1ff18f..ae4c120 100644 --- a/xbmc/windowing/egl/WinSystemEGL.cpp +++ b/xbmc/windowing/egl/WinSystemEGL.cpp @@ -304,12 +304,15 @@ bool CWinSystemEGL::CreateNewWindow(const std::string& name, bool fullScreen, RE CLog::Log(LOGERROR, "%s: Could not create new window",__FUNCTION__); return false; } - Show(); - CSingleLock lock(m_resourceSection); - // tell any shared resources - for (std::vector::iterator i = m_resources.begin(); i != m_resources.end(); ++i) - (*i)->OnResetDevice(); + { + CSingleLock lock(m_resourceSection); + // tell any shared resources + for (std::vector::iterator i = m_resources.begin(); i != m_resources.end(); ++i) + (*i)->OnResetDevice(); + } + + Show(); return true; } -- 2.7.1 From 972884791ef1bf01d0d094a0e4c71cf1ce507ba4 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Fri, 2 Jan 2015 10:02:09 +0100 Subject: [PATCH 079/250] renderer: drop old tempfix firstflippage, did not work anyway because RendererHandlesPresent returned always true Upstream-commit: f4e5d469dbe3bc12471d1a4ce6783d09a1cc9e89 (cherry picked from commit 23f4347c2915bb4032f4353d06cd673fd0888762) Signed-off-by: Matus Kral --- xbmc/guilib/GUIVideoControl.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xbmc/guilib/GUIVideoControl.cpp b/xbmc/guilib/GUIVideoControl.cpp index 27efb64..e6ed130 100644 --- a/xbmc/guilib/GUIVideoControl.cpp +++ b/xbmc/guilib/GUIVideoControl.cpp @@ -43,8 +43,7 @@ void CGUIVideoControl::Process(unsigned int currentTime, CDirtyRegionList &dirty g_renderManager.FrameMove(); // TODO Proper processing which marks when its actually changed. Just mark always for now. - if (g_renderManager.IsGuiLayer()) - MarkDirtyRegion(); + MarkDirtyRegion(); CGUIControl::Process(currentTime, dirtyregions); } -- 2.7.1 From a644f1d76c7ee41e71e8d1c613ffb6ffd42651ed Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 27 Jul 2015 15:08:42 +0200 Subject: [PATCH 080/250] Register to g_Windowing, implement OnDeviceReset(). Upstream-commit: bcb92964043a2bfa603247737c094c03541bc7f0 Move fb1 reconfiguration to own function. Call it on g_windowing reset. --- .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 122 +++++++++++++-------- .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 10 +- 2 files changed, 83 insertions(+), 49 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index c425814..da5f37f 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -25,6 +25,7 @@ #include "threads/Atomics.h" #include "utils/log.h" #include "DVDClock.h" +#include "windowing/WindowingFactory.h" #include #include @@ -1303,6 +1304,7 @@ CIMXContext::CIMXContext() , m_g2dHandle(NULL) , m_bufferCapture(NULL) , m_checkConfigRequired(true) + , m_deviceName("/dev/fb1") { // Limit queue to 2 m_input.resize(2); @@ -1314,58 +1316,39 @@ CIMXContext::~CIMXContext() Close(); } - -bool CIMXContext::Configure() +bool CIMXContext::GetFBInfo(const std::string &fbdev, struct fb_var_screeninfo *fbVar) { - - if (!m_checkConfigRequired) + int fb = open(fbdev.c_str(), O_RDONLY | O_NONBLOCK, 0); + if (fb < 0) + { + CLog::Log(LOGWARNING, "iMX : Failed to open /dev/fb0\n"); return false; + } - SetBlitRects(CRectInt(), CRectInt()); - m_fbCurrentPage = 0; + int err = ioctl(fb, FBIOGET_VSCREENINFO, fbVar); + if (err < 0) + CLog::Log(LOGWARNING, "iMX : Failed to query variable screen info at %s\n", fbdev.c_str()); - int fb0 = open("/dev/fb0", O_RDWR, 0); + close(fb); + return err >= 0; +} - if (fb0 < 0) - { - CLog::Log(LOGWARNING, "iMX : Failed to open /dev/fb0\n"); +bool CIMXContext::AdaptScreen() +{ + if (m_fbHandle <= 0) return false; - } struct fb_var_screeninfo fbVar; - if (ioctl(fb0, FBIOGET_VSCREENINFO, &fbVar) < 0) - { - CLog::Log(LOGWARNING, "iMX : Failed to read primary screen resolution\n"); - close(fb0); + if (!GetFBInfo("/dev/fb0", &fbVar)) return false; - } - - close(fb0); - - if (m_fbHandle) - Close(); CLog::Log(LOGNOTICE, "iMX : Initialize render buffers\n"); - memcpy(&m_fbVar, &fbVar, sizeof(fbVar)); - - const char *deviceName = "/dev/fb1"; + m_fbWidth = fbVar.xres; + m_fbHeight = fbVar.yres; - m_fbHandle = open(deviceName, O_RDWR | O_NONBLOCK, 0); - if (m_fbHandle < 0) - { - CLog::Log(LOGWARNING, "iMX : Failed to open framebuffer: %s\n", deviceName); + if (!GetFBInfo(m_deviceName, &m_fbVar)) return false; - } - - m_fbWidth = m_fbVar.xres; - m_fbHeight = m_fbVar.yres; - - if (ioctl(m_fbHandle, FBIOGET_VSCREENINFO, &m_fbVar) < 0) - { - CLog::Log(LOGWARNING, "iMX : Failed to query variable screen info at %s\n", deviceName); - return false; - } m_pageCrops = new CRectInt[m_fbPages]; @@ -1381,25 +1364,36 @@ bool CIMXContext::Configure() m_fbVar.nonstd = _4CC('R', 'G', 'B', '4'); m_fbVar.bits_per_pixel = 32; } - m_fbVar.activate = FB_ACTIVATE_NOW; + m_fbVar.activate |= FB_ACTIVATE_FORCE; m_fbVar.xres = m_fbWidth; m_fbVar.yres = m_fbHeight; // One additional line that is required for deinterlacing m_fbVar.yres_virtual = (m_fbVar.yres+1) * m_fbPages; m_fbVar.xres_virtual = m_fbVar.xres; - if (ioctl(m_fbHandle, FBIOPUT_VSCREENINFO, &m_fbVar) < 0) + CSingleLock lk(m_pageSwapLock); + + Blank(); + + int err; + struct fb_fix_screeninfo fb_fix; + + err = ioctl(m_fbHandle, FBIOPUT_VSCREENINFO, &m_fbVar); + if (err < 0) { - CLog::Log(LOGWARNING, "iMX : Failed to setup %s\n", deviceName); - close(m_fbHandle); - m_fbHandle = 0; - return false; + CLog::Log(LOGWARNING, "iMX : Failed to setup %s\n", m_deviceName.c_str()); + } + else + { + err = ioctl(m_fbHandle, FBIOGET_FSCREENINFO, &fb_fix); + if (err < 0) + CLog::Log(LOGWARNING, "iMX : Failed to query fixed screen info at %s\n", m_deviceName.c_str()); } - struct fb_fix_screeninfo fb_fix; - if (ioctl(m_fbHandle, FBIOGET_FSCREENINFO, &fb_fix) < 0) + Unblank(); + + if (err < 0) { - CLog::Log(LOGWARNING, "iMX : Failed to query fixed screen info at %s\n", deviceName); close(m_fbHandle); m_fbHandle = 0; return false; @@ -1414,6 +1408,37 @@ bool CIMXContext::Configure() CLog::Log(LOGDEBUG, "iMX : Allocated %d render buffers\n", m_fbPages); + return true; +} + +void CIMXContext::OnResetDevice() +{ + CLog::Log(LOGINFO, "iMX : Changing screen parameters\n"); + AdaptScreen(); +} + +bool CIMXContext::Configure() +{ + + if (!m_checkConfigRequired) + return false; + + SetBlitRects(CRectInt(), CRectInt()); + m_fbCurrentPage = 0; + + if (m_fbHandle) + Close(); + + m_fbHandle = open(m_deviceName.c_str(), O_RDWR | O_NONBLOCK, 0); + if (m_fbHandle < 0) + { + CLog::Log(LOGWARNING, "iMX : Failed to open framebuffer: %s\n", m_deviceName.c_str()); + return false; + } + + if (!AdaptScreen()) + return false; + m_ipuHandle = open("/dev/mxc_ipu", O_RDWR, 0); if (m_ipuHandle < 0) { @@ -1424,7 +1449,6 @@ bool CIMXContext::Configure() } Clear(); - Unblank(); // Start the ipu thread Create(); @@ -2054,11 +2078,13 @@ bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) void CIMXContext::OnStartup() { + g_Windowing.Register(this); CLog::Log(LOGNOTICE, "iMX : IPU thread started"); } void CIMXContext::OnExit() { + g_Windowing.Unregister(this); CLog::Log(LOGNOTICE, "iMX : IPU thread terminated"); } diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h index 8a39dd8..9a96aca 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h @@ -26,6 +26,7 @@ #include "guilib/Geometry.h" #include "DVDVideoCodec.h" #include "DVDStreamInfo.h" +#include "guilib/DispResource.h" #include #include @@ -88,13 +89,14 @@ protected: // iMX context class that handles all iMX hardware // related stuff -class CIMXContext : private CThread +class CIMXContext : private CThread, IDispResource { public: CIMXContext(); ~CIMXContext(); void RequireConfiguration() { m_checkConfigRequired = true; } + bool AdaptScreen(); bool Configure(); bool Close(); @@ -144,6 +146,8 @@ public: void *GetCaptureBuffer() const { if (m_bufferCapture) return m_bufferCapture->buf_vaddr; else return NULL; } void WaitCapture(); + void OnResetDevice(); + private: struct IPUTask { @@ -167,6 +171,8 @@ private: struct ipu_task task; }; + bool GetFBInfo(const std::string &fbdev, struct fb_var_screeninfo *fbVar); + bool PushTask(const IPUTask &); void PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *source, bool topBottomFields, CRect *dest = NULL); @@ -213,6 +219,8 @@ private: bool m_CaptureDone; bool m_checkConfigRequired; static const int m_fbPages; + + std::string m_deviceName; }; -- 2.7.1 From ede6cf581e917429fff79085262d2b55cd17714f Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 8 Aug 2015 14:55:26 +0200 Subject: [PATCH 081/250] cosmetics (change '1' to 'FB_BLANK_NORMAL') Upstream-commit: 8240d25988e8d1acf45dc1ef12c688c843388aca --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index da5f37f..e8ea3ea 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1516,7 +1516,7 @@ bool CIMXContext::GetPageInfo(CIMXBuffer *info, int page) bool CIMXContext::Blank() { if (!m_fbHandle) return false; - return ioctl(m_fbHandle, FBIOBLANK, 1) == 0; + return ioctl(m_fbHandle, FBIOBLANK, FB_BLANK_NORMAL) == 0; } bool CIMXContext::Unblank() -- 2.7.1 From 4c70f317b186865df143b0de17c076e7383149e9 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 28 Jul 2015 20:35:16 +0200 Subject: [PATCH 082/250] update to v15 using SysfsUtils Upstream-commit: bd877040b86d4cc55b85f0691038fe8a9f7493f7 --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 032c240..439498e 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -397,7 +397,7 @@ bool CEGLNativeTypeIMX::ShowWindow(bool show) ioctl(fd, FBIO_WAITFORVSYNC, 0); close(fd); } - set_sysfs_str("/sys/class/graphics/fb0/blank", show?"0":"1"); + SysfsUtils::SetInt("/sys/class/graphics/fb0/blank", show ? 0 : 1 ); m_show = show; return true; -- 2.7.1 From 363a42ec9cfa9ce5a2d787c8b488e8d1e484a53e Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 1 Aug 2015 18:47:28 +0200 Subject: [PATCH 083/250] imx6: add settings options for AC3 transcoding Upstream-commit: 45621a27e21db1cde8d73369eb10a3d809d7a387 --- system/settings/imx6.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/system/settings/imx6.xml b/system/settings/imx6.xml index 3ee2ed5..979a00b 100644 --- a/system/settings/imx6.xml +++ b/system/settings/imx6.xml @@ -45,4 +45,12 @@
+
+ + + + + + +
-- 2.7.1 From 1dc7de3c1f9bdeb028f149e3d63e01be55dfdd05 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 3 Aug 2015 04:50:38 +0200 Subject: [PATCH 084/250] - BaseRenderer: detect interlaced content and try to match it with screen resolution - baserenderer: change allowed diff on pixelRatio when comparing resolutions from 0.001 to 0.01 - Baserenderer: loose a bit criteria when matching resolution's fPixelRatios - BaseRenderer: resolution change - consider resolutions WxH as well when matching fract resolutions. - BaseRenderer: consider resolutions higher from GUI resolution too when matching - Simplify the resolution re-match after modelist refreshed. Upstream-commit: fc630207086618b4abea750e658b2bf07ef7cadd --- .../resource.language.en_gb/resources/strings.po | 13 +++++-- xbmc/Application.cpp | 8 ----- xbmc/Application.h | 1 - xbmc/cores/VideoRenderers/BaseRenderer.cpp | 42 ++++++++++++++++------ xbmc/cores/VideoRenderers/BaseRenderer.h | 1 - xbmc/cores/VideoRenderers/RenderFlags.cpp | 5 +++ xbmc/cores/VideoRenderers/RenderFlags.h | 3 +- .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 2 ++ .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 1 + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 1 + xbmc/windowing/egl/WinSystemEGL.cpp | 34 ++++++------------ 11 files changed, 65 insertions(+), 46 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 478564f..59d9f48 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -6719,7 +6719,12 @@ msgctxt "#13558" msgid "Adjust display resolution" msgstr "" -#empty strings from id 13559 to 13599 +#: system/settings/settings.xml +msgctxt "#13559" +msgid "Include interlaced modes" +msgstr "" + +#empty strings from id 13560 to 13599 #: system/settings/darwin.xml msgctxt "#13600" @@ -16207,7 +16212,11 @@ msgctxt "#36218" msgid "This category contains the electronic programming guide (EPG) settings." msgstr "" -#empty string with id 36219 +#. Description of setting "Videos -> Playback -> Include interlaced modes" with label #13559 +#: system/settings/settings.xml +msgctxt "#36219" +msgid "Interlaced modes will be used for interlaced content (deinterlacing will be deactivated)." +msgstr "" #: system/settings/settings.xml msgctxt "#36220" diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 13e7056..0fe02fa 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -291,7 +291,6 @@ CApplication::CApplication(void) m_ePlayState = PLAY_STATE_NONE; m_skinReverting = false; m_cecStandby = false; - m_res.strMode = ""; m_ourVT = -1; #ifdef HAS_GLX @@ -825,8 +824,6 @@ bool CApplication::CreateGUI(bool showXBMCSplash) info.iHeight, info.strMode.c_str()); - m_res = info; - CLog::Log(LOGDEBUG, "%s: -- base resolution changed to '%s'", __func__, m_res.strMode.c_str()); g_windowManager.Initialize(); return true; @@ -1465,11 +1462,6 @@ void CApplication::OnSettingChanged(const CSetting *setting) m_replayGainSettings.iNoGainPreAmp = ((CSettingInt*)setting)->GetValue(); else if (StringUtils::EqualsNoCase(settingId, CSettings::SETTING_MUSICPLAYER_REPLAYGAINAVOIDCLIPPING)) m_replayGainSettings.bAvoidClipping = ((CSettingBool*)setting)->GetValue(); - - if (StringUtils::EqualsNoCase(settingId, "videoscreen.screenmode") || StringUtils::EqualsNoCase(settingId, "videoscreen.resolution")) { - m_res = CDisplaySettings::Get().GetResolutionInfo(CDisplaySettings::Get().GetDisplayResolution()); - CLog::Log(LOGDEBUG, "%s: -- base resolution changed to '%s'", __func__, m_res.strMode.c_str()); - } } void CApplication::OnSettingAction(const CSetting *setting) diff --git a/xbmc/Application.h b/xbmc/Application.h index 3e53b8d..26f2fde 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h @@ -308,7 +308,6 @@ public: inline bool IsInScreenSaver() { return m_bScreenSave; }; inline bool IsDPMSActive() { return m_dpmsIsActive; }; int m_iScreenSaveLock; // spiff: are we checking for a lock? if so, ignore the screensaver state, if -1 we have failed to input locks - RESOLUTION_INFO m_res; bool m_bPlaybackStarting; typedef enum diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp index 66fe584..496e677 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp @@ -22,6 +22,7 @@ #include // std::abs(int) prototype #include +#include #include "BaseRenderer.h" #include "settings/DisplaySettings.h" #include "settings/MediaSettings.h" @@ -233,43 +234,61 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES float fRefreshRate = fps; - float last_diff = fRefreshRate; + float last_diff = FLT_MAX; int curr_diff = std::abs((int) m_sourceWidth - curr.iScreenWidth); int loop_diff = 0; // CHANGERESOLUTION - if (CSettings::Get().GetBool("videoplayer.adjustresolution") || bRelaxPixelRatio) + if (CSettings::GetInstance().GetBool("videoplayer.adjustresolution")) { bool i_found = false; - if (!bRelaxPixelRatio && !i_found && fRefreshRate != trunc(fRefreshRate)) - for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) + // if interlaced mode + if (m_iFlags & CONF_FLAGS_INTERLACED && CSettings::GetInstance().GetBool("videoplayer.adjustresolutioninterlaced")) + for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::GetInstance().ResolutionInfoSize(); i++) { const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); + if (!(info.dwFlags & D3DPRESENTFLAG_INTERLACED) + || info.iScreenHeight != m_sourceHeight + || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.11) + continue; + current = (RESOLUTION)i; + curr = info; + i_found = true; + } + + if (!i_found) + for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::GetInstance().ResolutionInfoSize(); i++) + { + const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); if ((fabs(info.fRefreshRate - fRefreshRate) > 0.001 && fabs(info.fRefreshRate - 2*fRefreshRate) > 0.001) - || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.001) + || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.11 + || (info.dwFlags & D3DPRESENTFLAG_INTERLACED && !(m_iFlags & CONF_FLAGS_INTERLACED)) + || (!CSettings::GetInstance().GetBool("videoplayer.adjustresolutioninterlaced") && (info.dwFlags & D3DPRESENTFLAG_INTERLACED)) + || m_sourceWidth > info.iScreenWidth || m_sourceHeight > info.iScreenHeight + || pow(info.iScreenWidth*info.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) > last_diff) continue; current = (RESOLUTION)i; curr = info; i_found = true; + last_diff = pow(curr.iScreenWidth*curr.iScreenHeight - m_sourceWidth*m_sourceHeight, 2); if (info.iScreenWidth == m_sourceWidth && info.iScreenHeight == m_sourceHeight) break; } - for (size_t i = (int)RES_DESKTOP; !i_found && i < CDisplaySettings::Get().ResolutionInfoSize(); i++) + last_diff = FLT_MAX; + for (size_t i = (int)RES_DESKTOP; !i_found && i < CDisplaySettings::GetInstance().ResolutionInfoSize(); i++) { const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); if (m_sourceWidth > info.iScreenWidth || m_sourceHeight > info.iScreenHeight - || pow(info.iScreenWidth*info.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) > - pow(curr.iScreenWidth*curr.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) + || pow(info.iScreenWidth*info.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) > last_diff || info.iScreen != curr.iScreen - || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK) - || (!bRelaxPixelRatio && fabs(info.fPixelRatio - curr.fPixelRatio) > 0.001)) + || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK)) { /* CLog::Log(LOGDEBUG, "curr %.2f, trying %.2f, mode nr. %d, %dx%d msk %d, m_msk %d", info.fPixelRatio, curr.fPixelRatio, i, info.iScreenWidth, info.iScreenHeight, info.dwFlags & D3DPRESENTFLAG_MODEMASK, @@ -279,10 +298,13 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES current = (RESOLUTION)i; curr = info; + last_diff = pow(curr.iScreenWidth*curr.iScreenHeight - m_sourceWidth*m_sourceHeight, 2); } } >>>>>>> adjust resolution on play. + last_diff = fRefreshRate; + // Find closest refresh rate for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::GetInstance().ResolutionInfoSize(); i++) { diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h index a01449a..d6a7140 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.h +++ b/xbmc/cores/VideoRenderers/BaseRenderer.h @@ -109,7 +109,6 @@ public: virtual void RegisterRenderFeaturesCallBack(const void *ctx, RenderFeaturesCallBackFn fn); static void SettingOptionsRenderMethodsFiller(const CSetting *setting, std::vector< std::pair > &list, int ¤t, void *data); - static RESOLUTION FindClosestResolution(float fps, float multiplier, RESOLUTION current, float& weight, unsigned int m_sourceWidth, unsigned int m_sourceHeight, unsigned m_iFlags, bool bRelaxPixelRatio = false); protected: void ChooseBestResolution(float fps); diff --git a/xbmc/cores/VideoRenderers/RenderFlags.cpp b/xbmc/cores/VideoRenderers/RenderFlags.cpp index 809766a..b4c6586 100644 --- a/xbmc/cores/VideoRenderers/RenderFlags.cpp +++ b/xbmc/cores/VideoRenderers/RenderFlags.cpp @@ -108,6 +108,11 @@ namespace RenderManager { return convert[mode]; } + unsigned int GetInterlacedModeFlag(bool interlaced) + { + return interlaced ? CONF_FLAGS_INTERLACED : 0; + } + std::string GetStereoModeInvert(const std::string& mode) { static std::map convert; diff --git a/xbmc/cores/VideoRenderers/RenderFlags.h b/xbmc/cores/VideoRenderers/RenderFlags.h index 84ee937..cc3fcf8 100644 --- a/xbmc/cores/VideoRenderers/RenderFlags.h +++ b/xbmc/cores/VideoRenderers/RenderFlags.h @@ -80,7 +80,7 @@ #define CONF_FLAGS_STEREO_CADANCE_LEFT_RIGHT 0x000000 #define CONF_FLAGS_STEREO_CADANCE_RIGHT_LEFT 0x008000 - +#define CONF_FLAGS_INTERLACED 0x010000 namespace RenderManager { @@ -89,6 +89,7 @@ namespace RenderManager { unsigned int GetFlagsColorPrimaries(unsigned int color_primaries); unsigned int GetFlagsColorTransfer(unsigned int color_transfer); unsigned int GetStereoModeFlags(const std::string& mode); + unsigned int GetInterlacedModeFlag(bool interlaced); std::string GetStereoModeInvert(const std::string& mode); } diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h index 68ada7d..501cc59 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h @@ -325,4 +325,6 @@ public: * Decoder request to re-open */ virtual void Reopen() {}; + + virtual bool GetInterlaced() { return false; } }; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h index 9a96aca..6965736 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h @@ -313,6 +313,7 @@ public: virtual void SetDropState(bool bDrop); virtual const char* GetName() { return (const char*)m_pFormatName; } virtual unsigned GetAllowedReferences(); + virtual bool GetInterlaced() { return m_initInfo.nInterlace; } static void Enter(); static void Leave(); diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp index 379c541..df3d8b5 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp @@ -1015,6 +1015,7 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) } flags |= stereo_flags; + flags |= GetInterlacedModeFlag(m_pVideoCodec->GetInterlaced()); CLog::Log(LOGDEBUG,"%s - change configuration. %dx%d. framerate: %4.2f. format: %s",__FUNCTION__,pPicture->iWidth, pPicture->iHeight, config_framerate, formatstr.c_str()); if(!g_renderManager.Configure(pPicture->iWidth diff --git a/xbmc/windowing/egl/WinSystemEGL.cpp b/xbmc/windowing/egl/WinSystemEGL.cpp index ae4c120..35b7de6 100644 --- a/xbmc/windowing/egl/WinSystemEGL.cpp +++ b/xbmc/windowing/egl/WinSystemEGL.cpp @@ -359,7 +359,7 @@ void CWinSystemEGL::UpdateResolutions() { CWinSystemBase::UpdateResolutions(); - RESOLUTION_INFO resDesktop, curDisplay; + RESOLUTION_INFO curDisplay, resDesktop = CDisplaySettings::GetInstance().GetResolutionInfo(CDisplaySettings::GetInstance().GetCurrentResolution()); std::vector resolutions; if (!m_egl->ProbeResolutions(resolutions) || resolutions.empty()) @@ -401,13 +401,13 @@ void CWinSystemEGL::UpdateResolutions() /* ProbeResolutions includes already all resolutions. * Only get desktop resolution so we can replace xbmc's desktop res */ - if (!g_application.m_res.strMode.empty()) - resDesktop = g_application.m_res; - else if (CDisplaySettings::GetInstance().GetDisplayResolution() != RES_DESKTOP) + if (resDesktop.strMode.empty() || CDisplaySettings::GetInstance().GetCurrentResolution() != CDisplaySettings::GetInstance().GetDisplayResolution()) resDesktop = CDisplaySettings::GetInstance().GetResolutionInfo(CDisplaySettings::GetInstance().GetDisplayResolution()); - else if (m_egl->GetNativeResolution(&curDisplay)) - resDesktop = curDisplay; + if (CDisplaySettings::GetInstance().GetCurrentResolution() == RES_DESKTOP) + if (m_egl->GetNativeResolution(&curDisplay)) + resDesktop = curDisplay; + CLog::Log(LOGDEBUG, "Looking for resolution %s", resDesktop.strMode.c_str()); RESOLUTION ResDesktop = RES_INVALID; for (size_t i = 0; i < resolutions.size(); i++) @@ -422,26 +422,14 @@ void CWinSystemEGL::UpdateResolutions() ResDesktop = (RESOLUTION)(i + (int)RES_DESKTOP); } - // don't swap resolutions if current matches previous index - if(CDisplaySettings::Get()Instance.GetCurrentResolution() == ResDesktop) - return; - else if (ResDesktop != RES_INVALID) + if (ResDesktop == RES_INVALID) { - CDisplaySettings::GetInstance().SetCurrentResolution(ResDesktop); - return; + ResDesktop = CDisplaySettings::GetInstance().GetDisplayResolution(); + CLog::Log(LOGNOTICE, "New screen doesn't provide previous resolution. Will change to %d (%s)", ResDesktop, + CDisplaySettings::GetInstance().GetResolutionInfo(ResDesktop).strMode.c_str()); } - // if new screen doesn't provide resolution we need, we try to find closest to previous - float weight; - ResDesktop = CBaseRenderer::FindClosestResolution(g_application.m_res.fRefreshRate, 1.0f, (RESOLUTION)0, weight, - g_application.m_res.iWidth, g_application.m_res.iHeight, g_application.m_res.dwFlags, true); - - if (ResDesktop != RES_INVALID) - { - CLog::Log(LOGNOTICE, "New screen doesn't provide previous resolution. Will change to %d", ResDesktop); - CDisplaySettings::GetInstance().SetCurrentResolution(ResDesktop, true); - g_application.m_res = CDisplaySettings::GetInstance().GetResolutionInfo(CDisplaySettings::GetInstance().GetDisplayResolution()); - } + CDisplaySettings::GetInstance().SetCurrentResolution(ResDesktop); } bool CWinSystemEGL::IsExtSupported(const char* extension) -- 2.7.1 From f1892dd145e297221c662fd3be033bb0e0406662 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 5 Aug 2015 01:03:02 +0200 Subject: [PATCH 085/250] Pvr & Epg: All LOGDEBUG loggin can be turned on/off via component log setup. Upstream-commit: 8ed43cf4dce9081c5e4b1bf4bcbecdc1b5792a7d --- .../resource.language.en_gb/resources/strings.po | 7 ++++- xbmc/commons/ilog.h | 1 + xbmc/epg/Epg.cpp | 9 ++++-- xbmc/epg/EpgContainer.cpp | 12 +++++--- xbmc/epg/EpgDatabase.cpp | 15 ++++++---- xbmc/epg/GUIEPGGridContainer.cpp | 1 + xbmc/pvr/PVRActionListener.cpp | 3 +- xbmc/pvr/PVRDatabase.cpp | 30 ++++++++++++------- xbmc/pvr/PVRManager.cpp | 34 +++++++++++++++------- xbmc/pvr/addons/PVRClient.cpp | 26 +++++++++++------ xbmc/pvr/addons/PVRClients.cpp | 10 +++++-- xbmc/pvr/channels/PVRChannel.cpp | 6 ++-- xbmc/pvr/channels/PVRChannelGroup.cpp | 19 +++++++----- xbmc/pvr/channels/PVRChannelGroups.cpp | 28 ++++++++++++------ xbmc/pvr/channels/PVRChannelGroupsContainer.cpp | 4 ++- xbmc/pvr/recordings/PVRRecordings.cpp | 16 ++++++---- xbmc/pvr/timers/PVRTimers.cpp | 27 ++++++++++------- xbmc/settings/AdvancedSettings.cpp | 1 + 18 files changed, 168 insertions(+), 81 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 59d9f48..b97db75 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -2989,7 +2989,12 @@ msgctxt "#680" msgid "Verbose logging for the [B]Video[/B] component" msgstr "" -#empty strings from id 681 to 699 +#: xbmc/settings/AdvancedSettings.cpp +msgctxt "#681" +msgid "Verbose logging for the [B]PVR[/B] component" +msgstr "" + +#empty strings from id 682 to 699 msgctxt "#700" msgid "Cleaning up library" diff --git a/xbmc/commons/ilog.h b/xbmc/commons/ilog.h index de90359..d4ee6cc 100644 --- a/xbmc/commons/ilog.h +++ b/xbmc/commons/ilog.h @@ -53,6 +53,7 @@ #define LOGUPNP (1 << (LOGMASKBIT + 8)) #define LOGCEC (1 << (LOGMASKBIT + 9)) #define LOGVIDEO (1 << (LOGMASKBIT + 10)) +#define LOGPVR (1 << (LOGMASKBIT + 11)) #include "utils/params_check_macros.h" diff --git a/xbmc/epg/Epg.cpp b/xbmc/epg/Epg.cpp index 0de86c0..4a96a97 100644 --- a/xbmc/epg/Epg.cpp +++ b/xbmc/epg/Epg.cpp @@ -353,7 +353,8 @@ bool CEpg::Load(void) int iEntriesLoaded = database->Get(*this); if (iEntriesLoaded <= 0) { - CLog::Log(LOGDEBUG, "EPG - %s - no database entries found for table '%s'.", __FUNCTION__, m_strName.c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "EPG - %s - no database entries found for table '%s'.", __FUNCTION__, m_strName.c_str()); } else { @@ -650,11 +651,13 @@ bool CEpg::UpdateFromScraper(time_t start, time_t end) } else if (!g_PVRClients->SupportsEPG(channel->ClientID())) { - CLog::Log(LOGDEBUG, "EPG - %s - the backend for channel '%s' on client '%i' does not support EPGs", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "EPG - %s - the backend for channel '%s' on client '%i' does not support EPGs", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); } else { - CLog::Log(LOGDEBUG, "EPG - %s - updating EPG for channel '%s' from client '%i'", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "EPG - %s - updating EPG for channel '%s' from client '%i'", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); bGrabSuccess = (g_PVRClients->GetEPGForChannel(channel, this, start, end) == PVR_ERROR_NO_ERROR); } } diff --git a/xbmc/epg/EpgContainer.cpp b/xbmc/epg/EpgContainer.cpp index 279d920..c565d6f 100644 --- a/xbmc/epg/EpgContainer.cpp +++ b/xbmc/epg/EpgContainer.cpp @@ -520,7 +520,8 @@ bool CEpgContainer::DeleteEpg(const CEpg &epg, bool bDeleteFromDatabase /* = fal if (epgEntry == m_epgs.end()) return false; - CLog::Log(LOGDEBUG, "deleting EPG table %s (%d)", epg.Name().c_str(), epg.EpgID()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "deleting EPG table %s (%d)", epg.Name().c_str(), epg.EpgID()); if (bDeleteFromDatabase && !m_bIgnoreDbForClient && m_database.IsOpen()) m_database.Delete(*epgEntry->second); @@ -828,7 +829,8 @@ void CEpgContainer::UpdateRequest(int clientID, unsigned int channelID) void CEpgContainer::UpdateEpgEvents() { - CLog::Log(LOGDEBUG, "EPGContainer - %s", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "EPGContainer - %s", __FUNCTION__); CSingleLock lock(m_critSection); CDateTime now = CDateTime::GetUTCDateTime(); int count = 0; @@ -848,7 +850,8 @@ void CEpgContainer::UpdateEpgEvents() ++event; } m_lastEpgEventPurge = now; - CLog::Log(LOGDEBUG, "EPGContainer - %s - %d item(s) purged", __FUNCTION__, count); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "EPGContainer - %s - %d item(s) purged", __FUNCTION__, count); } // Fill updated entries @@ -877,7 +880,8 @@ void CEpgContainer::UpdateEpgEvents() ++count; } } - CLog::Log(LOGDEBUG, "EPGContainer - %s - %d item(s) updated", __FUNCTION__, count); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "EPGContainer - %s - %d item(s) updated", __FUNCTION__, count); } void CEpgContainer::CleanupEpgEvents(const CEpgPtr& epg) diff --git a/xbmc/epg/EpgDatabase.cpp b/xbmc/epg/EpgDatabase.cpp index da1ccf6..bf132f0 100644 --- a/xbmc/epg/EpgDatabase.cpp +++ b/xbmc/epg/EpgDatabase.cpp @@ -42,7 +42,8 @@ void CEpgDatabase::CreateTables(void) { CLog::Log(LOGINFO, "EpgDB - %s - creating tables", __FUNCTION__); - CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epg'", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epg'", __FUNCTION__); m_pDS->exec( "CREATE TABLE epg (" "idEpg integer primary key, " @@ -51,7 +52,8 @@ void CEpgDatabase::CreateTables(void) ")" ); - CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epgtags'", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epgtags'", __FUNCTION__); m_pDS->exec( "CREATE TABLE epgtags (" "idBroadcast integer primary key, " @@ -83,7 +85,8 @@ void CEpgDatabase::CreateTables(void) "iFlags integer" ")" ); - CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'lastepgscan'", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'lastepgscan'", __FUNCTION__); m_pDS->exec("CREATE TABLE lastepgscan (" "idEpg integer primary key, " "sLastScan varchar(20)" @@ -93,7 +96,8 @@ void CEpgDatabase::CreateTables(void) void CEpgDatabase::CreateAnalytics() { - CLog::Log(LOGDEBUG, "%s - creating indices", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "%s - creating indices", __FUNCTION__); m_pDS->exec("CREATE UNIQUE INDEX idx_epg_idEpg_iStartTime on epgtags(idEpg, iStartTime desc);"); m_pDS->exec("CREATE INDEX idx_epg_iEndTime on epgtags(iEndTime);"); } @@ -125,7 +129,8 @@ void CEpgDatabase::UpdateTables(int iVersion) bool CEpgDatabase::DeleteEpg(void) { bool bReturn(false); - CLog::Log(LOGDEBUG, "EpgDB - %s - deleting all EPG data from the database", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "EpgDB - %s - deleting all EPG data from the database", __FUNCTION__); bReturn = DeleteValues("epg") || bReturn; bReturn = DeleteValues("epgtags") || bReturn; diff --git a/xbmc/epg/GUIEPGGridContainer.cpp b/xbmc/epg/GUIEPGGridContainer.cpp index b08bf5c..2fde748 100644 --- a/xbmc/epg/GUIEPGGridContainer.cpp +++ b/xbmc/epg/GUIEPGGridContainer.cpp @@ -37,6 +37,7 @@ #include "epg/Epg.h" #include "pvr/channels/PVRChannel.h" +#include "settings/AdvancedSettings.h" #include "Epg.h" #include "GUIEPGGridContainer.h" diff --git a/xbmc/pvr/PVRActionListener.cpp b/xbmc/pvr/PVRActionListener.cpp index d8e29a1..71475a3 100644 --- a/xbmc/pvr/PVRActionListener.cpp +++ b/xbmc/pvr/PVRActionListener.cpp @@ -111,7 +111,8 @@ bool CPVRActionListener::OnAction(const CAction &action) CFileItemPtr fileItem = group->GetLastPlayedChannel(playingChannel->ChannelID()); if (fileItem && fileItem->HasPVRChannelInfoTag()) { - CLog::Log(LOGDEBUG, "%s - switch to channel number %d", __FUNCTION__, fileItem->GetPVRChannelInfoTag()->ChannelNumber()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "%s - switch to channel number %d", __FUNCTION__, fileItem->GetPVRChannelInfoTag()->ChannelNumber()); CApplicationMessenger::GetInstance().SendMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1,static_cast( new CAction(ACTION_CHANNEL_SWITCH, static_cast(fileItem->GetPVRChannelInfoTag()->ChannelNumber())))); } diff --git a/xbmc/pvr/PVRDatabase.cpp b/xbmc/pvr/PVRDatabase.cpp index 5b19bff..da37e8e 100644 --- a/xbmc/pvr/PVRDatabase.cpp +++ b/xbmc/pvr/PVRDatabase.cpp @@ -47,7 +47,8 @@ void CPVRDatabase::CreateTables() { CLog::Log(LOGINFO, "PVR - %s - creating tables", __FUNCTION__); - CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channels'", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channels'", __FUNCTION__); m_pDS->exec( "CREATE TABLE channels (" "idChannel integer primary key, " @@ -71,7 +72,8 @@ void CPVRDatabase::CreateTables() ")" ); - CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelgroups'", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelgroups'", __FUNCTION__); m_pDS->exec( "CREATE TABLE channelgroups (" "idGroup integer primary key," @@ -84,7 +86,8 @@ void CPVRDatabase::CreateTables() ")" ); - CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channelgroups_channels'", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channelgroups_channels'", __FUNCTION__); m_pDS->exec( "CREATE TABLE map_channelgroups_channels (" "idChannel integer, " @@ -186,7 +189,8 @@ void CPVRDatabase::UpdateTables(int iVersion) bool CPVRDatabase::DeleteChannels(void) { - CLog::Log(LOGDEBUG, "PVR - %s - deleting all channels from the database", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - deleting all channels from the database", __FUNCTION__); return DeleteValues("channels"); } @@ -199,7 +203,8 @@ bool CPVRDatabase::DeleteClientChannels(const CPVRClient &client) return false; } - CLog::Log(LOGDEBUG, "PVR - %s - deleting all channels from client '%i' from the database", __FUNCTION__, client.GetID()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - deleting all channels from client '%i' from the database", __FUNCTION__, client.GetID()); Filter filter; filter.AppendWhere(PrepareSQL("iClientId = %u", client.GetID())); @@ -213,7 +218,8 @@ bool CPVRDatabase::Delete(const CPVRChannel &channel) if (channel.ChannelID() <= 0) return false; - CLog::Log(LOGDEBUG, "PVR - %s - deleting channel '%s' from the database", __FUNCTION__, channel.ChannelName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - deleting channel '%s' from the database", __FUNCTION__, channel.ChannelName().c_str()); Filter filter; filter.AppendWhere(PrepareSQL("idChannel = %u", channel.ChannelID())); @@ -260,7 +266,8 @@ int CPVRDatabase::Get(CPVRChannelGroupInternal &results) channel->UpdateEncryptionName(); #if PVRDB_DEBUGGING - CLog::Log(LOGDEBUG, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); #endif PVRChannelGroupMember newMember = { channel, (unsigned int)m_pDS->fv("iChannelNumber").get_asInt() }; results.m_sortedMembers.push_back(newMember); @@ -439,7 +446,8 @@ bool CPVRDatabase::RemoveStaleChannelsFromGroup(const CPVRChannelGroup &group) bool CPVRDatabase::DeleteChannelGroups(void) { - CLog::Log(LOGDEBUG, "PVR - %s - deleting all channel groups from the database", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - deleting all channel groups from the database", __FUNCTION__); return DeleteValues("channelgroups") && DeleteValues("map_channelgroups_channels"); @@ -480,7 +488,8 @@ bool CPVRDatabase::Get(CPVRChannelGroups &results) data.SetPosition(m_pDS->fv("iPosition").get_asInt()); results.Update(data); - CLog::Log(LOGDEBUG, "PVR - %s - group '%s' loaded from the database", __FUNCTION__, data.GroupName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - group '%s' loaded from the database", __FUNCTION__, data.GroupName().c_str()); m_pDS->next(); } m_pDS->close(); @@ -522,7 +531,8 @@ int CPVRDatabase::Get(CPVRChannelGroup &group) if (channel) { #if PVRDB_DEBUGGING - CLog::Log(LOGDEBUG, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); #endif PVRChannelGroupMember newMember = { channel, (unsigned int)iChannelNumber }; group.m_sortedMembers.push_back(newMember); diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index 9ceacf6..325ff60 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -62,6 +62,7 @@ #include "utils/StringUtils.h" #include "utils/Variant.h" #include "video/VideoDatabase.h" +#include "settings/AdvancedSettings.h" using namespace MUSIC_INFO; using namespace PVR; @@ -107,7 +108,8 @@ CPVRManager::~CPVRManager(void) { CAnnouncementManager::GetInstance().RemoveAnnouncer(this); Stop(); - CLog::Log(LOGDEBUG,"PVRManager - destroyed"); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG,"PVRManager - destroyed"); } void CPVRManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) @@ -345,7 +347,8 @@ bool CPVRManager::UpgradeOutdatedAddons(void) g_EpgContainer.Start(true); } - CLog::Log(LOGDEBUG, "PVRManager - %s - restarted", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVRManager - %s - restarted", __FUNCTION__); return true; } @@ -524,7 +527,8 @@ void CPVRManager::Process(void) g_EpgContainer.Start(true); /* main loop */ - CLog::Log(LOGDEBUG, "PVRManager - %s - entering main loop", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVRManager - %s - entering main loop", __FUNCTION__); bool bRestart(false); while (IsStarted() && m_addons && m_addons->HasConnectedClients() && !bRestart) @@ -635,7 +639,8 @@ bool CPVRManager::Load(void) if (!IsInitialising() || !m_addons || !m_addons->HasConnectedClients()) return false; - CLog::Log(LOGDEBUG, "PVRManager - %s - active clients found. continue to start", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVRManager - %s - active clients found. continue to start", __FUNCTION__); /* reset observer for pvr windows */ for (std::size_t i = 0; i != ARRAY_SIZE(m_pvrWindowIds); i++) @@ -751,7 +756,8 @@ bool CPVRManager::ContinueLastChannel(void) return true; } - CLog::Log(LOGDEBUG, "PVRManager - %s - no last played channel to continue playback found", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVRManager - %s - no last played channel to continue playback found", __FUNCTION__); return false; } @@ -877,7 +883,10 @@ int CPVRManager::GetCurrentEpg(CFileItemList &results) const if (channel) iReturn = channel->GetEPG(results); else - CLog::Log(LOGDEBUG,"PVRManager - %s - no current channel set", __FUNCTION__); + { + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG,"PVRManager - %s - no current channel set", __FUNCTION__); + } return iReturn; } @@ -1058,8 +1067,9 @@ bool CPVRManager::OpenLiveStream(const CFileItem &fileItem) if (!fileItem.HasPVRChannelInfoTag()) return bReturn; - CLog::Log(LOGDEBUG,"PVRManager - %s - opening live stream on channel '%s'", - __FUNCTION__, fileItem.GetPVRChannelInfoTag()->ChannelName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG,"PVRManager - %s - opening live stream on channel '%s'", + __FUNCTION__, fileItem.GetPVRChannelInfoTag()->ChannelName().c_str()); // check if we're allowed to play this file if (IsParentalLocked(fileItem.GetPVRChannelInfoTag())) @@ -1335,8 +1345,9 @@ bool CPVRManager::PerformChannelSwitch(const CPVRChannelPtr &channel, bool bPrev CSingleLock lock(m_critSection); if (m_bIsSwitchingChannels) { - CLog::Log(LOGDEBUG, "PVRManager - %s - can't switch to channel '%s'. waiting for the previous switch to complete", - __FUNCTION__, channel->ChannelName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVRManager - %s - can't switch to channel '%s'. waiting for the previous switch to complete", + __FUNCTION__, channel->ChannelName().c_str()); return false; } @@ -1351,7 +1362,8 @@ bool CPVRManager::PerformChannelSwitch(const CPVRChannelPtr &channel, bool bPrev m_bIsSwitchingChannels = true; } - CLog::Log(LOGDEBUG, "PVRManager - %s - switching to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVRManager - %s - switching to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); // will be deleted by CPVRChannelSwitchJob::DoWork() CFileItem* previousFile = m_currentFile; diff --git a/xbmc/pvr/addons/PVRClient.cpp b/xbmc/pvr/addons/PVRClient.cpp index 395caca..b38a37f 100644 --- a/xbmc/pvr/addons/PVRClient.cpp +++ b/xbmc/pvr/addons/PVRClient.cpp @@ -174,7 +174,8 @@ ADDON_STATUS CPVRClient::Create(int iClientId) /* initialise the add-on */ bool bReadyToUse(false); - CLog::Log(LOGDEBUG, "PVR - %s - creating PVR add-on instance '%s'", __FUNCTION__, Name().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - creating PVR add-on instance '%s'", __FUNCTION__, Name().c_str()); try { if ((status = CAddonDll::Create()) == ADDON_STATUS_OK) @@ -202,7 +203,8 @@ void CPVRClient::Destroy(void) m_bReadyToUse = false; /* reset 'ready to use' to false */ - CLog::Log(LOGDEBUG, "PVR - %s - destroying PVR add-on '%s'", __FUNCTION__, GetFriendlyName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - destroying PVR add-on '%s'", __FUNCTION__, GetFriendlyName().c_str()); /* destroy the add-on */ try { CAddonDll::Destroy(); } @@ -842,8 +844,9 @@ PVR_ERROR CPVRClient::GetChannelGroupMembers(CPVRChannelGroup *group) PVR_CHANNEL_GROUP tag; WriteClientGroupInfo(*group, tag); - CLog::Log(LOGDEBUG, "PVR - %s - get group members for group '%s' from add-on '%s'", - __FUNCTION__, tag.strGroupName, GetFriendlyName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - get group members for group '%s' from add-on '%s'", + __FUNCTION__, tag.strGroupName, GetFriendlyName().c_str()); retVal = m_pStruct->GetChannelGroupMembers(&handle, tag); LogError(retVal, __FUNCTION__); @@ -1702,11 +1705,13 @@ bool CPVRClient::OpenStream(const CPVRChannelPtr &channel, bool bIsSwitchingChan if(!CanPlayChannel(channel)) { - CLog::Log(LOGDEBUG, "add-on '%s' can not play channel '%s'", GetFriendlyName().c_str(), channel->ChannelName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "add-on '%s' can not play channel '%s'", GetFriendlyName().c_str(), channel->ChannelName().c_str()); } else if (!channel->StreamURL().empty()) { - CLog::Log(LOGDEBUG, "opening live stream on url '%s'", channel->StreamURL().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "opening live stream on url '%s'", channel->StreamURL().c_str()); bReturn = true; // the Njoy N7 sometimes doesn't switch channels, but opens a stream to the previous channel @@ -1722,7 +1727,8 @@ bool CPVRClient::OpenStream(const CPVRChannelPtr &channel, bool bIsSwitchingChan } else { - CLog::Log(LOGDEBUG, "opening live stream for channel '%s'", channel->ChannelName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "opening live stream for channel '%s'", channel->ChannelName().c_str()); PVR_CHANNEL tag; WriteClientChannelInfo(channel, tag); @@ -1945,14 +1951,16 @@ bool CPVRClient::Autoconfigure(void) { // %s service found at %s std::string strLogLine(StringUtils::Format(g_localizeStrings.Get(19689).c_str(), (*it).GetName().c_str(), (*it).GetIP().c_str())); - CLog::Log(LOGDEBUG, "%s - %s", __FUNCTION__, strLogLine.c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "%s - %s", __FUNCTION__, strLogLine.c_str()); if (DialogResponse::YES != HELPERS::ShowYesNoDialogLines(CVariant{19688}, // Scanning for PVR services CVariant{strLogLine}, CVariant{19690})) // Do you want to use this service? { - CLog::Log(LOGDEBUG, "%s - %s service found but not enabled by the user", __FUNCTION__, (*it).GetName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "%s - %s service found but not enabled by the user", __FUNCTION__, (*it).GetName().c_str()); m_rejectedAvahiHosts.push_back(*it); } else diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp index da39071..687c81f 100644 --- a/xbmc/pvr/addons/PVRClients.cpp +++ b/xbmc/pvr/addons/PVRClients.cpp @@ -36,6 +36,7 @@ #include "pvr/PVRManager.h" #include "pvr/recordings/PVRRecordings.h" #include "pvr/timers/PVRTimers.h" +#include "settings/AdvancedSettings.h" #include "settings/Settings.h" #include "utils/Variant.h" @@ -367,7 +368,8 @@ bool CPVRClients::SwitchChannel(const CPVRChannelPtr &channel) CSingleLock lock(m_critSection); if (m_bIsSwitchingChannels) { - CLog::Log(LOGDEBUG, "PVRClients - %s - can't switch to channel '%s'. waiting for the previous switch to complete", __FUNCTION__, channel->ChannelName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVRClients - %s - can't switch to channel '%s'. waiting for the previous switch to complete", __FUNCTION__, channel->ChannelName().c_str()); return false; } m_bIsSwitchingChannels = true; @@ -1111,7 +1113,8 @@ int CPVRClients::RegisterClient(AddonPtr client) if (!client->Enabled() || !database.Open()) return -1; - CLog::Log(LOGDEBUG, "%s - registering add-on '%s'", __FUNCTION__, client->Name().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "%s - registering add-on '%s'", __FUNCTION__, client->Name().c_str()); // check whether we already know this client iClientId = database.GetAddonId(client); //database->GetClientId(client->ID()); @@ -1396,7 +1399,8 @@ bool CPVRClients::UpdateAddons(void) if (bDisable) { - CLog::Log(LOGDEBUG, "%s - disabling add-on '%s'", __FUNCTION__, (*it)->Name().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "%s - disabling add-on '%s'", __FUNCTION__, (*it)->Name().c_str()); CAddonMgr::GetInstance().DisableAddon((*it)->ID()); usableClients--; } diff --git a/xbmc/pvr/channels/PVRChannel.cpp b/xbmc/pvr/channels/PVRChannel.cpp index 9957537..0a3ecb9 100644 --- a/xbmc/pvr/channels/PVRChannel.cpp +++ b/xbmc/pvr/channels/PVRChannel.cpp @@ -25,6 +25,7 @@ #include "threads/SingleLock.h" #include "utils/log.h" #include "utils/StringUtils.h" +#include "settings/AdvancedSettings.h" #include "utils/Variant.h" #include "pvr/PVRDatabase.h" @@ -546,8 +547,9 @@ int CPVRChannel::GetEPG(CFileItemList &results) const CEpgPtr epg = GetEPG(); if (!epg) { - CLog::Log(LOGDEBUG, "PVR - %s - cannot get EPG for channel '%s'", - __FUNCTION__, m_strChannelName.c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVR - %s - cannot get EPG for channel '%s'", + __FUNCTION__, m_strChannelName.c_str()); return -1; } diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp index 8a2af48..1a0a006 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.cpp +++ b/xbmc/pvr/channels/PVRChannelGroup.cpp @@ -34,6 +34,7 @@ #include "threads/SingleLock.h" #include "utils/log.h" #include "utils/StringUtils.h" +#include "settings/AdvancedSettings.h" #include "pvr/PVRDatabase.h" #include "pvr/PVRManager.h" @@ -162,7 +163,8 @@ bool CPVRChannelGroup::Load(void) m_bUsingBackendChannelNumbers = CSettings::GetInstance().GetBool(CSettings::SETTING_PVRMANAGER_USEBACKENDCHANNELNUMBERS); int iChannelCount = m_iGroupId > 0 ? LoadFromDb() : 0; - CLog::Log(LOGDEBUG, "PVRChannelGroup - %s - %d channels loaded from the database for group '%s'", + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVRChannelGroup - %s - %d channels loaded from the database for group '%s'", __FUNCTION__, iChannelCount, m_strGroupName.c_str()); if (!Update()) @@ -173,8 +175,9 @@ bool CPVRChannelGroup::Load(void) if (Size() - iChannelCount > 0) { - CLog::Log(LOGDEBUG, "PVRChannelGroup - %s - %d channels added from clients to group '%s'", - __FUNCTION__, static_cast(Size() - iChannelCount), m_strGroupName.c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "PVRChannelGroup - %s - %d channels added from clients to group '%s'", + __FUNCTION__, static_cast(Size() - iChannelCount), m_strGroupName.c_str()); } SortAndRenumber(); @@ -900,8 +903,9 @@ bool CPVRChannelGroup::Persist(void) if (CPVRDatabase *database = GetPVRDatabase()) { - CLog::Log(LOGDEBUG, "CPVRChannelGroup - %s - persisting channel group '%s' with %d channels", - __FUNCTION__, GroupName().c_str(), (int) m_members.size()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRChannelGroup - %s - persisting channel group '%s' with %d channels", + __FUNCTION__, GroupName().c_str(), (int) m_members.size()); m_bChanged = false; lock.Leave(); @@ -1034,8 +1038,9 @@ void CPVRChannelGroup::OnSettingChanged(const CSetting *setting) /* check whether this channel group has to be renumbered */ if (bChannelOrderChanged || bChannelNumbersChanged) { - CLog::Log(LOGDEBUG, "CPVRChannelGroup - %s - renumbering group '%s' to use the backend channel order and/or numbers", - __FUNCTION__, m_strGroupName.c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRChannelGroup - %s - renumbering group '%s' to use the backend channel order and/or numbers", + __FUNCTION__, m_strGroupName.c_str()); SortAndRenumber(); Persist(); } diff --git a/xbmc/pvr/channels/PVRChannelGroups.cpp b/xbmc/pvr/channels/PVRChannelGroups.cpp index 95bf4b5..3188ea5 100644 --- a/xbmc/pvr/channels/PVRChannelGroups.cpp +++ b/xbmc/pvr/channels/PVRChannelGroups.cpp @@ -23,6 +23,7 @@ #include "settings/Settings.h" #include "utils/log.h" #include "utils/StringUtils.h" +#include "settings/AdvancedSettings.h" #include "pvr/PVRDatabase.h" #include "pvr/PVRManager.h" @@ -243,7 +244,8 @@ bool CPVRChannelGroups::UpdateGroupsEntries(const CPVRChannelGroups &groups) // user defined group wasn't found if (existingGroup.GroupType() == PVR_GROUP_TYPE_DEFAULT && !group) { - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - user defined group %s with id '%u' does not exist on the client anymore; deleting it", __FUNCTION__, existingGroup.GroupName().c_str(), existingGroup.GroupID()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - user defined group %s with id '%u' does not exist on the client anymore; deleting it", __FUNCTION__, existingGroup.GroupName().c_str(), existingGroup.GroupID()); DeleteGroup(*m_groups.at(iGroupPtr)); } } @@ -278,10 +280,12 @@ bool CPVRChannelGroups::LoadUserDefinedChannelGroups(void) if (bSyncWithBackends) { GetGroupsFromClients(); - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" new user defined %s channel groups fetched from clients", __FUNCTION__, (m_groups.size() - iSize), m_bRadio ? "radio" : "TV"); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" new user defined %s channel groups fetched from clients", __FUNCTION__, (m_groups.size() - iSize), m_bRadio ? "radio" : "TV"); } else - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - 'synchannelgroups' is disabled; skipping groups from clients", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - 'synchannelgroups' is disabled; skipping groups from clients", __FUNCTION__); std::vector emptyGroups; @@ -293,7 +297,8 @@ bool CPVRChannelGroups::LoadUserDefinedChannelGroups(void) { if (!(*it)->Load()) { - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - failed to load channel group '%s'", __FUNCTION__, (*it)->GroupName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - failed to load channel group '%s'", __FUNCTION__, (*it)->GroupName().c_str()); return false; } @@ -305,7 +310,8 @@ bool CPVRChannelGroups::LoadUserDefinedChannelGroups(void) for (std::vector::iterator it = emptyGroups.begin(); it != emptyGroups.end(); ++it) { - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - deleting empty group '%s'", __FUNCTION__, (*it)->GroupName().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - deleting empty group '%s'", __FUNCTION__, (*it)->GroupName().c_str()); DeleteGroup(*(*it)); } @@ -324,7 +330,8 @@ bool CPVRChannelGroups::Load(void) // remove previous contents Clear(); - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - loading all %s channel groups", __FUNCTION__, m_bRadio ? "radio" : "TV"); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - loading all %s channel groups", __FUNCTION__, m_bRadio ? "radio" : "TV"); // create the internal channel group CPVRChannelGroupPtr internalGroup = CPVRChannelGroupPtr(new CPVRChannelGroupInternal(m_bRadio)); @@ -332,7 +339,8 @@ bool CPVRChannelGroups::Load(void) // load groups from the database database->Get(*this); - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" %s groups fetched from the database", __FUNCTION__, m_groups.size(), m_bRadio ? "radio" : "TV"); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" %s groups fetched from the database", __FUNCTION__, m_groups.size(), m_bRadio ? "radio" : "TV"); // load channels of internal group if (!internalGroup->Load()) @@ -352,7 +360,8 @@ bool CPVRChannelGroups::Load(void) CPVRChannelGroupPtr lastPlayedGroup = GetLastPlayedGroup(); SetSelectedGroup(lastPlayedGroup ? lastPlayedGroup : internalGroup); - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" %s channel groups loaded", __FUNCTION__, m_groups.size(), m_bRadio ? "radio" : "TV"); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" %s channel groups loaded", __FUNCTION__, m_groups.size(), m_bRadio ? "radio" : "TV"); // need at least 1 group return m_groups.size() > 0; @@ -361,7 +370,8 @@ bool CPVRChannelGroups::Load(void) bool CPVRChannelGroups::PersistAll(void) { bool bReturn(true); - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - persisting all changes in channel groups", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - persisting all changes in channel groups", __FUNCTION__); CSingleLock lock(m_critSection); for (std::vector::iterator it = m_groups.begin(); it != m_groups.end(); ++it) diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp index 70883dc..98ba1e9 100644 --- a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp +++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp @@ -24,6 +24,7 @@ #include "utils/log.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" +#include "settings/AdvancedSettings.h" #include "pvr/PVRManager.h" @@ -54,7 +55,8 @@ bool CPVRChannelGroupsContainer::Update(bool bChannelsOnly /* = false */) m_bUpdateChannelsOnly = bChannelsOnly; lock.Leave(); - CLog::Log(LOGDEBUG, "CPVRChannelGroupsContainer - %s - updating %s", __FUNCTION__, bChannelsOnly ? "channels" : "channel groups"); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRChannelGroupsContainer - %s - updating %s", __FUNCTION__, bChannelsOnly ? "channels" : "channel groups"); bool bReturn = m_groupsRadio->Update(bChannelsOnly) && m_groupsTV->Update(bChannelsOnly); diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp index 5288a34..60db40d 100644 --- a/xbmc/pvr/recordings/PVRRecordings.cpp +++ b/xbmc/pvr/recordings/PVRRecordings.cpp @@ -19,6 +19,7 @@ */ #include "PVRRecordings.h" +#include "settings/AdvancedSettings.h" #include @@ -179,7 +180,8 @@ void CPVRRecordings::Update(void) m_bIsUpdating = true; lock.Leave(); - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - updating recordings", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRRecordings - %s - updating recordings", __FUNCTION__); UpdateFromClients(); lock.Enter(); @@ -290,7 +292,8 @@ bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) { bResult = true; - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - item path %s", __FUNCTION__, item->GetPath().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRRecordings - %s - item path %s", __FUNCTION__, item->GetPath().c_str()); CFileItemList items; if (item->m_bIsFolder) { @@ -299,15 +302,18 @@ bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) else items.Add(item); - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - will set watched for %d items", __FUNCTION__, items.Size()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRRecordings - %s - will set watched for %d items", __FUNCTION__, items.Size()); for (int i=0;im_bIsFolder) { - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - path %s is a folder, will call recursively", __FUNCTION__, pItem->GetPath().c_str()); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRRecordings - %s - path %s is a folder, will call recursively", __FUNCTION__, pItem->GetPath().c_str()); if (pItem->GetLabel() != "..") { SetRecordingsPlayCount(pItem, count); diff --git a/xbmc/pvr/timers/PVRTimers.cpp b/xbmc/pvr/timers/PVRTimers.cpp index 5c9ed15..da204ff 100644 --- a/xbmc/pvr/timers/PVRTimers.cpp +++ b/xbmc/pvr/timers/PVRTimers.cpp @@ -36,6 +36,7 @@ #include "utils/log.h" #include "utils/StringUtils.h" #include "utils/Variant.h" +#include "settings/AdvancedSettings.h" using namespace PVR; using namespace EPG; @@ -82,7 +83,8 @@ bool CPVRTimers::Update(void) m_bIsUpdating = true; } - CLog::Log(LOGDEBUG, "CPVRTimers - %s - updating timers", __FUNCTION__); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG, "CPVRTimers - %s - updating timers", __FUNCTION__); CPVRTimers newTimerList; g_PVRClients->GetTimers(&newTimerList); return UpdateEntries(newTimerList); @@ -131,8 +133,9 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) timerNotifications.push_back(strMessage); } - CLog::Log(LOGDEBUG,"PVRTimers - %s - updated timer %d on client %d", - __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG,"PVRTimers - %s - updated timer %d on client %d", + __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } else @@ -167,8 +170,9 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) timerNotifications.push_back(strMessage); } - CLog::Log(LOGDEBUG,"PVRTimers - %s - added timer %d on client %d", - __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG,"PVRTimers - %s - added timer %d on client %d", + __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } } @@ -185,8 +189,9 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) if (!timers.GetByClient(timer->m_iClientId, timer->m_iClientIndex)) { /* timer was not found */ - CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", - __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", + __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); if (g_PVRManager.IsStarted()) timerNotifications.push_back(timer->GetDeletedNotificationText()); @@ -202,8 +207,9 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) (!timer->m_bStartAnyTime && timer->StartAsUTC() != it->first)) { /* timer start has changed */ - CLog::Log(LOGDEBUG,"PVRTimers - %s - changed start time timer %d on client %d", - __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG,"PVRTimers - %s - changed start time timer %d on client %d", + __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); timer->ClearEpgTag(); @@ -496,7 +502,8 @@ bool CPVRTimers::DeleteTimersOnChannel(const CPVRChannelPtr &channel, bool bDele if (bDeleteActiveItem && bDeleteRepeatingItem && bChannelsMatch) { - CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); + if (g_advancedSettings.CanLogComponent(LOGPVR)) + CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); bReturn = (*timerIt)->DeleteFromClient(true) || bReturn; SetChanged(); } diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index e202cf8..f7d5f7b 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -1333,6 +1333,7 @@ void CAdvancedSettings::SettingOptionsLoggingComponentsFiller(const CSetting *se list.push_back(std::make_pair(g_localizeStrings.Get(672), LOGFFMPEG)); list.push_back(std::make_pair(g_localizeStrings.Get(676), LOGAUDIO)); list.push_back(std::make_pair(g_localizeStrings.Get(680), LOGVIDEO)); + list.push_back(std::make_pair(g_localizeStrings.Get(681), LOGPVR)); #ifdef HAS_LIBRTMP list.push_back(std::make_pair(g_localizeStrings.Get(673), LOGRTMP)); #endif -- 2.7.1 From b7f09a015c74265bf2da01ba32d58fe6c6784c69 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 8 Aug 2015 17:16:47 +0200 Subject: [PATCH 086/250] Makefile to regenerate python interface files Upstream-commit: e0b3bb0071b9a52a8fccb18f13b8cd3f9c3ccf3c --- Makefile.python-interfaces | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Makefile.python-interfaces diff --git a/Makefile.python-interfaces b/Makefile.python-interfaces new file mode 100644 index 0000000..22b0059 --- /dev/null +++ b/Makefile.python-interfaces @@ -0,0 +1,15 @@ +include bootstrap.mk + +null := +space := ${null} ${null} +${space} := ${space} + +AUTOGENERATED_MAKEFILE = xbmc/interfaces/python/Makefile + +# hack targets to keep build system up to date +Makefile : config.status $(addsuffix .in, $(AUTOGENERATED_MAKEFILES)) + @echo "Regenerating Makefiles..." + @./config.status &> /dev/null + @echo "done" + +config.status: configure -- 2.7.1 From 4151fed6b98ca1c97c83b2e45f8486019ab0fde8 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 8 Aug 2015 20:41:07 +0200 Subject: [PATCH 087/250] rebrand xbmc -> kodi Upstream-commit: 16a05dc2aa3f4178e81f536132e9ad4fe3465eea --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 2 +- xbmc/xbmc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 439498e..8defe54 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -181,7 +181,7 @@ void CEGLNativeTypeIMX::Destroy() SetNativeResolution(m_init); - system("/usr/bin/splash --force -i -m 'stopping xbmc...'"); + system("/usr/bin/splash --force -i -m 'stopping kodi...'"); #endif return; } diff --git a/xbmc/xbmc.cpp b/xbmc/xbmc.cpp index 18c8e0e..ecdaa0b 100644 --- a/xbmc/xbmc.cpp +++ b/xbmc/xbmc.cpp @@ -51,7 +51,7 @@ extern "C" int XBMC_Run(bool renderGUI) struct stat buf; if (stat(filename.c_str(), &buf) != -1) { - system("/usr/bin/splash --force -i -m 'starting xbmc...'"); + system("/usr/bin/splash --force -i -m 'starting kodi...'"); showXBMCSplash = false; } -- 2.7.1 From 907386b8f17db388825984d37b049887b5c39e0b Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 9 Aug 2015 02:49:29 +0200 Subject: [PATCH 088/250] Recognise interlaced mode on output. Disable deinterlacing if screen in interlaced mode. Upstream-commit: 42e9cc9d9c6f571b2467d4809547144484f35688 --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 11 ++++++++++- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index e8ea3ea..cee0a79 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #define IMX_VDI_MAX_WIDTH 968 #define FRAME_ALIGN 16 @@ -44,6 +45,7 @@ #define Align(ptr,align) (((unsigned int)ptr + (align) - 1)/(align)*(align)) #define Align2(ptr,align) (((unsigned int)ptr)/(align)*(align)) +#define BIT(nr) (1UL << (nr)) // Global instance CIMXContext g_IMXContext; @@ -1346,6 +1348,7 @@ bool CIMXContext::AdaptScreen() m_fbWidth = fbVar.xres; m_fbHeight = fbVar.yres; + m_fbInterlaced = fbVar.vmode & FB_VMODE_INTERLACED; if (!GetFBInfo(m_deviceName, &m_fbVar)) return false; @@ -1367,6 +1370,12 @@ bool CIMXContext::AdaptScreen() m_fbVar.activate |= FB_ACTIVATE_FORCE; m_fbVar.xres = m_fbWidth; m_fbVar.yres = m_fbHeight; + + if (m_fbInterlaced) + m_fbVar.vmode |= FB_VMODE_INTERLACED; + else + m_fbVar.vmode &= ~FB_VMODE_INTERLACED; + // One additional line that is required for deinterlacing m_fbVar.yres_virtual = (m_fbVar.yres+1) * m_fbPages; m_fbVar.xres_virtual = m_fbVar.xres; @@ -1557,7 +1566,7 @@ void CIMXContext::SetInterpolatedFrame(bool flag) void CIMXContext::SetDeInterlacing(bool flag) { bool sav_deInt = m_deInterlacing; - m_deInterlacing = flag; + m_deInterlacing = m_fbInterlaced ? false : flag; // If deinterlacing configuration changes then fb has to be reconfigured if (sav_deInt != m_deInterlacing) { diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h index 6965736..9f144c7 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h @@ -190,6 +190,7 @@ private: int m_fbCurrentPage; int m_fbWidth; int m_fbHeight; + bool m_fbInterlaced; int m_fbLineLength; int m_fbPageSize; int m_fbPhysSize; -- 2.7.1 From f2b94a219b252b2c2a9fbc54ddf5ec4932cbe893 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 15 Aug 2015 21:01:50 +0200 Subject: [PATCH 089/250] DVDVideoCodecIMX: decode unknown divx4 content in SW Upstream-commit: 395c490bd58ae1c200380318f63a51b5e7bcca7e --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index cee0a79..c82c81c 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -569,6 +569,12 @@ bool CDVDVideoCodecIMX::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) switch(m_hints.codec_tag) { case _4CC('D','I','V','X'): + // Test for VPU unsupported profiles to revert to sw decoding + if (m_hints.profile == -99 && m_hints.level == -99) + { + CLog::Log(LOGNOTICE, "i.MX6 iMX-divx4 profile %d level %d - sw decoding", m_hints.profile, m_hints.level); + return false; + } m_decOpenParam.CodecFormat = VPU_V_XVID; // VPU_V_DIVX4 m_pFormatName = "iMX-divx4"; break; -- 2.7.1 From d1ddc7a3d5cf02cae5de3dfb8230f1fa358e6446 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 15 Aug 2015 21:59:49 +0200 Subject: [PATCH 090/250] DVDVideoCodecIMX: update Upstream-commit: 177806979a0f93c116f5df152f606b2e53696956 --- xbmc/cores/VideoRenderers/BaseRenderer.cpp | 36 ++ xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 74 +--- xbmc/cores/VideoRenderers/RenderFlags.h | 1 + .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 395 ++++++++++----------- .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 28 +- 5 files changed, 250 insertions(+), 284 deletions(-) diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp index 496e677..07f7e37 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp @@ -36,6 +36,9 @@ #include "settings/AdvancedSettings.h" #include "cores/VideoRenderers/RenderFlags.h" +#if defined(HAS_IMXVPU) +#include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h" +#endif #include "Application.h" CBaseRenderer::CBaseRenderer() @@ -725,6 +728,15 @@ void CBaseRenderer::CalculateFrameAspectRatio(unsigned int desired_width, unsign void CBaseRenderer::ManageDisplay() { +#ifdef HAS_IMXVPU + extern CIMXContext g_IMXContext; + RENDER_STEREO_MODE stereo = g_graphicsContext.GetStereoMode(); + + // this hack is needed to get the 2D mode of a 3D movie going + if (m_format == RENDER_FMT_IMXMAP && stereo) + g_graphicsContext.SetStereoView(RENDER_STEREO_VIEW_LEFT); +#endif + m_viewRect = g_graphicsContext.GetViewWindow(); m_sourceRect.x1 = 0.0f; @@ -773,6 +785,30 @@ void CBaseRenderer::ManageDisplay() } CalcNormalDisplayRect(m_viewRect.x1, m_viewRect.y1, m_viewRect.Width(), m_viewRect.Height(), GetAspectRatio() * CDisplaySettings::GetInstance().GetPixelRatio(), CDisplaySettings::GetInstance().GetZoomAmount(), CDisplaySettings::GetInstance().GetVerticalShift()); +#ifdef HAS_IMXVPU + if (m_format != RENDER_FMT_IMXMAP) + return; + + if (stereo) + g_graphicsContext.SetStereoView(RENDER_STEREO_VIEW_OFF); + + switch (stereo) + { + case RENDER_STEREO_MODE_SPLIT_HORIZONTAL: + m_destRect.y2 *= 2.0; + m_sourceRect.y2 *= 2.0; + break; + case RENDER_STEREO_MODE_SPLIT_VERTICAL: + m_destRect.x2 *= 2.0; + m_sourceRect.x2 *= 2.0; + break; + + default: + break; + } + + g_IMXContext.SetBlitRects(m_sourceRect, m_destRect); +#endif } void CBaseRenderer::SetViewMode(int viewMode) diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp index 1c4715a..7fd5b4c 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp @@ -584,9 +584,9 @@ void CLinuxRendererGLES::RenderUpdateVideo(bool clear, DWORD flags, DWORD alpha) if (IsGuiLayer()) return; + ManageDisplay(); if (m_renderMethod & RENDER_BYPASS) { - ManageDisplay(); // if running bypass, then the player might need the src/dst rects // for sizing video playback on a layer other than the gles layer. if (m_RenderUpdateCallBackFn) @@ -659,77 +659,21 @@ void CLinuxRendererGLES::RenderUpdateVideo(bool clear, DWORD flags, DWORD alpha) CDVDVideoCodecIMXBuffer *buffer = m_buffers[m_iYV12RenderBuffer].IMXBuffer; if (buffer != NULL && buffer->IsValid()) { - // this hack is needed to get the 2D mode of a 3D movie going - RENDER_STEREO_MODE stereo_mode = g_graphicsContext.GetStereoMode(); - if (stereo_mode) - g_graphicsContext.SetStereoView(RENDER_STEREO_VIEW_LEFT); - - ManageDisplay(); - - if (stereo_mode) - g_graphicsContext.SetStereoView(RENDER_STEREO_VIEW_OFF); - - CRect dstRect(m_destRect); - CRect srcRect(m_sourceRect); - switch (stereo_mode) - { - case RENDER_STEREO_MODE_SPLIT_HORIZONTAL: - dstRect.y2 *= 2.0; - srcRect.y2 *= 2.0; - break; - - case RENDER_STEREO_MODE_SPLIT_VERTICAL: - dstRect.x2 *= 2.0; - srcRect.x2 *= 2.0; - break; - - default: - break; - } - - //CLog::Log(LOGDEBUG, "BLIT RECTS: source x1 %f x2 %f y1 %f y2 %f dest x1 %f x2 %f y1 %f y2 %f", srcRect.x1, srcRect.x2, srcRect.y1, srcRect.y2, dstRect.x1, dstRect.x2, dstRect.y1, dstRect.y2); - g_IMXContext.SetBlitRects(srcRect, dstRect); - - bool topFieldFirst = true; - - // Deinterlacing requested - if (flags & RENDER_FLAG_FIELDMASK) + uint8_t fieldFmt = flags & RENDER_FLAG_FIELDMASK; + if (flags & RENDER_FLAG_FIELDS) { - if ((buffer->GetFieldType() == VPU_FIELD_BOTTOM) - || (buffer->GetFieldType() == VPU_FIELD_BT) ) - topFieldFirst = false; - - if (flags & RENDER_FLAG_FIELD0) - { - // Double rate first frame - g_IMXContext.SetDeInterlacing(true); - g_IMXContext.SetDoubleRate(true); - g_IMXContext.SetInterpolatedFrame(true); - } - else if (flags & RENDER_FLAG_FIELD1) - { - // Double rate second frame - g_IMXContext.SetDeInterlacing(true); - g_IMXContext.SetDoubleRate(true); - g_IMXContext.SetInterpolatedFrame(false); - } - else - { - // Fast motion - g_IMXContext.SetDeInterlacing(true); - g_IMXContext.SetDoubleRate(false); - } + fieldFmt |= IPU_DEINTERLACE_RATE_EN; + if (flags & RENDER_FLAG_FIELD1) + fieldFmt |= IPU_DEINTERLACE_RATE_FRAME1; } - // Progressive - else - g_IMXContext.SetDeInterlacing(false); - g_IMXContext.BlitAsync(NULL, buffer, topFieldFirst); + g_IMXContext.SetFieldData(fieldFmt); + g_IMXContext.BlitAsync(NULL, buffer); } #if 0 unsigned long long current2 = XbmcThreads::SystemClockMillis(); - printf("r: %d %d\n", m_iYV12RenderBuffer, (int)(current2-current)); + printf("r: %d %d fm: %d, --xx: %0x, xx--: %0x\n", m_iYV12RenderBuffer, (int)(current2-current), fieldFmt, fieldFmt & 3, fieldFmt & 0xc0); #endif } #endif diff --git a/xbmc/cores/VideoRenderers/RenderFlags.h b/xbmc/cores/VideoRenderers/RenderFlags.h index cc3fcf8..4f9fa6c 100644 --- a/xbmc/cores/VideoRenderers/RenderFlags.h +++ b/xbmc/cores/VideoRenderers/RenderFlags.h @@ -31,6 +31,7 @@ #define RENDER_FLAG_FIELD0 0x80 #define RENDER_FLAG_FIELD1 0x100 #define RENDER_FLAG_WEAVE 0x200 +#define RENDER_FLAG_FIELDS 0x180 // #define RENDER_FLAG_LAST 0x40 diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index c82c81c..793c449 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -26,6 +26,7 @@ #include "utils/log.h" #include "DVDClock.h" #include "windowing/WindowingFactory.h" +#include "guilib/GraphicContext.h" #include #include @@ -424,7 +425,6 @@ CDVDVideoCodecIMX::CDVDVideoCodecIMX() m_convert_bitstream = false; m_bytesToBeConsumed = 0; m_previousPts = DVD_NOPTS_VALUE; - m_warnOnce = true; #ifdef DUMP_STREAM m_dump = NULL; #endif @@ -448,8 +448,6 @@ bool CDVDVideoCodecIMX::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) return false; } - g_IMXContext.RequireConfiguration(); - #ifdef DUMP_STREAM m_dump = fopen("stream.dump", "wb"); if (m_dump != NULL) @@ -504,6 +502,7 @@ bool CDVDVideoCodecIMX::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) } #endif + m_warnOnce = true; m_convert_bitstream = false; switch(m_hints.codec) { @@ -786,6 +785,7 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) #endif if (m_frameReported) m_bytesToBeConsumed += inData.nSize; + ret = VPU_DecDecodeBuf(m_vpuHandle, &inData, &decRet); #ifdef IMX_PROFILE_BUFFERS unsigned long long dec_single_call = XbmcThreads::SystemClockMillis()-before_dec; @@ -935,7 +935,7 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) // According to libfslvpuwrap: If this flag is set then the frame should // be dropped. It is just returned to gather decoder information but not // for display. - if (decRet & VPU_DEC_OUTPUT_MOSAIC_DIS) + else if (decRet & VPU_DEC_OUTPUT_MOSAIC_DIS) { ret = VPU_DecGetOutputFrame(m_vpuHandle, &m_frameInfo); if(ret != VPU_DEC_RET_SUCCESS) @@ -953,35 +953,36 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) } } //VPU_DEC_OUTPUT_MOSAIC_DIS - if (decRet & VPU_DEC_OUTPUT_REPEAT) + else if (decRet & VPU_DEC_OUTPUT_REPEAT) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s - Frame repeat.\n", __FUNCTION__); } - if (decRet & VPU_DEC_OUTPUT_DROPPED) + else if (decRet & VPU_DEC_OUTPUT_DROPPED) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s - Frame dropped.\n", __FUNCTION__); } - if (decRet & VPU_DEC_NO_ENOUGH_BUF) + else if (decRet & VPU_DEC_NO_ENOUGH_BUF) { CLog::Log(LOGERROR, "%s - No frame buffer available.\n", __FUNCTION__); } - if (decRet & VPU_DEC_SKIP) + else if (decRet & VPU_DEC_SKIP) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s - Frame skipped.\n", __FUNCTION__); } - if (decRet & VPU_DEC_FLUSH) + else if (decRet & VPU_DEC_FLUSH) { CLog::Log(LOGNOTICE, "%s - VPU requires a flush.\n", __FUNCTION__); Reset(); retStatus = VC_FLUSHED; } - if (decRet & VPU_DEC_OUTPUT_EOS) + else if (decRet & VPU_DEC_OUTPUT_EOS) { CLog::Log(LOGNOTICE, "%s - EOS encountered.\n", __FUNCTION__); } + if ((decRet & VPU_DEC_NO_ENOUGH_INBUF) || (decRet & VPU_DEC_OUTPUT_DIS)) { @@ -1083,6 +1084,7 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) #endif m_frameCounter++; + pDvdVideoPicture->iFlags = 0; pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED; if (m_dropState) @@ -1091,27 +1093,17 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) pDvdVideoPicture->iFlags &= ~DVP_FLAG_DROPPED; if (m_initInfo.nInterlace) - pDvdVideoPicture->iFlags |= DVP_FLAG_INTERLACED; - else - pDvdVideoPicture->iFlags &= ~DVP_FLAG_INTERLACED; - - // do a sanity check to not deinterlace progressive content - if ((pDvdVideoPicture->iFlags & DVP_FLAG_INTERLACED) && (m_currentBuffer->GetFieldType() == VPU_FIELD_NONE)) { - if (m_warnOnce) + if (m_currentBuffer->GetFieldType() == VPU_FIELD_NONE && m_warnOnce) { m_warnOnce = false; CLog::Log(LOGWARNING, "Interlaced content reported by VPU, but full frames detected - Please turn off deinterlacing manually."); } - } - - if (pDvdVideoPicture->iFlags & DVP_FLAG_INTERLACED) - { - if (m_currentBuffer->GetFieldType() != VPU_FIELD_BOTTOM && m_currentBuffer->GetFieldType() != VPU_FIELD_BT) + else if (m_currentBuffer->GetFieldType() == VPU_FIELD_TB || m_currentBuffer->GetFieldType() == VPU_FIELD_TOP) pDvdVideoPicture->iFlags |= DVP_FLAG_TOP_FIELD_FIRST; + + pDvdVideoPicture->iFlags |= DVP_FLAG_INTERLACED; } - else - pDvdVideoPicture->iFlags &= ~DVP_FLAG_TOP_FIELD_FIRST; pDvdVideoPicture->format = RENDER_FMT_IMXMAP; pDvdVideoPicture->iWidth = m_frameInfo.pExtInfo->FrmCropRect.nRight - m_frameInfo.pExtInfo->FrmCropRect.nLeft; @@ -1307,26 +1299,35 @@ CIMXContext::CIMXContext() , m_fbVirtAddr(NULL) , m_ipuHandle(0) , m_vsync(true) - , m_deInterlacing(false) , m_pageCrops(NULL) + , m_bFbIsConfigured(false) , m_g2dHandle(NULL) , m_bufferCapture(NULL) - , m_checkConfigRequired(true) , m_deviceName("/dev/fb1") { // Limit queue to 2 m_input.resize(2); m_beginInput = m_endInput = m_bufferedInput = 0; + m_pageCrops = new CRectInt[m_fbPages]; + CLog::Log(LOGDEBUG, "iMX : Allocated %d render buffers\n", m_fbPages); + + SetBlitRects(CRectInt(), CRectInt()); + + // Start the ipu thread + Create(); } CIMXContext::~CIMXContext() { - Close(); + StopThread(false); + Dispose(); + Blank(); + CloseDevices(); } bool CIMXContext::GetFBInfo(const std::string &fbdev, struct fb_var_screeninfo *fbVar) { - int fb = open(fbdev.c_str(), O_RDONLY | O_NONBLOCK, 0); + int fb = open(fbdev.c_str(), O_RDONLY, 0); if (fb < 0) { CLog::Log(LOGWARNING, "iMX : Failed to open /dev/fb0\n"); @@ -1341,29 +1342,56 @@ bool CIMXContext::GetFBInfo(const std::string &fbdev, struct fb_var_screeninfo * return err >= 0; } +void CIMXContext::MemMap(struct fb_fix_screeninfo *fb_fix) +{ + if (m_fbVirtAddr && m_fbPhysSize) + { + munmap(m_fbVirtAddr, m_fbPhysSize); + m_fbVirtAddr = NULL; + m_fbPhysAddr = 0; + } + else if (fb_fix) + { + m_fbLineLength = fb_fix->line_length; + m_fbPhysSize = fb_fix->smem_len; + m_fbPageSize = m_fbLineLength * m_fbVar.yres_virtual / m_fbPages; + m_fbPhysAddr = fb_fix->smem_start; + m_fbVirtAddr = (uint8_t*)mmap(0, m_fbPhysSize, PROT_READ | PROT_WRITE, MAP_SHARED, m_fbHandle, 0); + m_fbCurrentPage = 0; + Clear(); + } +} + bool CIMXContext::AdaptScreen() { - if (m_fbHandle <= 0) - return false; + CSingleLock lk(m_pageSwapLock); + + if(m_ipuHandle) { + close(m_ipuHandle); + m_ipuHandle = 0; + } + + MemMap(); + + if(!m_fbHandle) + goto Err; struct fb_var_screeninfo fbVar; if (!GetFBInfo("/dev/fb0", &fbVar)) - return false; + goto Err; - CLog::Log(LOGNOTICE, "iMX : Initialize render buffers\n"); + CLog::Log(LOGNOTICE, "iMX : Changing framebuffer parameters\n"); m_fbWidth = fbVar.xres; m_fbHeight = fbVar.yres; - m_fbInterlaced = fbVar.vmode & FB_VMODE_INTERLACED; if (!GetFBInfo(m_deviceName, &m_fbVar)) - return false; - - m_pageCrops = new CRectInt[m_fbPages]; + goto Err; m_fbVar.xoffset = 0; m_fbVar.yoffset = 0; - if (m_deInterlacing) + + if (0 && m_currentFieldFmt) { m_fbVar.nonstd = _4CC('U', 'Y', 'V', 'Y'); m_fbVar.bits_per_pixel = 16; @@ -1373,144 +1401,96 @@ bool CIMXContext::AdaptScreen() m_fbVar.nonstd = _4CC('R', 'G', 'B', '4'); m_fbVar.bits_per_pixel = 32; } - m_fbVar.activate |= FB_ACTIVATE_FORCE; + m_fbVar.activate = FB_ACTIVATE_NOW; m_fbVar.xres = m_fbWidth; m_fbVar.yres = m_fbHeight; - if (m_fbInterlaced) - m_fbVar.vmode |= FB_VMODE_INTERLACED; - else - m_fbVar.vmode &= ~FB_VMODE_INTERLACED; - - // One additional line that is required for deinterlacing - m_fbVar.yres_virtual = (m_fbVar.yres+1) * m_fbPages; + m_fbVar.yres_virtual = (m_fbVar.yres + 0) * m_fbPages; m_fbVar.xres_virtual = m_fbVar.xres; - CSingleLock lk(m_pageSwapLock); - Blank(); - int err; struct fb_fix_screeninfo fb_fix; - err = ioctl(m_fbHandle, FBIOPUT_VSCREENINFO, &m_fbVar); - if (err < 0) + if (ioctl(m_fbHandle, FBIOPUT_VSCREENINFO, &m_fbVar) < 0) { CLog::Log(LOGWARNING, "iMX : Failed to setup %s\n", m_deviceName.c_str()); + goto Err; } - else + else if (ioctl(m_fbHandle, FBIOGET_FSCREENINFO, &fb_fix) < 0) { - err = ioctl(m_fbHandle, FBIOGET_FSCREENINFO, &fb_fix); - if (err < 0) - CLog::Log(LOGWARNING, "iMX : Failed to query fixed screen info at %s\n", m_deviceName.c_str()); + CLog::Log(LOGWARNING, "iMX : Failed to query fixed screen info at %s\n", m_deviceName.c_str()); + goto Err; } - Unblank(); - - if (err < 0) - { - close(m_fbHandle); - m_fbHandle = 0; - return false; - } + MemMap(&fb_fix); - // Final setup - m_fbLineLength = fb_fix.line_length; - m_fbPhysSize = fb_fix.smem_len; - m_fbPageSize = m_fbLineLength * m_fbVar.yres_virtual / m_fbPages; - m_fbPhysAddr = fb_fix.smem_start; - m_fbVirtAddr = (uint8_t*)mmap(0, m_fbPhysSize, PROT_READ | PROT_WRITE, MAP_SHARED, m_fbHandle, 0); + if (m_currentFieldFmt) + m_ipuHandle = open("/dev/mxc_ipu", O_RDWR, 0); - CLog::Log(LOGDEBUG, "iMX : Allocated %d render buffers\n", m_fbPages); + Unblank(); + m_bFbIsConfigured = true; return true; + +Err: + TaskRestart(); + return false; } void CIMXContext::OnResetDevice() { - CLog::Log(LOGINFO, "iMX : Changing screen parameters\n"); + CLog::Log(LOGDEBUG, "iMX : %s - going to change screen parameters\n", __FUNCTION__); + m_bFbIsConfigured = false; AdaptScreen(); } -bool CIMXContext::Configure() +bool CIMXContext::TaskRestart() { + CLog::Log(LOGINFO, "iMX : %s - restarting IMX rendererer\n", __FUNCTION__); + // Stop the ipu thread + CThread::StopThread(false); + CloseDevices(); + StopThread(); - if (!m_checkConfigRequired) - return false; + Create(); + return true; +} - SetBlitRects(CRectInt(), CRectInt()); - m_fbCurrentPage = 0; +void CIMXContext::Dispose() +{ + if (!m_pageCrops) + return; - if (m_fbHandle) - Close(); + delete[] m_pageCrops; + m_pageCrops = NULL; +} - m_fbHandle = open(m_deviceName.c_str(), O_RDWR | O_NONBLOCK, 0); +bool CIMXContext::OpenDevices() +{ + m_fbHandle = open(m_deviceName.c_str(), O_RDWR, 0); if (m_fbHandle < 0) - { CLog::Log(LOGWARNING, "iMX : Failed to open framebuffer: %s\n", m_deviceName.c_str()); - return false; - } - - if (!AdaptScreen()) - return false; - - m_ipuHandle = open("/dev/mxc_ipu", O_RDWR, 0); - if (m_ipuHandle < 0) - { - CLog::Log(LOGWARNING, "iMX : Failed to initialize IPU: %s\n", strerror(errno)); - m_ipuHandle = 0; - Close(); - return false; - } - Clear(); - - // Start the ipu thread - Create(); - m_checkConfigRequired = false; - return true; + return m_fbHandle > 0; } -bool CIMXContext::Close() +bool CIMXContext::CloseDevices() { - CLog::Log(LOGINFO, "iMX : Closing context\n"); - - // Stop the ipu thread - StopThread(); - - if (m_pageCrops) - { - delete[] m_pageCrops; - m_pageCrops = NULL; - } - - if (m_fbVirtAddr) - { - Clear(); - munmap(m_fbVirtAddr, m_fbPhysSize); - m_fbVirtAddr = NULL; - } + CLog::Log(LOGINFO, "iMX : Closing devices\n"); if (m_fbHandle) { - Blank(); close(m_fbHandle); m_fbHandle = 0; - m_fbPhysAddr = 0; } if (m_ipuHandle) { - // Close IPU device - if (close(m_ipuHandle)) - CLog::Log(LOGERROR, "iMX : Failed to close IPU: %s\n", strerror(errno)); - + close(m_ipuHandle); m_ipuHandle = 0; } - m_checkConfigRequired = true; - CLog::Log(LOGNOTICE, "iMX : Deinitialized render context\n"); - return true; } @@ -1531,12 +1511,18 @@ bool CIMXContext::GetPageInfo(CIMXBuffer *info, int page) bool CIMXContext::Blank() { if (!m_fbHandle) return false; + + CSingleLock lk(m_pageSwapLock); + m_bFbIsConfigured = false; return ioctl(m_fbHandle, FBIOBLANK, FB_BLANK_NORMAL) == 0; } bool CIMXContext::Unblank() { if (!m_fbHandle) return false; + + CSingleLock lk(m_pageSwapLock); + m_bFbIsConfigured = true; return ioctl(m_fbHandle, FBIOBLANK, FB_BLANK_UNBLANK) == 0; } @@ -1546,97 +1532,93 @@ bool CIMXContext::SetVSync(bool enable) return true; } -void CIMXContext::SetDoubleRate(bool flag) -{ - if (flag) - m_currentFieldFmt |= IPU_DEINTERLACE_RATE_EN; - else - m_currentFieldFmt &= ~IPU_DEINTERLACE_RATE_EN; - - m_currentFieldFmt &= ~IPU_DEINTERLACE_RATE_FRAME1; -} - bool CIMXContext::DoubleRate() const { return m_currentFieldFmt & IPU_DEINTERLACE_RATE_EN; } -void CIMXContext::SetInterpolatedFrame(bool flag) +void CIMXContext::SetBlitRects(const CRect &srcRect, const CRect &dstRect) { - if (flag) - m_currentFieldFmt &= ~IPU_DEINTERLACE_RATE_FRAME1; - else - m_currentFieldFmt |= IPU_DEINTERLACE_RATE_FRAME1; + m_srcRect = srcRect; + m_dstRect = dstRect; } -void CIMXContext::SetDeInterlacing(bool flag) +void CIMXContext::SetFieldData(uint8_t fieldFmt) { - bool sav_deInt = m_deInterlacing; - m_deInterlacing = m_fbInterlaced ? false : flag; - // If deinterlacing configuration changes then fb has to be reconfigured - if (sav_deInt != m_deInterlacing) - { - m_checkConfigRequired = true; - Configure(); - } -} + if (m_bStop || !IsRunning()) + return; -void CIMXContext::SetBlitRects(const CRect &srcRect, const CRect &dstRect) -{ - m_srcRect = srcRect; - m_dstRect = dstRect; + // disable deinterlacing when not rendering fullscreen + if (!g_graphicsContext.IsFullScreenVideo()) + fieldFmt = 0; + + bool deint = !!m_currentFieldFmt; + m_currentFieldFmt = fieldFmt; + if (!!fieldFmt == deint) + return; + + CLog::Log(LOGDEBUG, "iMX : Deinterlacing parameters changed (%s)\n", !!fieldFmt ? "active" : "not active"); + m_bFbIsConfigured = false; + AdaptScreen(); } -bool CIMXContext::Blit(int page, CIMXBuffer *source_p, CIMXBuffer *source, bool topBottomFields) +bool CIMXContext::Blit(int page, CIMXBuffer *source_p, CIMXBuffer *source) { if (page < 0 || page >= m_fbPages) return false; IPUTask ipu; - PrepareTask(ipu, source_p, source, topBottomFields); + PrepareTask(ipu, source_p, source); return DoTask(ipu, page); } -bool CIMXContext::BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, bool topBottomFields, CRect *dest) +bool CIMXContext::BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, CRect *dest) { IPUTask ipu; - PrepareTask(ipu, source_p, source, topBottomFields, dest); + + PrepareTask(ipu, source_p, source, dest); return PushTask(ipu); } bool CIMXContext::PushCaptureTask(CIMXBuffer *source, CRect *dest) { IPUTask ipu; + m_CaptureDone = false; - PrepareTask(ipu, NULL, source, false, dest); + PrepareTask(ipu, NULL, source, dest); return PushTask(ipu); } bool CIMXContext::ShowPage(int page) { - int ret; - if (!m_fbHandle) return false; if (page < 0 || page >= m_fbPages) return false; + if (!m_bFbIsConfigured) return false; // Protect page swapping from screen capturing that does read the current // front buffer. This is actually not done very frequently so the lock // does not hurt. CSingleLock lk(m_pageSwapLock); - m_fbCurrentPage = page; m_fbVar.activate = FB_ACTIVATE_VBL; - m_fbVar.yoffset = (m_fbVar.yres+1)*page; - if ((ret = ioctl(m_fbHandle, FBIOPAN_DISPLAY, &m_fbVar)) < 0) - CLog::Log(LOGWARNING, "Panning failed: %s\n", strerror(errno)); - // Wait for sync - if (m_vsync) + m_fbVar.yoffset = (m_fbVar.yres + 0) * page; + if (ioctl(m_fbHandle, FBIOPAN_DISPLAY, &m_fbVar) < 0) { - if (ioctl(m_fbHandle, FBIO_WAITFORVSYNC, 0) < 0) - CLog::Log(LOGWARNING, "Vsync failed: %s\n", strerror(errno)); + CLog::Log(LOGWARNING, "Panning failed: %s\n", strerror(errno)); + return false; } + m_fbCurrentPage = page; + if (!m_vsync) + return true; + + // Wait for flip + if (ioctl(m_fbHandle, FBIO_WAITFORVSYNC, 0) < 0) + { + CLog::Log(LOGWARNING, "Vsync failed: %s\n", strerror(errno)); + return false; + } return true; } @@ -1766,17 +1748,18 @@ bool CIMXContext::PushTask(const IPUTask &task) if (!task.current) return false; - CSingleLock lk(m_monitor); - if (m_bStop) { m_inputNotEmpty.notifyAll(); return false; } - // If the input queue is full, wait for a free slot - while ((m_bufferedInput == m_input.size()) && !m_bStop) - m_inputNotFull.wait(lk); + { + CSingleLock lk(m_monitor); + // If the input queue is full, wait for a free slot + while ((m_bufferedInput == m_input.size()) && !m_bStop) + m_inputNotFull.wait(lk); + } if (m_bStop) { @@ -1788,10 +1771,13 @@ bool CIMXContext::PushTask(const IPUTask &task) if (task.previous) task.previous->Lock(); task.current->Lock(); - memcpy(&m_input[m_endInput], &task, sizeof(IPUTask)); - m_endInput = (m_endInput+1) % m_input.size(); - ++m_bufferedInput; - m_inputNotEmpty.notifyAll(); + { + CSingleLock lk(m_monitor); + memcpy(&m_input[m_endInput], &task, sizeof(IPUTask)); + m_endInput = (m_endInput+1) % m_input.size(); + ++m_bufferedInput; + m_inputNotEmpty.notifyAll(); + } return true; } @@ -1804,9 +1790,8 @@ void CIMXContext::WaitCapture() } void CIMXContext::PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *source, - bool topBottomFields, CRect *dest) + CRect *dest) { - Configure(); // Fill with zeros ipu.Zero(); ipu.previous = source_p; @@ -1852,10 +1837,10 @@ void CIMXContext::PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *so dstRect.y2 = m_fbHeight; } - iSrcRect.x1 = (int)srcRect.x1; - iSrcRect.y1 = (int)srcRect.y1; - iSrcRect.x2 = (int)srcRect.x2; - iSrcRect.y2 = (int)srcRect.y2; + iSrcRect.x1 = Align((int)srcRect.x1,8); + iSrcRect.y1 = Align((int)srcRect.y1,8); + iSrcRect.x2 = Align2((int)srcRect.x2,8); + iSrcRect.y2 = Align2((int)srcRect.y2,8); iDstRect.x1 = Align((int)dstRect.x1,8); iDstRect.y1 = Align((int)dstRect.y1,8); @@ -1887,7 +1872,7 @@ void CIMXContext::PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *so else { // Setup deinterlacing if enabled - if (m_deInterlacing) + if (m_currentFieldFmt) { ipu.task.input.deinterlace.enable = 1; /* @@ -1901,11 +1886,6 @@ void CIMXContext::PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *so */ ipu.task.input.deinterlace.motion = HIGH_MOTION; ipu.task.input.deinterlace.field_fmt = m_currentFieldFmt; - - if (topBottomFields) - ipu.task.input.deinterlace.field_fmt |= IPU_DEINTERLACE_FIELD_TOP; - else - ipu.task.input.deinterlace.field_fmt |= IPU_DEINTERLACE_FIELD_BOTTOM; } } } @@ -1993,6 +1973,9 @@ bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) case IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER: ipu.task.output.crop.h -= 8; break; + // deinterlacing setup changing, m_ipuHandle is closed + case -1: + return true; default: CLog::Log(LOGWARNING, "iMX : unhandled IPU check error: %d\n", ret); return false; @@ -2093,6 +2076,9 @@ bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) void CIMXContext::OnStartup() { + OpenDevices(); + + AdaptScreen(); g_Windowing.Register(this); CLog::Log(LOGNOTICE, "iMX : IPU thread started"); } @@ -2114,8 +2100,7 @@ void CIMXContext::StopThread(bool bWait /*= true*/) void CIMXContext::Process() { - bool ret, useBackBuffer; - int backBuffer; + bool ret; // open g2d here to ensure all g2d fucntions are called from the same thread if (m_g2dHandle == NULL) @@ -2129,32 +2114,32 @@ void CIMXContext::Process() while (!m_bStop) { + IPUTask *task; { CSingleLock lk(m_monitor); while (!m_bufferedInput && !m_bStop) m_inputNotEmpty.wait(lk); - if (m_bStop) break; - - useBackBuffer = m_vsync; - IPUTask &task = m_input[m_beginInput]; - backBuffer = useBackBuffer?1-m_fbCurrentPage:m_fbCurrentPage; + task = &m_input[m_beginInput]; + } + if (m_bStop) + break; - // Hack to detect we deal with capture buffer - if (task.task.output.width != 0) - useBackBuffer = false; - ret = DoTask(task, backBuffer); + ret = DoTask(*task, (1-m_fbCurrentPage) & m_vsync); - // Free resources - task.Done(); + // Free resources + task->Done(); + { + CSingleLock lk(m_monitor); m_beginInput = (m_beginInput+1) % m_input.size(); --m_bufferedInput; m_inputNotFull.notifyAll(); } // Show back buffer - if (useBackBuffer && ret) ShowPage(backBuffer); + if (task->task.output.width && ret) + ShowPage(1-m_fbCurrentPage); } // Mark all pending jobs as done diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h index 9f144c7..6ebc60e 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h @@ -95,25 +95,23 @@ public: CIMXContext(); ~CIMXContext(); - void RequireConfiguration() { m_checkConfigRequired = true; } bool AdaptScreen(); - bool Configure(); - bool Close(); + bool TaskRestart(); + bool CloseDevices(); + bool OpenDevices(); bool Blank(); bool Unblank(); bool SetVSync(bool enable); - bool IsValid() const { return m_checkConfigRequired == false; } + bool IsValid() const { return IsRunning() && m_bFbIsConfigured; } // Populates a CIMXBuffer with attributes of a page bool GetPageInfo(CIMXBuffer *info, int page); // Blitter configuration - void SetDeInterlacing(bool flag); - void SetDoubleRate(bool flag); + void SetFieldData(uint8_t fieldFmt); bool DoubleRate() const; - void SetInterpolatedFrame(bool flag); void SetBlitRects(const CRect &srcRect, const CRect &dstRect); @@ -121,14 +119,13 @@ public: // source_p (previous buffer) is required for de-interlacing // modes LOW_MOTION and MED_MOTION. bool Blit(int targetPage, CIMXBuffer *source_p, - CIMXBuffer *source, - bool topBottomFields = true); + CIMXBuffer *source); // Same as blit but runs in another thread and returns after the task has // been queued. BlitAsync renders always to the current backbuffer and // swaps the pages. bool BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, - bool topBottomFields = true, CRect *dest = NULL); + CRect *dest = NULL); // Shows a page vsynced bool ShowPage(int page); @@ -175,9 +172,12 @@ private: bool PushTask(const IPUTask &); void PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *source, - bool topBottomFields, CRect *dest = NULL); + CRect *dest = NULL); bool DoTask(IPUTask &ipu, int targetPage); + void Dispose(); + void MemMap(struct fb_fix_screeninfo *fb_fix = NULL); + virtual void OnStartup(); virtual void OnExit(); virtual void StopThread(bool bWait = true); @@ -198,14 +198,14 @@ private: uint8_t *m_fbVirtAddr; struct fb_var_screeninfo m_fbVar; int m_ipuHandle; - int m_currentFieldFmt; + uint8_t m_currentFieldFmt; bool m_vsync; - bool m_deInterlacing; CRect m_srcRect; CRect m_dstRect; CRectInt m_inputRect; CRectInt m_outputRect; CRectInt *m_pageCrops; + bool m_bFbIsConfigured; CCriticalSection m_pageSwapLock; TaskQueue m_input; @@ -218,7 +218,6 @@ private: void *m_g2dHandle; struct g2d_buf *m_bufferCapture; bool m_CaptureDone; - bool m_checkConfigRequired; static const int m_fbPages; std::string m_deviceName; @@ -356,3 +355,4 @@ protected: FILE *m_dump; #endif }; + -- 2.7.1 From 35b9799c9ca99776bfb8ff67da1e46fd7c0743f4 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 15 Aug 2015 22:08:38 +0200 Subject: [PATCH 091/250] DVDVideoCodecIMX: add frame SkipMode handling in decoder Upstream-commit: b6a6974d6b6f0977f56a4260699abc8d32b6d43f --- .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 23 +++++++++++++++++----- .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 2 ++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 793c449..a8b1f8a 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -413,6 +413,7 @@ CDVDVideoCodecIMX::CDVDVideoCodecIMX() m_currentBuffer = NULL; m_extraMem = NULL; m_vpuFrameBufferNum = 0; + m_dropRequest = false; m_dropState = false; m_convert_bitstream = false; m_frameCounter = 0; @@ -683,6 +684,14 @@ void CDVDVideoCodecIMX::Dispose() return; } +inline +void CDVDVideoCodecIMX::SetSkipMode() +{ + VpuDecSkipMode skip = m_dropRequest ? VPU_DEC_SKIPB : VPU_DEC_SKIPNONE; + if (VPU_DEC_RET_SUCCESS != VPU_DecConfig(m_vpuHandle, VPU_DEC_CONF_SKIPMODE, &skip)) + CLog::Log(LOGERROR, "%s - iMX VPU set skip mode failed.\n", __FUNCTION__); +} + int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) { VpuDecFrameLengthInfo frameLengthInfo; @@ -786,6 +795,8 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) if (m_frameReported) m_bytesToBeConsumed += inData.nSize; + SetSkipMode(); + ret = VPU_DecDecodeBuf(m_vpuHandle, &inData, &decRet); #ifdef IMX_PROFILE_BUFFERS unsigned long long dec_single_call = XbmcThreads::SystemClockMillis()-before_dec; @@ -837,7 +848,7 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) } } //VPU_DEC_INIT_OK - if (decRet & VPU_DEC_ONE_FRM_CONSUMED) + if (decRet & VPU_DEC_ONE_FRM_CONSUMED && !(decRet & VPU_DEC_OUTPUT_DROPPED)) { ret = VPU_DecGetConsumedFrameInfo(m_vpuHandle, &frameLengthInfo); if (ret != VPU_DEC_RET_SUCCESS) @@ -962,6 +973,7 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s - Frame dropped.\n", __FUNCTION__); + m_dropState = true; } else if (decRet & VPU_DEC_NO_ENOUGH_BUF) { @@ -1088,9 +1100,10 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED; if (m_dropState) + { pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED; - else - pDvdVideoPicture->iFlags &= ~DVP_FLAG_DROPPED; + m_dropState = false; + } if (m_initInfo.nInterlace) { @@ -1129,9 +1142,9 @@ void CDVDVideoCodecIMX::SetDropState(bool bDrop) // and avoid artefacts... // (Of course these frames won't be rendered but only decoded) - if (m_dropState != bDrop) + if (m_dropRequest != bDrop) { - m_dropState = bDrop; + m_dropRequest = bDrop; #ifdef TRACE_FRAMES CLog::Log(LOGDEBUG, "%s : %d\n", __FUNCTION__, bDrop); #endif diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h index 6ebc60e..2bb5f65 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h @@ -307,6 +307,7 @@ public: virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options); virtual void Dispose(); virtual int Decode(BYTE *pData, int iSize, double dts, double pts); + virtual void SetSkipMode(); virtual void Reset(); virtual bool ClearPicture(DVDVideoPicture *pDvdVideoPicture); virtual bool GetPicture(DVDVideoPicture *pDvdVideoPicture); @@ -335,6 +336,7 @@ protected: CDecMemInfo m_decMemInfo; // VPU dedicated memory description VpuDecHandle m_vpuHandle; // Handle for VPU library calls VpuDecInitInfo m_initInfo; // Initial info returned from VPU at decoding start + bool m_dropRequest; // Current drop state bool m_dropState; // Current drop state int m_vpuFrameBufferNum; // Total number of allocated frame buffers VpuFrameBuffer *m_vpuFrameBuffers; // Table of VPU frame buffers description -- 2.7.1 From 0e841dba3a2e0ef9d328ba30428e055fbedb1962 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 18 Aug 2015 03:04:23 +0200 Subject: [PATCH 092/250] EGL: move EDID parsing to a separate class. Update IMX and RPI. Upstream-commit: f0dd422d1de1d34c1442b4a8ba3d4cfc0004e5f7 --- xbmc/windowing/egl/EGLEdid.cpp | 75 +++++++++++++++++++++++++ xbmc/windowing/egl/EGLEdid.h | 52 +++++++++++++++++ xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 44 ++------------- xbmc/windowing/egl/EGLNativeTypeIMX.h | 17 +----- xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 48 ++++++++++++++-- xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h | 6 +- xbmc/windowing/egl/Makefile.in | 1 + 7 files changed, 184 insertions(+), 59 deletions(-) create mode 100644 xbmc/windowing/egl/EGLEdid.cpp create mode 100644 xbmc/windowing/egl/EGLEdid.h diff --git a/xbmc/windowing/egl/EGLEdid.cpp b/xbmc/windowing/egl/EGLEdid.cpp new file mode 100644 index 0000000..babc506 --- /dev/null +++ b/xbmc/windowing/egl/EGLEdid.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2011-2013 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "system.h" +#include "EGLEdid.h" +#include "utils/log.h" + +CEGLEdid::CEGLEdid() + : m_fSar(0.0f) +{ +} + +CEGLEdid::~CEGLEdid() +{ +} + +float CEGLEdid::ValidateSAR(struct dt_dim *dtm, bool mb) +{ + int Height = dtm->Height | (mb ? (dtm->msbits & 0x0f) << 8 : 0); + if (Height < 1) + return .0f; + + int Width = dtm->Width | (mb ? (dtm->msbits & 0xf0) << 4 : 0); + float t_sar = (float) Width / Height; + + if (t_sar < 0.33 || t_sar > 3.00) + t_sar = .0f; + else + CLog::Log(LOGINFO, "%s: Screen SAR: %.3f (from detailed: %s, %dx%d)",__FUNCTION__, t_sar, mb ? "yes" : "no", Width, Height); + + return t_sar; +} + +void CEGLEdid::CalcSAR() +{ + m_fSar = .0f; + ReadEdidData(); + + // enumerate through (max four) detailed timing info blocks + // specs and lookup WxH [mm / in]. W and H are in 3 bytes, + // where 1st = W, 2nd = H, 3rd byte is 4bit/4bit. + for (int i = EDID_DTM_START; i < 126 && m_fSar == 0; i += 18) + m_fSar = ValidateSAR((struct dt_dim *)(m_edid +i +EDID_DTM_OFFSET_DIMENSION), true); + + // fallback - info related to 'Basic display parameters.' is at offset 0x14-0x18. + // where W is 2nd byte, H 3rd. + if (m_fSar == 0) + m_fSar = ValidateSAR((struct dt_dim *)(m_edid +EDID_STRUCT_DISPLAY +1)); + + // if m_sar != 0, final SAR is usefull + // if it is 0, EDID info was missing or calculated + // SAR value wasn't sane + if (m_fSar == 0) + { + CLog::Log(LOGWARNING, "%s: Screen SAR - not usable info",__FUNCTION__); + m_fSar = 1.0f; + } +} diff --git a/xbmc/windowing/egl/EGLEdid.h b/xbmc/windowing/egl/EGLEdid.h new file mode 100644 index 0000000..5c10e44 --- /dev/null +++ b/xbmc/windowing/egl/EGLEdid.h @@ -0,0 +1,52 @@ +#pragma once + +/* + * Copyright (C) 2011-2013 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include + +#define EDID_STRUCT_DISPLAY 0x14 +#define EDID_DTM_START 0x36 +#define EDID_DTM_OFFSET_DIMENSION 0x0c +#define EDID_MAXSIZE 512 + +class CEGLEdid +{ + struct dt_dim { + uint8_t Width; + uint8_t Height; + uint8_t msbits; + }; + +public: + CEGLEdid(); + virtual ~CEGLEdid(); + + virtual void ReadEdidData() = 0; + + float GetSAR() const { return m_fSar; } + void CalcSAR(); + +protected: + float ValidateSAR(struct dt_dim *dtm, bool mb = false); + + float m_fSar; + uint8_t m_edid[EDID_MAXSIZE]; +}; diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 8defe54..426f774 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -47,8 +47,7 @@ using namespace PERIPHERALS; CEGLNativeTypeIMX::CEGLNativeTypeIMX() #ifdef HAS_IMXVPU - : m_sar(0.0f) - , m_display(NULL) + : m_display(NULL) , m_window(NULL) #endif { @@ -341,7 +340,7 @@ bool CEGLNativeTypeIMX::FindMatchingResolution(const RESOLUTION_INFO &res, const bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutions) { #ifdef HAS_IMXVPU - GetMonitorSAR(); + CalcSAR(); if (m_readonly) return false; @@ -407,24 +406,7 @@ bool CEGLNativeTypeIMX::ShowWindow(bool show) } #ifdef HAS_IMXVPU -float CEGLNativeTypeIMX::ValidateSAR(struct dt_dim *dtm, bool mb) -{ - int Height = dtm->Height | (mb ? (dtm->msbits & 0x0f) << 8 : 0); - if (Height < 1) - return .0f; - - int Width = dtm->Width | (mb ? (dtm->msbits & 0xf0) << 4 : 0); - float t_sar = (float) Width / Height; - - if (t_sar < 0.33 || t_sar > 3.00) - t_sar = .0f; - else - CLog::Log(LOGDEBUG, "%s: Screen SAR: %.3f (from detailed: %s, %dx%d)",__FUNCTION__, t_sar, mb ? "yes" : "no", Width, Height); - - return t_sar; -} - -void CEGLNativeTypeIMX::GetMonitorSAR() +void CEGLNativeTypeIMX::ReadEdidData() { FILE *f_edid; char *str = NULL; @@ -434,7 +416,6 @@ void CEGLNativeTypeIMX::GetMonitorSAR() // kernels <= 3.18 use ./soc0/soc.1 in official imx kernel // kernels > 3.18 use ./soc0/soc - m_sar = 0; f_edid = fopen("/sys/devices/soc0/soc/20e0000.hdmi_video/edid", "r"); if(!f_edid) f_edid = fopen("/sys/devices/soc0/soc.1/20e0000.hdmi_video/edid", "r"); @@ -470,23 +451,6 @@ void CEGLNativeTypeIMX::GetMonitorSAR() str = NULL; } fclose(f_edid); - - // enumerate through (max four) detailed timing info blocks - // specs and lookup WxH [mm / in]. W and H are in 3 bytes, - // where 1st = W, 2nd = H, 3rd byte is 4bit/4bit. - for (int i = EDID_DTM_START; i < 126 && m_sar == 0; i += 18) - m_sar = ValidateSAR((struct dt_dim *)(m_edid +i +EDID_DTM_OFFSET_DIMENSION), true); - - // fallback - info related to 'Basic display parameters.' is at offset 0x14-0x18. - // where W is 2nd byte, H 3rd. - if (m_sar == 0) - m_sar = ValidateSAR((struct dt_dim *)(m_edid +EDID_STRUCT_DISPLAY +1)); - - // if m_sar != 0, final SAR is usefull - // if it is 0, EDID info was missing or calculated - // SAR value wasn't sane - if (m_sar == 0) - CLog::Log(LOGDEBUG, "%s: Screen SAR - not usable info",__FUNCTION__); } bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) const @@ -540,7 +504,7 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->bFullScreen = true; res->iSubtitles = (int)(0.965 * res->iHeight); - res->fPixelRatio *= !m_sar ? 1.0f : (float)m_sar / res->iScreenWidth * res->iScreenHeight; + res->fPixelRatio *= (float)GetSAR() / res->iScreenWidth * res->iScreenHeight; res->strMode = StringUtils::Format("%4sx%4s @ %.3f%s - Full Screen (%.3f) %s", StringUtils::Format("%d", res->iScreenWidth).c_str(), StringUtils::Format("%d", res->iScreenHeight).c_str(), res->fRefreshRate, res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : " ", res->fPixelRatio, diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.h b/xbmc/windowing/egl/EGLNativeTypeIMX.h index 940196f..d7976f4 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.h +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.h @@ -24,18 +24,10 @@ #include #include "EGLNativeType.h" -#define EDID_STRUCT_DISPLAY 0x14 -#define EDID_DTM_START 0x36 -#define EDID_DTM_OFFSET_DIMENSION 0x0c +#include "EGLEdid.h" -class CEGLNativeTypeIMX : public CEGLNativeType +class CEGLNativeTypeIMX : public CEGLNativeType, private CEGLEdid { - struct dt_dim { - uint8_t Width; - uint8_t Height; - uint8_t msbits; - }; - public: CEGLNativeTypeIMX(); virtual ~CEGLNativeTypeIMX(); @@ -59,20 +51,17 @@ public: virtual bool GetPreferredResolution(RESOLUTION_INFO *res) const; virtual bool ShowWindow(bool show = true); + virtual void ReadEdidData(); #ifdef HAS_IMXVPU protected: bool m_readonly; bool m_show; - float m_sar; RESOLUTION_INFO m_init; bool ModeToResolution(std::string mode, RESOLUTION_INFO *res) const; bool FindMatchingResolution(const RESOLUTION_INFO &res, const std::vector &resolutions); - void GetMonitorSAR(); - float ValidateSAR(struct dt_dim *dtm, bool mb = false); EGLNativeDisplayType m_display; EGLNativeWindowType m_window; - uint8_t m_edid[512]; #endif }; diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp index cdf2620..7c4b1a3 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp @@ -220,7 +220,7 @@ bool CEGLNativeTypeRaspberryPI::GetNativeResolution(RESOLUTION_INFO *res) const res->iScreenWidth = tv_state.display.hdmi.width; res->iScreenHeight= tv_state.display.hdmi.height; res->dwFlags = MAKEFLAGS(tv_state.display.hdmi.group, tv_state.display.hdmi.mode, tv_state.display.hdmi.scan_mode); - res->fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)res->iScreenWidth / (float)res->iScreenHeight); + res->fPixelRatio = (float)GetSAR() / ((float)res->iScreenWidth / (float)res->iScreenHeight); // Also add 3D flags if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_SBS_HALF) { @@ -247,7 +247,19 @@ bool CEGLNativeTypeRaspberryPI::GetNativeResolution(RESOLUTION_INFO *res) const res->iScreenHeight= tv_state.display.sdtv.height; res->dwFlags = MAKEFLAGS(HDMI_RES_GROUP_INVALID, tv_state.display.sdtv.mode, 1); res->fRefreshRate = (float)tv_state.display.sdtv.frame_rate; - res->fPixelRatio = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)res->iScreenWidth / (float)res->iScreenHeight); + res->fPixelRatio = (float)GetSAR() / ((float)res->iScreenWidth / (float)res->iScreenHeight); + } + else if ((tv_state.state & VC_LCD_ATTACHED_DEFAULT) != 0) // lcd + { + res->iScreen = 0; + res->bFullScreen = true; + res->iWidth = tv_state.display.sdtv.width; + res->iHeight = tv_state.display.sdtv.height; + res->iScreenWidth = tv_state.display.sdtv.width; + res->iScreenHeight= tv_state.display.sdtv.height; + res->dwFlags = MAKEFLAGS(HDMI_RES_GROUP_INVALID, 0, 0); + res->fRefreshRate = (float)tv_state.display.sdtv.frame_rate; + res->fPixelRatio = (float)GetSAR() / ((float)res->iScreenWidth / (float)res->iScreenHeight); } DLOG("CEGLNativeTypeRaspberryPI::GetNativeResolution %s\n", res->strMode.c_str()); @@ -533,6 +545,8 @@ bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &r if(!m_DllBcmHost) return false; + CalcSAR(); + /* read initial desktop resolution before probe resolutions. * probing will replace the desktop resolution when it finds the same one. * we raplace it because probing will generate more detailed @@ -637,7 +651,7 @@ void CEGLNativeTypeRaspberryPI::GetSupportedModes(HDMI_RES_GROUP_T group, std::v res.iHeight = tv->height; res.iScreenWidth = tv->width; res.iScreenHeight = tv->height; - res.fPixelRatio = get_display_aspect_ratio((HDMI_ASPECT_T)tv->aspect_ratio) / ((float)res.iScreenWidth / (float)res.iScreenHeight); + res.fPixelRatio = (float)GetSAR() / ((float)res.iScreenWidth / (float)res.iScreenHeight); res.iSubtitles = (int)(0.965 * res.iHeight); if (!m_desktopRes.dwFlags && prefer_group == group && prefer_mode == tv->code) @@ -728,5 +742,31 @@ void CEGLNativeTypeRaspberryPI::CallbackTvServiceCallback(void *userdata, uint32 callback->TvServiceCallback(reason, param1, param2); } -#endif +void CEGLNativeTypeRaspberryPI::ReadEdidData() +{ + uint8_t buffer[128]; + size_t offset = 0; + int i, extensions = 0; + int siz = vc_tv_hdmi_ddc_read(offset, sizeof(buffer), buffer); + offset += sizeof(buffer); + + /* First block always exist */ + if (siz == sizeof(buffer)) + { + memcpy(&m_edid, &buffer, sizeof(buffer)); + extensions = buffer[0x7e]; /* This tells you how many more blocks to read */ + + for (i = 0; i < extensions && i < EDID_MAXSIZE - sizeof(buffer); i++, offset += sizeof(buffer)) + { + siz = vc_tv_hdmi_ddc_read(offset, sizeof(buffer), buffer); + + if (siz != sizeof(buffer)) + break; + + memcpy((uint8_t *)(&m_edid + offset), &buffer, sizeof(buffer)); + } + } +} + +#endif diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h index ba6d9d2..e72ba4e 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h @@ -28,10 +28,12 @@ #include "peripherals/Peripherals.h" #include "threads/Thread.h" +#include "EGLEdid.h" + using namespace PERIPHERALS; class DllBcmHost; -class CEGLNativeTypeRaspberryPI : public CEGLNativeType +class CEGLNativeTypeRaspberryPI : public CEGLNativeType, private CEGLEdid { public: CEGLNativeTypeRaspberryPI(); @@ -56,6 +58,8 @@ public: virtual bool GetPreferredResolution(RESOLUTION_INFO *res) const; virtual bool ShowWindow(bool show); + virtual void ReadEdidData(); + #if defined(TARGET_RASPBERRY_PI) private: DllBcmHost *m_DllBcmHost; diff --git a/xbmc/windowing/egl/Makefile.in b/xbmc/windowing/egl/Makefile.in index 32fb168..7854ca9 100644 --- a/xbmc/windowing/egl/Makefile.in +++ b/xbmc/windowing/egl/Makefile.in @@ -14,6 +14,7 @@ ifeq (@USE_IMXVPU@,1) SRCS+= EGLNativeTypeIMX.cpp endif SRCS+= EGLWrapper.cpp +SRCS+= EGLEdid.cpp # Wayland specific detail ifeq (@USE_WAYLAND@,1) -- 2.7.1 From aa15a90b50217a2e2cb637cbf7419d25e884d6d2 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 24 Aug 2015 04:46:09 +0200 Subject: [PATCH 093/250] Revert "[filesystem/afp] - remove AFP implementation" Upstream-commit: 74ddf8cdc1c81c4f83583e86a92f5c06abdd434c This reverts commit e19e4b2466d8c1c92dd38d8b728522131a4e16dc. Conflicts: Kodi.xcodeproj/project.pbxproj configure.in project/VS2010Express/XBMC.vcxproj project/VS2010Express/XBMC.vcxproj.filters xbmc/filesystem/DirectoryFactory.cpp xbmc/filesystem/FileFactory.cpp xbmc/network/GUIDialogNetworkSetup.cpp --- Kodi.xcodeproj/project.pbxproj | 30 +- .../resource.language.en_gb/resources/strings.po | 5 +- configure.ac | 35 + lib/afpfs-ng/01-gcrypt.patch | 26 + lib/afpfs-ng/02-pointer.patch | 280 ++ lib/afpfs-ng/04-boxee1.patch | 25 + lib/afpfs-ng/05-boxee2.patch | 89 + lib/afpfs-ng/06-boxee3.patch | 141 + lib/afpfs-ng/07-boxee4.patch | 27 + lib/afpfs-ng/08-boxee5.patch | 11 + lib/afpfs-ng/10-fix-errno.patch | 23 + lib/afpfs-ng/11-fix-stat.patch | 11 + lib/afpfs-ng/12-fix-even-more-pointers.patch | 83 + lib/afpfs-ng/Makefile | 68 + lib/afpfs-ng/fix_afpfs-ng_includes.patch | 3082 +++++++++++++++++++ project/VS2010Express/XBMC.vcxproj | 125 +- project/VS2010Express/XBMC.vcxproj.filters | 266 +- tools/android/packaging/Makefile.in | 1 + tools/depends/target/Makefile | 3 +- tools/depends/target/afpfs-ng/01-gcrypt.patch | 26 + tools/depends/target/afpfs-ng/02-pointer.patch | 280 ++ tools/depends/target/afpfs-ng/04-boxee1.patch | 25 + tools/depends/target/afpfs-ng/05-boxee2.patch | 89 + tools/depends/target/afpfs-ng/06-boxee3.patch | 141 + tools/depends/target/afpfs-ng/07-boxee4.patch | 27 + tools/depends/target/afpfs-ng/08-boxee5.patch | 11 + tools/depends/target/afpfs-ng/10-fix-errno.patch | 23 + tools/depends/target/afpfs-ng/11-fix-stat.patch | 11 + tools/depends/target/afpfs-ng/Makefile | 62 + tools/depends/target/afpfs-ng/android.patch | 70 + .../target/afpfs-ng/fix_afpfs-ng_includes.patch | 3092 ++++++++++++++++++++ tools/depends/target/config-binaddons.site.in | 2 +- tools/depends/target/config.site.in | 2 +- xbmc/Application.cpp | 13 +- xbmc/DllPaths_generated.h.in | 1 + xbmc/DllPaths_generated_android.h.in | 1 + xbmc/FileItem.cpp | 6 + xbmc/FileItem.h | 1 + xbmc/Util.cpp | 12 +- xbmc/cores/dvdplayer/Edl.cpp | 3 +- xbmc/filesystem/AFPDirectory.cpp | 324 ++ xbmc/filesystem/AFPDirectory.h | 47 + xbmc/filesystem/AFPFile.cpp | 728 +++++ xbmc/filesystem/AFPFile.h | 134 + xbmc/filesystem/DirectoryFactory.cpp | 6 + xbmc/filesystem/DllLibAfp.h | 214 ++ xbmc/filesystem/FileFactory.cpp | 6 + xbmc/filesystem/Makefile.in | 5 + xbmc/filesystem/ZeroconfDirectory.cpp | 4 + xbmc/network/GUIDialogNetworkSetup.cpp | 10 +- xbmc/network/GUIDialogNetworkSetup.h | 3 +- xbmc/network/ZeroconfBrowser.cpp | 3 + xbmc/system.h | 4 + xbmc/utils/URIUtils.cpp | 16 + xbmc/utils/URIUtils.h | 1 + xbmc/utils/test/TestURIUtils.cpp | 6 + 56 files changed, 9678 insertions(+), 62 deletions(-) create mode 100644 lib/afpfs-ng/01-gcrypt.patch create mode 100644 lib/afpfs-ng/02-pointer.patch create mode 100644 lib/afpfs-ng/04-boxee1.patch create mode 100644 lib/afpfs-ng/05-boxee2.patch create mode 100644 lib/afpfs-ng/06-boxee3.patch create mode 100644 lib/afpfs-ng/07-boxee4.patch create mode 100644 lib/afpfs-ng/08-boxee5.patch create mode 100644 lib/afpfs-ng/10-fix-errno.patch create mode 100644 lib/afpfs-ng/11-fix-stat.patch create mode 100644 lib/afpfs-ng/12-fix-even-more-pointers.patch create mode 100644 lib/afpfs-ng/Makefile create mode 100644 lib/afpfs-ng/fix_afpfs-ng_includes.patch create mode 100644 tools/depends/target/afpfs-ng/01-gcrypt.patch create mode 100644 tools/depends/target/afpfs-ng/02-pointer.patch create mode 100644 tools/depends/target/afpfs-ng/04-boxee1.patch create mode 100644 tools/depends/target/afpfs-ng/05-boxee2.patch create mode 100644 tools/depends/target/afpfs-ng/06-boxee3.patch create mode 100644 tools/depends/target/afpfs-ng/07-boxee4.patch create mode 100644 tools/depends/target/afpfs-ng/08-boxee5.patch create mode 100644 tools/depends/target/afpfs-ng/10-fix-errno.patch create mode 100644 tools/depends/target/afpfs-ng/11-fix-stat.patch create mode 100644 tools/depends/target/afpfs-ng/Makefile create mode 100644 tools/depends/target/afpfs-ng/android.patch create mode 100644 tools/depends/target/afpfs-ng/fix_afpfs-ng_includes.patch create mode 100644 xbmc/filesystem/AFPDirectory.cpp create mode 100644 xbmc/filesystem/AFPDirectory.h create mode 100644 xbmc/filesystem/AFPFile.cpp create mode 100644 xbmc/filesystem/AFPFile.h create mode 100644 xbmc/filesystem/DllLibAfp.h diff --git a/Kodi.xcodeproj/project.pbxproj b/Kodi.xcodeproj/project.pbxproj index 8fb3ba7..34ec704 100644 --- a/Kodi.xcodeproj/project.pbxproj +++ b/Kodi.xcodeproj/project.pbxproj @@ -709,6 +709,7 @@ DF2401271B41A26F001E02DA /* ImageResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2401241B41A26E001E02DA /* ImageResource.cpp */; }; DF2863B719918B07008994AB /* Gif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2863B519918B07008994AB /* Gif.cpp */; }; DF2863B819918B07008994AB /* Gif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF2863B519918B07008994AB /* Gif.cpp */; }; + DF24A6B41406C7C500C7721E /* AFPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF24A6B01406C7C500C7721E /* AFPDirectory.cpp */; }; DF28DF4D17B8379E0077F41A /* ProfilesOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF28DF4B17B8379E0077F41A /* ProfilesOperations.cpp */; }; DF28DF4E17B8379E0077F41A /* ProfilesOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF28DF4B17B8379E0077F41A /* ProfilesOperations.cpp */; }; DF28EDA2170E1A11005FA9D2 /* GUIDialogLockSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF28ED94170E1A11005FA9D2 /* GUIDialogLockSettings.cpp */; }; @@ -803,6 +804,7 @@ DF8990211709BB5400B35C21 /* ViewStateSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF89901F1709BB5400B35C21 /* ViewStateSettings.cpp */; }; DF923E5D1A11536A008CDB0C /* DataCacheCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF923E5B1A11536A008CDB0C /* DataCacheCore.cpp */; }; DF923E5E1A11536A008CDB0C /* DataCacheCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF923E5B1A11536A008CDB0C /* DataCacheCore.cpp */; }; + DF93D6991444A8B1007C6459 /* AFPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6631444A8B0007C6459 /* AFPFile.cpp */; }; DF93D69A1444A8B1007C6459 /* DirectoryCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6651444A8B0007C6459 /* DirectoryCache.cpp */; }; DF93D69B1444A8B1007C6459 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6671444A8B0007C6459 /* FileCache.cpp */; }; DF93D69C1444A8B1007C6459 /* CDDAFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6691444A8B0007C6459 /* CDDAFile.cpp */; }; @@ -916,6 +918,8 @@ DFEF0BC1180ADEDA00AEAED1 /* SmartPlaylistFileItemListModifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEF0BBF180ADEDA00AEAED1 /* SmartPlaylistFileItemListModifier.cpp */; }; DFEF0BC2180ADEDA00AEAED1 /* SmartPlaylistFileItemListModifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEF0BBF180ADEDA00AEAED1 /* SmartPlaylistFileItemListModifier.cpp */; }; DFF0EBB7175281E1002DA3A4 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E49910EA174E54C900741B6D /* CoreAudio.framework */; }; + DFF0F1E717528350002DA3A4 /* AFPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF24A6B01406C7C500C7721E /* AFPDirectory.cpp */; }; + DFF0F1E817528350002DA3A4 /* AFPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6631444A8B0007C6459 /* AFPFile.cpp */; }; DFFA440119104C1300C3923B /* AppIcon29x29.png in Resources */ = {isa = PBXBuildFile; fileRef = DFFA43D619104BFA00C3923B /* AppIcon29x29.png */; }; DFFA440219104C1300C3923B /* AppIcon29x29@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DFFA43D719104BFA00C3923B /* AppIcon29x29@2x.png */; }; DFFA440319104C1300C3923B /* AppIcon40x40.png in Resources */ = {isa = PBXBuildFile; fileRef = DFFA43D819104BFA00C3923B /* AppIcon40x40.png */; }; @@ -1482,6 +1486,9 @@ E499124D174E5D7E00741B6D /* GUIDialogVolumeBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E17EA0D25F9FA00618676 /* GUIDialogVolumeBar.cpp */; }; E499124E174E5D7E00741B6D /* GUIDialogYesNo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E17EC0D25F9FA00618676 /* GUIDialogYesNo.cpp */; }; E499124F174E5D8F00741B6D /* AddonsDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A7B42B113CBB950059D6AA /* AddonsDirectory.cpp */; }; + E4991250174E5D8F00741B6D /* AFPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF24A6B01406C7C500C7721E /* AFPDirectory.cpp */; }; + E4991251174E5D8F00741B6D /* AFPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6631444A8B0007C6459 /* AFPFile.cpp */; }; + E4991252174E5D8F00741B6D /* ASAPFileDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 88ACB0190DCF40800083CFDF /* ASAPFileDirectory.cpp */; }; E4991253174E5D8F00741B6D /* BlurayDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5ED8D6A1551F91400842059 /* BlurayDirectory.cpp */; }; E4991254174E5D8F00741B6D /* CacheStrategy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16990D25F9FA00618676 /* CacheStrategy.cpp */; }; E4991255174E5D8F00741B6D /* CDDADirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E169B0D25F9FA00618676 /* CDDADirectory.cpp */; }; @@ -3496,11 +3503,8 @@ DF2345DE15FA639500A934F6 /* UPnPRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPnPRenderer.h; sourceTree = ""; }; DF2345DF15FA639500A934F6 /* UPnPServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UPnPServer.cpp; sourceTree = ""; }; DF2345E015FA639500A934F6 /* UPnPServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPnPServer.h; sourceTree = ""; }; - DF2401241B41A26E001E02DA /* ImageResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageResource.cpp; sourceTree = ""; }; - DF2401251B41A26E001E02DA /* ImageResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageResource.h; sourceTree = ""; }; - DF2863B419918B07008994AB /* DllLibGif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DllLibGif.h; sourceTree = ""; }; - DF2863B519918B07008994AB /* Gif.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Gif.cpp; sourceTree = ""; }; - DF2863B619918B07008994AB /* Gif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Gif.h; sourceTree = ""; }; + DF24A6B01406C7C500C7721E /* AFPDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AFPDirectory.cpp; sourceTree = ""; }; + DF24A6B11406C7C500C7721E /* AFPDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFPDirectory.h; sourceTree = ""; }; DF28DF4B17B8379E0077F41A /* ProfilesOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProfilesOperations.cpp; sourceTree = ""; }; DF28DF4C17B8379E0077F41A /* ProfilesOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfilesOperations.h; sourceTree = ""; }; DF28ED94170E1A11005FA9D2 /* GUIDialogLockSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogLockSettings.cpp; sourceTree = ""; }; @@ -3631,6 +3635,8 @@ DF8990201709BB5400B35C21 /* ViewStateSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewStateSettings.h; sourceTree = ""; }; DF923E5B1A11536A008CDB0C /* DataCacheCore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataCacheCore.cpp; sourceTree = ""; }; DF923E5C1A11536A008CDB0C /* DataCacheCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataCacheCore.h; sourceTree = ""; }; + DF93D6631444A8B0007C6459 /* AFPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AFPFile.cpp; sourceTree = ""; }; + DF93D6641444A8B0007C6459 /* AFPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFPFile.h; sourceTree = ""; }; DF93D6651444A8B0007C6459 /* DirectoryCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryCache.cpp; sourceTree = ""; }; DF93D6661444A8B0007C6459 /* DirectoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryCache.h; sourceTree = ""; }; DF93D6671444A8B0007C6459 /* FileCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCache.cpp; sourceTree = ""; }; @@ -7790,6 +7796,12 @@ E38E175F0D25F9FA00618676 /* VideoDatabaseDirectory */, F5A7B42B113CBB950059D6AA /* AddonsDirectory.cpp */, F5A7B42A113CBB950059D6AA /* AddonsDirectory.h */, + DF24A6B01406C7C500C7721E /* AFPDirectory.cpp */, + DF24A6B11406C7C500C7721E /* AFPDirectory.h */, + DF93D6631444A8B0007C6459 /* AFPFile.cpp */, + DF93D6641444A8B0007C6459 /* AFPFile.h */, + 88ACB0190DCF40800083CFDF /* ASAPFileDirectory.cpp */, + 88ACB01A0DCF40800083CFDF /* ASAPFileDirectory.h */, F5ED8D6A1551F91400842059 /* BlurayDirectory.cpp */, F5ED8D6B1551F91400842059 /* BlurayDirectory.h */, B5101B5719DFF8DD00294D1E /* BlurayFile.cpp */, @@ -9747,7 +9759,7 @@ DF34892A13FD9C780026A711 /* AirPlayServer.cpp in Sources */, DF34898213FDAAF60026A711 /* HttpParser.cpp in Sources */, 18968DC814155D7C005BA742 /* ApplicationOperations.cpp in Sources */, - DF0E4AD41AD5986F00A75430 /* GUIDialogPVRRadioRDSInfo.cpp in Sources */, + DF24A6B41406C7C500C7721E /* AFPDirectory.cpp in Sources */, 32C631281423A90F00F18420 /* JpegIO.cpp in Sources */, DF448457140048A60069344B /* AirTunesServer.cpp in Sources */, DF44845E140048C80069344B /* PipesManager.cpp in Sources */, @@ -9783,6 +9795,7 @@ DFCA6ACA152245CD000BFAAE /* HTTPWebinterfaceHandler.cpp in Sources */, 42E2E1C91B53F74D005C7E4E /* VideoLibraryRefreshingJob.cpp in Sources */, DFCA6ACB152245CD000BFAAE /* IHTTPRequestHandler.cpp in Sources */, + DF93D6991444A8B1007C6459 /* AFPFile.cpp in Sources */, DF93D69A1444A8B1007C6459 /* DirectoryCache.cpp in Sources */, DF93D69B1444A8B1007C6459 /* FileCache.cpp in Sources */, 3994427A1A8DD920006C39E9 /* VideoLibraryScanningJob.cpp in Sources */, @@ -10187,6 +10200,8 @@ B179BD6B1AD8EA7B00EA8D49 /* InputCodingTableBaiduPY.cpp in Sources */, B179BD6E1AD8EA7B00EA8D49 /* InputCodingTableBasePY.cpp in Sources */, B179BD711AD8EA7B00EA8D49 /* InputCodingTableFactory.cpp in Sources */, + DFF0F1E717528350002DA3A4 /* AFPDirectory.cpp in Sources */, + DFF0F1E817528350002DA3A4 /* AFPFile.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -10432,6 +10447,9 @@ E499124D174E5D7E00741B6D /* GUIDialogVolumeBar.cpp in Sources */, E499124E174E5D7E00741B6D /* GUIDialogYesNo.cpp in Sources */, E499124F174E5D8F00741B6D /* AddonsDirectory.cpp in Sources */, + E4991250174E5D8F00741B6D /* AFPDirectory.cpp in Sources */, + E4991251174E5D8F00741B6D /* AFPFile.cpp in Sources */, + E4991252174E5D8F00741B6D /* ASAPFileDirectory.cpp in Sources */, E4991253174E5D8F00741B6D /* BlurayDirectory.cpp in Sources */, E4991254174E5D8F00741B6D /* CacheStrategy.cpp in Sources */, E4991255174E5D8F00741B6D /* CDDADirectory.cpp in Sources */, diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index b97db75..a496be8 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -11224,7 +11224,10 @@ msgctxt "#20260" msgid "Secure Shell (SSH / SFTP)" msgstr "" -#empty string with id 20261 +#: xbmc/network/GUIDialogNetworkSetup.cpp +msgctxt "#20261" +msgid "Apple Filing Protocol (AFP)" +msgstr "" #: xbmc/storage/MediaManager.cpp msgctxt "#20262" diff --git a/configure.ac b/configure.ac index 29b799c..4414d8d 100644 --- a/configure.ac +++ b/configure.ac @@ -202,6 +202,8 @@ libnfs_not_found="== Could not find libnfs. NFS client support disabled. ==" libnfs_disabled="== NFS support disabled. ==" libgif_not_found="== Could not find libgif. libgif support disabled. ==" libgif_disabled="== libgif support disabled. ==" +libafpclient_not_found="== Could not find libafpclient. AFP client support disabled. ==" +libafpclient_disabled="== AFP support disabled. ==" libshairplay_not_found="== Could not find libshairplay. ==" samba_disabled="== SAMBA support disabled. ==" libplist_not_found="== Could not find libplist. AirPlay support disabled. ==" @@ -380,6 +382,12 @@ AC_ARG_ENABLE([gif], [use_libgif=$enableval], [use_libgif=auto]) +AC_ARG_ENABLE([afpclient], + [AS_HELP_STRING([--enable-afpclient], + [enable AFP support via libafpclient (default is auto)])], + [use_libafpclient=$enableval], + [use_libafpclient=auto]) + AC_ARG_ENABLE([airplay], [AS_HELP_STRING([--enable-airplay], [enable AirPlay support(default is auto)])], @@ -1564,6 +1572,26 @@ else AC_MSG_NOTICE($libgif_disabled) fi +# libafpclient +USE_LIBAFPCLIENT=0 +if test "x$use_libafpclient" != "xno"; then + AC_CHECK_HEADERS([afpfs-ng/libafpclient.h],, + [if test "x$use_libafpclient" = "xyes"; then + AC_MSG_ERROR($libafpclient_not_found) + elif test "x$use_libafpclient" != "xno"; then + AC_MSG_NOTICE($libafpclient_not_found) + use_libafpclient="no" + fi + ]) + if test "x$use_libafpclient" != "xno"; then + XB_FIND_SONAME([AFPCLIENT], [afpclient], [use_libafpclient]) + AC_DEFINE([HAVE_LIBAFPCLIENT], [1], [Whether to use libafpclient library.]) + USE_LIBAFPCLIENT=1 + fi +else + AC_MSG_NOTICE($libafpclient_disabled) +fi + # libplist for airplay feature USE_AIRPLAY=0 if test "$use_airplay" != "no"; then @@ -2345,6 +2373,12 @@ else final_message="$final_message\n libgif support:\tNo" fi +if test "x$use_libafpclient" != "xno"; then + final_message="$final_message\n libafpclient support:\tYes" +else + final_message="$final_message\n libafpclient support:\tNo" +fi + if test "$use_airplay" != "no"; then final_message="$final_message\n AirPlay support:\tYes" else @@ -2598,6 +2632,7 @@ AC_SUBST(USE_VAAPI) AC_SUBST(USE_LIBSMBCLIENT) AC_SUBST(USE_LIBNFS) AC_SUBST(USE_LIBGIF) +AC_SUBST(USE_LIBAFPCLIENT) AC_SUBST(USE_AIRPLAY) AC_SUBST(USE_OPENMAX) AC_SUBST(USE_PULSE) diff --git a/lib/afpfs-ng/01-gcrypt.patch b/lib/afpfs-ng/01-gcrypt.patch new file mode 100644 index 0000000..7bcace2 --- /dev/null +++ b/lib/afpfs-ng/01-gcrypt.patch @@ -0,0 +1,26 @@ +diff -ru afpfs-ng-0.8.1/configure.ac afpfs-ng-0.8.1+iPhone/configure.ac +--- afpfs-ng-0.8.1/configure.ac 2008-03-08 16:23:12.000000000 +0000 ++++ afpfs-ng-0.8.1+iPhone/configure.ac 2010-10-24 05:26:15.000000000 +0000 +@@ -50,21 +50,6 @@ + case $host in + *-*-darwin*) + AC_MSG_CHECKING([for correct gcrypt version]) +- AC_RUN_IFELSE( +- [AC_LANG_PROGRAM([ +- #include +- #include ],[ +- char*p= GCRYPT_VERSION; +- unsigned int vers; +- vers=atoi(p)*10000; +- p=strchr(p,'.')+1; +- vers+=atoi(p)*100; +- p=strchr(p,'.')+1; +- vers+=atoi(p); +- if (vers<10400) return 1; +- ])], +- [AC_MSG_RESULT([yes])], +- [AC_MSG_ERROR([version is < 1.4.0])]) + AM_CONDITIONAL(HAVE_LIBGCRYPT, true) + AC_DEFINE([HAVE_LIBGCRYPT], [1] ) + ;; + diff --git a/lib/afpfs-ng/02-pointer.patch b/lib/afpfs-ng/02-pointer.patch new file mode 100644 index 0000000..80507b5 --- /dev/null +++ b/lib/afpfs-ng/02-pointer.patch @@ -0,0 +1,280 @@ +diff -up afpfs-ng-0.8.1/cmdline/getstatus.c.pointer afpfs-ng-0.8.1/cmdline/getstatus.c +--- afpfs-ng-0.8.1/cmdline/getstatus.c.pointer 2011-06-14 17:06:35.000000000 +0200 ++++ afpfs-ng-0.8.1/cmdline/getstatus.c 2011-06-14 17:07:25.000000000 +0200 +@@ -1,4 +1,5 @@ + #include ++#include + #include + #include + +diff -up afpfs-ng-0.8.1/fuse/client.c.pointer afpfs-ng-0.8.1/fuse/client.c +--- afpfs-ng-0.8.1/fuse/client.c.pointer 2008-03-08 03:44:16.000000000 +0100 ++++ afpfs-ng-0.8.1/fuse/client.c 2011-06-14 17:02:15.000000000 +0200 +@@ -61,8 +61,9 @@ static int start_afpfsd(void) + snprintf(filename, PATH_MAX, + "/usr/local/bin/%s",AFPFSD_FILENAME); + if (access(filename,X_OK)) { +- snprintf(filename, "/usr/bin/%s", ++ snprintf(filename, sizeof(filename), "/usr/bin/%s", + AFPFSD_FILENAME); ++ filename[sizeof(filename) - 1] = 0; + if (access(filename,X_OK)) { + printf("Could not find server (%s)\n", + filename); +diff -up afpfs-ng-0.8.1/fuse/fuse_int.c.pointer afpfs-ng-0.8.1/fuse/fuse_int.c +--- afpfs-ng-0.8.1/fuse/fuse_int.c.pointer 2008-03-02 06:06:24.000000000 +0100 ++++ afpfs-ng-0.8.1/fuse/fuse_int.c 2011-06-14 17:02:15.000000000 +0200 +@@ -197,7 +197,7 @@ static int fuse_open(const char *path, s + ret = ml_open(volume,path,flags,&fp); + + if (ret==0) +- fi->fh=(void *) fp; ++ fi->fh=(unsigned long) fp; + + return ret; + } +diff -up afpfs-ng-0.8.1/include/afpfs-ng/afp.h.pointer afpfs-ng-0.8.1/include/afp.h +--- afpfs-ng-0.8.1/include/afpfs-ng/afp.h.pointer 2008-03-08 17:08:18.000000000 +0100 ++++ afpfs-ng-0.8.1/include/afpfs-ng/afp.h 2011-06-14 17:02:15.000000000 +0200 +@@ -370,7 +370,7 @@ int afp_unmount_all_volumes(struct afp_s + + int afp_opendt(struct afp_volume *volume, unsigned short * refnum); + +-int afp_closedt(struct afp_server * server, unsigned short * refnum); ++int afp_closedt(struct afp_server * server, unsigned short refnum); + + int afp_getcomment(struct afp_volume *volume, unsigned int did, + const char * pathname, struct afp_comment * comment); +diff -up afpfs-ng-0.8.1/include/afpfs-gn/utils.h.pointer afpfs-ng-0.8.1/include/utils.h +--- afpfs-ng-0.8.1/include/afpfs-ng/utils.h.pointer 2008-02-18 04:33:58.000000000 +0100 ++++ afpfs-ng-0.8.1/include/afpfs-ng/utils.h 2011-06-14 17:02:15.000000000 +0200 +@@ -8,8 +8,8 @@ + #define hton64(x) (x) + #define ntoh64(x) (x) + #else /* BYTE_ORDER == BIG_ENDIAN */ +-#define hton64(x) ((u_int64_t) (htonl(((x) >> 32) & 0xffffffffLL)) | \ +- (u_int64_t) ((htonl(x) & 0xffffffffLL) << 32)) ++#define hton64(x) ((u_int64_t) (htonl((((unsigned long long)(x)) >> 32) & 0xffffffffLL)) | \ ++ (u_int64_t) ((htonl((unsigned long long)(x)) & 0xffffffffLL) << 32)) + #define ntoh64(x) (hton64(x)) + #endif /* BYTE_ORDER == BIG_ENDIAN */ + +diff -up afpfs-ng-0.8.1/lib/afp_url.c.pointer afpfs-ng-0.8.1/lib/afp_url.c +--- afpfs-ng-0.8.1/lib/afp_url.c.pointer 2008-03-04 21:16:49.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/afp_url.c 2011-06-14 17:02:15.000000000 +0200 +@@ -33,7 +33,7 @@ static int check_port(char * port) + static int check_uamname(const char * uam) + { + char * p; +- for (p=uam;*p;p++) { ++ for (p=(char *)uam;*p;p++) { + if (*p==' ') continue; + if ((*p<'A') || (*p>'z')) return -1; + } +@@ -188,7 +188,7 @@ int afp_parse_url(struct afp_url * url, + return -1; + + } +- if (p==NULL) p=toparse; ++ if (p==NULL) p=(char *)toparse; + + /* Now split on the first / */ + if (sscanf(p,"%[^/]/%[^$]", +diff -up afpfs-ng-0.8.1/lib/did.c.pointer afpfs-ng-0.8.1/lib/did.c +--- afpfs-ng-0.8.1/lib/did.c.pointer 2008-02-18 04:39:17.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/did.c 2011-06-14 17:02:15.000000000 +0200 +@@ -226,7 +226,7 @@ int get_dirid(struct afp_volume * volume + + + /* Go to the end of last known entry */ +- p=path+(p-copy); ++ p=(char *)path+(p-copy); + p2=p; + + while ((p=strchr(p+1,'/'))) { +diff -up afpfs-ng-0.8.1/lib/dsi.c.pointer afpfs-ng-0.8.1/lib/dsi.c +--- afpfs-ng-0.8.1/lib/dsi.c.pointer 2008-02-18 04:53:03.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/dsi.c 2011-06-14 17:02:15.000000000 +0200 +@@ -474,7 +474,7 @@ void dsi_getstatus_reply(struct afp_serv + } + server->flags=ntohs(reply1->flags); + +- p=(void *)((unsigned int) server->incoming_buffer + sizeof(*reply1)); ++ p=(void *)((unsigned long) server->incoming_buffer + sizeof(*reply1)); + p+=copy_from_pascal(server->server_name,p,AFP_SERVER_NAME_LEN)+1; + + /* Now work our way through the variable bits */ +@@ -757,7 +757,7 @@ gotenough: + printf("<<< read() of rest of AFP, %d bytes\n",amount_to_read); + #endif + ret = read(server->fd, (void *) +- (((unsigned int) server->incoming_buffer)+server->data_read), ++ (((unsigned long) server->incoming_buffer)+server->data_read), + amount_to_read); + if (ret<0) return -1; + if (ret==0) { +diff -up afpfs-ng-0.8.1/lib/loop.c.pointer afpfs-ng-0.8.1/lib/loop.c +--- afpfs-ng-0.8.1/lib/loop.c.pointer 2008-02-18 04:40:11.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/loop.c 2011-06-14 17:02:15.000000000 +0200 +@@ -25,7 +25,7 @@ + static unsigned char exit_program=0; + + static pthread_t ending_thread; +-static pthread_t main_thread = NULL; ++static pthread_t main_thread = (pthread_t)NULL; + + static int loop_started=0; + static pthread_cond_t loop_started_condition; +diff -up afpfs-ng-0.8.1/lib/lowlevel.c.pointer afpfs-ng-0.8.1/lib/lowlevel.c +--- afpfs-ng-0.8.1/lib/lowlevel.c.pointer 2008-02-20 02:33:17.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/lowlevel.c 2011-06-14 17:02:15.000000000 +0200 +@@ -582,7 +582,7 @@ int ll_getattr(struct afp_volume * volum + if (volume->server->using_version->av_number>=30) + stbuf->st_mode |= fp.unixprivs.permissions; + else +- set_nonunix_perms(stbuf,&fp); ++ set_nonunix_perms(&stbuf->st_mode,&fp); + + stbuf->st_uid=fp.unixprivs.uid; + stbuf->st_gid=fp.unixprivs.gid; +diff -up afpfs-ng-0.8.1/lib/midlevel.c.pointer afpfs-ng-0.8.1/lib/midlevel.c +--- afpfs-ng-0.8.1/lib/midlevel.c.pointer 2008-03-08 17:08:18.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/midlevel.c 2011-06-14 17:02:15.000000000 +0200 +@@ -713,7 +713,7 @@ int ml_write(struct afp_volume * volume, + { + + int ret,err=0; +- int totalwritten = 0; ++ size_t totalwritten = 0; + uint64_t sizetowrite, ignored; + unsigned char flags = 0; + unsigned int max_packet_size=volume->server->tx_quantum; +diff -up afpfs-ng-0.8.1/lib/proto_attr.c.pointer afpfs-ng-0.8.1/lib/proto_attr.c +--- afpfs-ng-0.8.1/lib/proto_attr.c.pointer 2008-01-30 05:37:58.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/proto_attr.c 2011-06-14 17:02:15.000000000 +0200 +@@ -166,7 +166,7 @@ int afp_getextattr(struct afp_volume * v + copy_path(server,p,pathname,strlen(pathname)); + unixpath_to_afppath(server,p); + p2=p+sizeof_path_header(server)+strlen(pathname); +- if (((unsigned int ) p2) & 0x1) p2++; ++ if (((unsigned long) p2) & 0x1) p2++; + req2=(void *) p2; + + req2->len=htons(namelen); +diff -up afpfs-ng-0.8.1/lib/proto_desktop.c.pointer afpfs-ng-0.8.1/lib/proto_desktop.c +--- afpfs-ng-0.8.1/lib/proto_desktop.c.pointer 2008-02-18 04:44:11.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/proto_desktop.c 2011-06-14 17:02:15.000000000 +0200 +@@ -168,7 +168,7 @@ int afp_getcomment_reply(struct afp_serv + return 0; + } + +-int afp_closedt(struct afp_server * server, unsigned short * refnum) ++int afp_closedt(struct afp_server * server, unsigned short refnum) + { + struct { + struct dsi_header dsi_header __attribute__((__packed__)); +diff -up afpfs-ng-0.8.1/lib/proto_directory.c.pointer afpfs-ng-0.8.1/lib/proto_directory.c +--- afpfs-ng-0.8.1/lib/proto_directory.c.pointer 2008-02-19 03:39:29.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/proto_directory.c 2011-06-14 17:02:15.000000000 +0200 +@@ -248,6 +248,7 @@ int afp_enumerate_reply(struct afp_serve + + return 0; + } ++ + int afp_enumerateext2_reply(struct afp_server *server, char * buf, unsigned int size, void * other) + { + +@@ -266,8 +267,7 @@ int afp_enumerateext2_reply(struct afp_s + char * p = buf + sizeof(*reply); + int i; + char *max=buf+size; +- struct afp_file_info * filebase = NULL, *filecur=NULL, *new_file=NULL; +- void ** x = other; ++ struct afp_file_info * filebase = NULL, *filecur = NULL, *new_file = NULL, **x = (struct afp_file_info **) other; + + if (reply->dsi_header.return_code.error_code) { + return reply->dsi_header.return_code.error_code; +diff -up afpfs-ng-0.8.1/lib/proto_map.c.pointer afpfs-ng-0.8.1/lib/proto_map.c +--- afpfs-ng-0.8.1/lib/proto_map.c.pointer 2008-01-30 05:37:59.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/proto_map.c 2011-06-14 17:02:15.000000000 +0200 +@@ -122,7 +122,7 @@ int afp_mapid_reply(struct afp_server *s + + if (reply->header.return_code.error_code!=kFPNoErr) return -1; + +- copy_from_pascal_two(name,&reply->name,255); ++ copy_from_pascal_two(name,reply->name,255); + + return 0; + } +diff -up afpfs-ng-0.8.1/lib/proto_session.c.pointer afpfs-ng-0.8.1/lib/proto_session.c +--- afpfs-ng-0.8.1/lib/proto_session.c.pointer 2008-02-18 04:46:19.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/proto_session.c 2011-06-14 17:02:15.000000000 +0200 +@@ -39,7 +39,7 @@ int afp_getsessiontoken(struct afp_serve + switch (type) { + case kLoginWithTimeAndID: + case kReconnWithTimeAndID: { +- uint32_t *p = (void *) (((unsigned int) request)+ ++ uint32_t *p = (void *) (((unsigned long) request)+ + sizeof(*request)); + + offset=sizeof(timestamp); +@@ -63,7 +63,7 @@ int afp_getsessiontoken(struct afp_serve + goto error; + } + +- data=(void *) (((unsigned int) request)+sizeof(*request)+offset); ++ data=(void *) (((unsigned long) request)+sizeof(*request)+offset); + request->idlength=htonl(datalen); + request->pad=0; + request->type=htons(type); +@@ -127,7 +127,7 @@ int afp_disconnectoldsession(struct afp_ + if ((request=malloc(sizeof(*request) + AFP_TOKEN_MAX_LEN))==NULL) + return -1; + +- token_data = request + sizeof(*request); ++ token_data = (char *)request + sizeof(*request); + + request->type=htons(type); + +diff -up afpfs-ng-0.8.1/lib/uams.c.pointer afpfs-ng-0.8.1/lib/uams.c +--- afpfs-ng-0.8.1/lib/uams.c.pointer 2008-01-04 04:52:44.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/uams.c 2011-06-14 17:02:15.000000000 +0200 +@@ -180,7 +180,7 @@ static int cleartxt_login(struct afp_ser + goto cleartxt_fail; + + p += copy_to_pascal(p, username) + 1; +- if ((int)p & 0x1) ++ if ((long)p & 0x1) + len--; + else + p++; +@@ -230,7 +230,7 @@ static int cleartxt_passwd(struct afp_se + goto cleartxt_fail; + + p += copy_to_pascal(p, username) + 1; +- if ((int)p & 0x1) ++ if ((long)p & 0x1) + len--; + else + p++; +@@ -580,7 +580,7 @@ static int dhx_login(struct afp_server * + if (ai == NULL) + goto dhx_noctx_fail; + d += copy_to_pascal(ai, username) + 1; +- if (((int)d) % 2) ++ if (((long)d) % 2) + d++; + else + ai_len--; +diff -up afpfs-ng-0.8.1/lib/utils.c.pointer afpfs-ng-0.8.1/lib/utils.c +--- afpfs-ng-0.8.1/lib/utils.c.pointer 2008-02-18 04:53:37.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/utils.c 2011-06-14 17:02:15.000000000 +0200 +@@ -196,7 +196,7 @@ int invalid_filename(struct afp_server * + maxlen=255; + + +- p=filename+1; ++ p=(char *)filename+1; + while ((q=strchr(p,'/'))) { + if (q>p+maxlen) + return 1; diff --git a/lib/afpfs-ng/04-boxee1.patch b/lib/afpfs-ng/04-boxee1.patch new file mode 100644 index 0000000..9f3c20f --- /dev/null +++ b/lib/afpfs-ng/04-boxee1.patch @@ -0,0 +1,25 @@ +--- afpfs-ng-0.8.1/include/afpfs-ng/dsi.h 2008-02-18 04:33:24.000000000 +0100 ++++ afpfs-ng-0.8.1/include/afpfs-ng/dsi.h 2011-08-26 21:33:33.000000000 +0200 +@@ -6,13 +6,15 @@ + + struct dsi_request + { +- unsigned short requestid; +- unsigned char subcommand; +- void * other; +- unsigned char wait; +- pthread_cond_t condition_cond; +- struct dsi_request * next; +- int return_code; ++ unsigned short requestid; ++ unsigned char subcommand; ++ void * other; ++ int wait; ++ int done_waiting; ++ pthread_cond_t waiting_cond; ++ pthread_mutex_t waiting_mutex; ++ struct dsi_request * next; ++ int return_code; + }; + + int dsi_receive(struct afp_server * server, void * data, int size); diff --git a/lib/afpfs-ng/05-boxee2.patch b/lib/afpfs-ng/05-boxee2.patch new file mode 100644 index 0000000..50250bc --- /dev/null +++ b/lib/afpfs-ng/05-boxee2.patch @@ -0,0 +1,89 @@ +--- afpfs-ng-0.8.1/lib/afp.c 2008-03-08 03:44:16.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/afp.c 2011-08-26 21:33:33.000000000 +0200 +@@ -68,7 +68,7 @@ + afp_getsessiontoken_reply,afp_blank_reply, NULL, NULL, + afp_enumerateext2_reply, NULL, NULL, NULL, /*64 - 71 */ + afp_listextattrs_reply, NULL, NULL, NULL, +- afp_blank_reply, NULL, NULL, NULL, /*72 - 79 */ ++ afp_blank_reply, NULL, afp_blank_reply, afp_blank_reply, /*72 - 79 */ + + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +@@ -320,8 +320,16 @@ + + struct dsi_request * p; + struct afp_server *s2; ++ ++ ++ if (s==NULL) ++ goto out; ++ + for (p=s->command_requests;p;p=p->next) { +- pthread_cond_signal(&p->condition_cond); ++ pthread_mutex_lock(&p->waiting_mutex); ++ p->done_waiting=1; ++ pthread_cond_signal(&p->waiting_cond); ++ pthread_mutex_unlock(&p->waiting_mutex); + } + + if (s==server_base) { +@@ -354,7 +362,7 @@ + s->exit_flag = 0; + s->path_encoding=kFPUTF8Name; /* This is a default */ + s->next=NULL; +- s->bufsize=2048; ++ s->bufsize=4096; + s->incoming_buffer=malloc(s->bufsize); + + s->attention_quantum=AFP_DEFAULT_ATTENTION_QUANTUM; +@@ -524,13 +532,14 @@ + kFPVolCreateDateBit|kFPVolIDBit | + kFPVolNameBit; + char new_encoding; ++ int ret; + + if (server->using_version->av_number>=30) + bitmap|= kFPVolNameBit|kFPVolBlockSizeBit; + +- switch (afp_volopen(volume,bitmap, +- (strlen(volume->volpassword)>0) ? volume->volpassword : NULL)) +- { ++ ret = afp_volopen(volume,bitmap, ++ (strlen(volume->volpassword)>0) ? volume->volpassword : NULL); ++ switch(ret){ + case kFPAccessDenied: + *l+=snprintf(mesg,max-*l, + "Incorrect volume password\n"); +@@ -544,6 +553,10 @@ + *l+=snprintf(mesg,max-*l, + "Could not open volume\n"); + goto error; ++ case ETIMEDOUT: ++ *l+=snprintf(mesg,max-*l, ++ "Timed out waiting to open volume\n"); ++ goto error; + } + + /* It is said that if a volume's encoding will be the same +@@ -641,7 +654,6 @@ + add_server(server); + + add_fd_and_signal(server->fd); +- + if (!full) { + return 0; + } +@@ -649,10 +661,13 @@ + /* Get the status, and calculate the transmit time. We use this to + * calculate our rx quantum. */ + gettimeofday(&t1,NULL); ++ + if ((error=dsi_getstatus(server))!=0) + goto error; + gettimeofday(&t2,NULL); + ++ afp_server_identify(server); ++ + if ((t2.tv_sec - t1.tv_sec) > 0) + server->tx_delay= (t2.tv_sec - t1.tv_sec) * 1000; + else diff --git a/lib/afpfs-ng/06-boxee3.patch b/lib/afpfs-ng/06-boxee3.patch new file mode 100644 index 0000000..4b7c916 --- /dev/null +++ b/lib/afpfs-ng/06-boxee3.patch @@ -0,0 +1,141 @@ +--- afpfs-ng-0.8.1/lib/dsi.c 2011-08-26 17:27:16.000000000 +0200 ++++ afpfs-ng-0.8.1/lib/dsi.c 2011-08-26 21:33:33.000000000 +0200 +@@ -64,7 +64,7 @@ + rx.size=0; + dsi_setup_header(server,&header,DSI_DSIGetStatus); + /* We're intentionally ignoring the results */ +- ret=dsi_send(server,(char *) &header,sizeof(struct dsi_header),20, ++ ret=dsi_send(server,(char *) &header,sizeof(struct dsi_header),60, + 0,(void *) &rx); + + free(rx.data); +@@ -197,6 +197,7 @@ + new_request->other=other; + new_request->wait=wait; + new_request->next=NULL; ++ new_request->done_waiting=0; + + pthread_mutex_lock(&server->request_queue_mutex); + if (server->command_requests==NULL) { +@@ -208,7 +209,8 @@ + server->stats.requests_pending++; + pthread_mutex_unlock(&server->request_queue_mutex); + +- pthread_cond_init(&new_request->condition_cond,NULL); ++ pthread_cond_init(&new_request->waiting_cond,NULL); ++ pthread_mutex_init(&new_request->waiting_mutex,NULL); + + if (server->connect_state==SERVER_STATE_DISCONNECTED) { + char mesg[1024]; +@@ -240,16 +242,12 @@ + server->stats.tx_bytes+=size; + pthread_mutex_unlock(&server->send_mutex); + +- int tmpwait=new_request->wait; + #ifdef DEBUG_DSI + printf("=== Waiting for response for %d %s\n", + new_request->requestid, + afp_get_command_name(new_request->subcommand)); + #endif +- if (tmpwait<0) { +- +- pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +- pthread_mutex_lock(&mutex); ++ if (new_request->wait<0) { + + /* Wait forever */ + #ifdef DEBUG_DSI +@@ -258,14 +256,17 @@ + afp_get_command_name(new_request->subcommand)); + #endif + +- rc=pthread_cond_wait( +- &new_request->condition_cond, +- &mutex ); +- pthread_mutex_unlock(&mutex); +- +- } else if (tmpwait>0) { +- pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +- pthread_mutex_lock(&mutex); ++ pthread_mutex_lock(&new_request->waiting_mutex); ++ ++ if (new_request->done_waiting==0) ++ rc=pthread_cond_wait( ++ &new_request->waiting_cond, ++ &new_request->waiting_mutex ); ++ ++ pthread_mutex_unlock(&new_request->waiting_mutex); ++ ++ } else if (new_request->wait>0) { ++ /* wait for new_request->wait seconds */ + + #ifdef DEBUG_DSI + printf("=== Waiting for %d %s, for %ds\n", +@@ -283,13 +284,15 @@ + printf("=== Changing my mind, no longer waiting for %d\n", + new_request->requestid); + #endif +- pthread_mutex_unlock(&mutex); + goto skip; + } +- rc=pthread_cond_timedwait( +- &new_request->condition_cond, +- &mutex,&ts); +- pthread_mutex_unlock(&mutex); ++ pthread_mutex_lock(&new_request->waiting_mutex); ++ if (new_request->done_waiting==0) ++ rc=pthread_cond_timedwait( ++ &new_request->waiting_cond, ++ &new_request->waiting_mutex,&ts); ++ pthread_mutex_unlock(&new_request->waiting_mutex); ++ + if (rc==ETIMEDOUT) { + /* FIXME: should handle this case properly */ + #ifdef DEBUG_DSI +@@ -299,6 +302,7 @@ + goto out; + } + } else { ++ /* Don't wait */ + #ifdef DEBUG_DSI + printf("=== Skipping wait altogether for %d\n",new_request->requestid); + #endif +@@ -474,7 +478,7 @@ + } + server->flags=ntohs(reply1->flags); + +- p=(void *)((unsigned long) server->incoming_buffer + sizeof(*reply1)); ++ p=(void *)((unsigned int) server->incoming_buffer + sizeof(*reply1)); + p+=copy_from_pascal(server->server_name,p,AFP_SERVER_NAME_LEN)+1; + + /* Now work our way through the variable bits */ +@@ -577,6 +581,7 @@ + unsigned char mins=0; + unsigned char checkmessage=0; + ++ memset(mesg,0,AFP_LOGINMESG_LEN); + + /* The logic here's undocumented. If we get an attention packet and + there's no flag, then go check the message. Also, go check the +@@ -757,7 +762,7 @@ + printf("<<< read() of rest of AFP, %d bytes\n",amount_to_read); + #endif + ret = read(server->fd, (void *) +- (((unsigned long) server->incoming_buffer)+server->data_read), ++ (((unsigned int) server->incoming_buffer)+server->data_read), + amount_to_read); + if (ret<0) return -1; + if (ret==0) { +@@ -862,8 +867,11 @@ + #ifdef DEBUG_DSI + printf("<<< Signalling %d, returning %d or %d\n",request->requestid,request->return_code,rc); + #endif ++ pthread_mutex_lock(&request->waiting_mutex); + request->wait=0; +- pthread_cond_signal(&request->condition_cond); ++ request->done_waiting=1; ++ pthread_cond_signal(&request->waiting_cond); ++ pthread_mutex_unlock(&request->waiting_mutex); + } else { + dsi_remove_from_request_queue(server,request); + } diff --git a/lib/afpfs-ng/07-boxee4.patch b/lib/afpfs-ng/07-boxee4.patch new file mode 100644 index 0000000..3e09f40 --- /dev/null +++ b/lib/afpfs-ng/07-boxee4.patch @@ -0,0 +1,27 @@ +--- afpfs-ng-0.8.1/lib/identify.c 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/identify.c 2011-08-26 21:33:33.000000000 +0200 +@@ -0,0 +1,24 @@ ++#include ++#include ++ ++ ++/* ++ * afp_server_identify() ++ * ++ * Identifies a server ++ * ++ * Right now, this only does identification using the machine_type ++ * given in getsrvrinfo, but this could later use mDNS to get ++ * more details. ++ */ ++void afp_server_identify(struct afp_server * s) ++{ ++ if (strcmp(s->machine_type,"Netatalk")==0) ++ s->server_type=AFPFS_SERVER_TYPE_NETATALK; ++ else if (strcmp(s->machine_type,"AirPort")==0) ++ s->server_type=AFPFS_SERVER_TYPE_AIRPORT; ++ else if (strcmp(s->machine_type,"Macintosh")==0) ++ s->server_type=AFPFS_SERVER_TYPE_MACINTOSH; ++ else ++ s->server_type=AFPFS_SERVER_TYPE_UNKNOWN; ++} diff --git a/lib/afpfs-ng/08-boxee5.patch b/lib/afpfs-ng/08-boxee5.patch new file mode 100644 index 0000000..253fb05 --- /dev/null +++ b/lib/afpfs-ng/08-boxee5.patch @@ -0,0 +1,11 @@ +--- afpfs-ng-0.8.1/lib/Makefile.am 2008-02-18 04:34:32.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/Makefile.am 2011-08-26 21:33:33.000000000 +0200 +@@ -4,7 +4,7 @@ + + lib_LTLIBRARIES = libafpclient.la + +-libafpclient_la_SOURCES = afp.c codepage.c did.c dsi.c map_def.c uams.c uams_def.c unicode.c users.c utils.c resource.c log.c client.c server.c connect.c loop.c midlevel.c proto_attr.c proto_desktop.c proto_directory.c proto_files.c proto_fork.c proto_login.c proto_map.c proto_replyblock.c proto_server.c proto_volume.c proto_session.c afp_url.c status.c forklist.c debug.c lowlevel.c ++libafpclient_la_SOURCES = afp.c codepage.c did.c dsi.c map_def.c uams.c uams_def.c unicode.c users.c utils.c resource.c log.c client.c server.c connect.c loop.c midlevel.c proto_attr.c proto_desktop.c proto_directory.c proto_files.c proto_fork.c proto_login.c proto_map.c proto_replyblock.c proto_server.c proto_volume.c proto_session.c afp_url.c status.c forklist.c debug.c lowlevel.c identify.c + + # libafpclient_la_LDFLAGS = -module -avoid-version + diff --git a/lib/afpfs-ng/10-fix-errno.patch b/lib/afpfs-ng/10-fix-errno.patch new file mode 100644 index 0000000..ff7ce44 --- /dev/null +++ b/lib/afpfs-ng/10-fix-errno.patch @@ -0,0 +1,23 @@ +--- afpfs-ng-0.8.1/lib/afp.c 2011-09-04 19:42:42.000000000 +0200 ++++ afpfs-ng-0.8.1/lib/afp.c 2011-09-04 19:39:44.000000000 +0200 +@@ -19,7 +19,6 @@ + #include + #include + #include +-#include + + #include + #include +--- afpfs-ng-0.8.1/lib/afp_url.c 2011-09-04 19:42:42.000000000 +0200 ++++ afpfs-ng-0.8.1/lib/afp_url.c 2011-09-04 19:40:27.000000000 +0200 +@@ -21,7 +21,9 @@ + + static int check_port(char * port) + { +- long long ret = strtol(port,NULL,10); ++ long long ret = 0; ++ errno = 0; ++ ret = strtol(port,NULL,10); + if ((ret<0) || (ret>32767)) return -1; + if (errno) { + printf("port error\n"); diff --git a/lib/afpfs-ng/11-fix-stat.patch b/lib/afpfs-ng/11-fix-stat.patch new file mode 100644 index 0000000..09e9a35 --- /dev/null +++ b/lib/afpfs-ng/11-fix-stat.patch @@ -0,0 +1,11 @@ +--- afpfs-ng-0.8.1/lib/lowlevel.c 2011-10-01 20:36:55.000000000 +0200 ++++ afpfs-ng-0.8.1/lib/lowlevel.c 2011-10-01 20:46:00.000000000 +0200 +@@ -579,7 +579,7 @@ + return -EIO; + } + +- if (volume->server->using_version->av_number>=30) ++ if (volume->server->using_version->av_number>=30 && fp.unixprivs.permissions != 0) + stbuf->st_mode |= fp.unixprivs.permissions; + else + set_nonunix_perms(&stbuf->st_mode,&fp); diff --git a/lib/afpfs-ng/12-fix-even-more-pointers.patch b/lib/afpfs-ng/12-fix-even-more-pointers.patch new file mode 100644 index 0000000..b5926bc --- /dev/null +++ b/lib/afpfs-ng/12-fix-even-more-pointers.patch @@ -0,0 +1,83 @@ +diff -uPr afpfs-ng-0.8.1/include/afpfs-ng/afp.h afpfs-ng-0.8.1/include/afpfs-ng/afp.h +--- afpfs-ng-0.8.1/include/afpfs-ng/afp.h 2012-10-30 22:30:29.000000000 +0100 ++++ afpfs-ng-0.8.1/include/afpfs-ng/afp.h 2012-10-30 22:26:15.000000000 +0100 +@@ -71,7 +71,7 @@ + struct afp_file_info * largelist_next; + unsigned char isdir; + unsigned long long size; +- unsigned short resourcesize; ++ unsigned long long resourcesize; + unsigned int resource; + unsigned short forkid; + struct afp_icon * icon; +--- afpfs-ng-0.8.1/lib/loop.c 2012-10-30 22:48:19.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/loop.c 2012-10-30 22:48:47.000000000 +0100 +@@ -87,12 +87,13 @@ + static int ending=0; + void * just_end_it_now(void * ignore) + { +- if (ending) return; ++ if (ending) return NULL; + ending=1; + if (libafpclient->forced_ending_hook) + libafpclient->forced_ending_hook(); + exit_program=2; + signal_main_thread(); ++ return NULL; + } + + /*This is a hack to handle a problem where the first pthread_kill doesnt' work*/ +diff -uPr afpfs-ng-0.8.1/lib/dsi.c afpfs-ng-0.8.1/lib/dsi.c +--- afpfs-ng-0.8.1/lib/dsi.c 2012-10-30 22:30:29.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/dsi.c 2012-10-30 22:11:09.000000000 +0100 +@@ -478,7 +478,7 @@ + } + server->flags=ntohs(reply1->flags); + +- p=(void *)((unsigned int) server->incoming_buffer + sizeof(*reply1)); ++ p=(void *)((unsigned long) server->incoming_buffer + sizeof(*reply1)); + p+=copy_from_pascal(server->server_name,p,AFP_SERVER_NAME_LEN)+1; + + /* Now work our way through the variable bits */ +@@ -762,7 +762,7 @@ + printf("<<< read() of rest of AFP, %d bytes\n",amount_to_read); + #endif + ret = read(server->fd, (void *) +- (((unsigned int) server->incoming_buffer)+server->data_read), ++ (((unsigned long) server->incoming_buffer)+server->data_read), + amount_to_read); + if (ret<0) return -1; + if (ret==0) { +diff -uPr afpfs-ng-0.8.1/lib/lowlevel.c afpfs-ng-0.8.1/lib/lowlevel.c +--- afpfs-ng-0.8.1/lib/lowlevel.c 2012-10-30 22:30:29.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/lowlevel.c 2012-10-30 22:29:57.000000000 +0100 +@@ -582,7 +582,7 @@ + if (volume->server->using_version->av_number>=30 && fp.unixprivs.permissions != 0) + stbuf->st_mode |= fp.unixprivs.permissions; + else +- set_nonunix_perms(&stbuf->st_mode,&fp); ++ set_nonunix_perms((mode_t *)&stbuf->st_mode,&fp); + + stbuf->st_uid=fp.unixprivs.uid; + stbuf->st_gid=fp.unixprivs.gid; +diff -uPr afpfs-ng-0.8.1/lib/proto_directory.c afpfs-ng-0.8.1/lib/proto_directory.c +--- afpfs-ng-0.8.1/lib/proto_directory.c 2012-10-30 22:30:29.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/proto_directory.c 2012-10-30 22:15:28.000000000 +0100 +@@ -259,7 +259,7 @@ + uint16_t reqcount; + } __attribute__((__packed__)) * reply = (void *) buf; + +- struct { ++ struct sEntry{ + uint16_t size; + uint8_t isdir; + uint8_t pad; +@@ -293,7 +293,7 @@ + filecur=new_file; + } + +- entry = p; ++ entry = (struct sEntry *)p; + + parse_reply_block(server,p+sizeof(*entry), + ntohs(entry->size),entry->isdir, diff --git a/lib/afpfs-ng/Makefile b/lib/afpfs-ng/Makefile new file mode 100644 index 0000000..67ccdc2 --- /dev/null +++ b/lib/afpfs-ng/Makefile @@ -0,0 +1,68 @@ +# A quick and dirty Makefile to download/build and install +# +# Usage: +# make +# sudo make install + +# lib name, version +LIBNAME=afpfs-ng +VERSION=0.8.1 +SOURCE=$(LIBNAME)-$(VERSION) + +# download location and format +BASE_URL=http://mirrors.xbmc.org/build-deps/darwin-libs +ARCHIVE=$(SOURCE).tar.gz. +TARBALLS_LOCATION=. +RETRIEVE_TOOL=/usr/bin/curl +RETRIEVE_TOOL_FLAGS=-Ls --create-dirs --output $(TARBALLS_LOCATION)/$(ARCHIVE) +ARCHIVE_TOOL=tar +ARCHIVE_TOOL_FLAGS=xf +PREFIX ?= /usr/local +AFPFSNG_CONFIGOPTS ?= --prefix=$(PREFIX) + + +ARCHIVE=$(SOURCE).tar.bz2 + + + +# configuration settings +export PATH:=$(TOOLCHAIN)/bin:$(PATH) +CONFIGURE=./configure $(AFPFSNG_CONFIGOPTS) \ + --disable-fuse ac_cv_func_malloc_0_nonnull=yes + +SO_NAME=$(SOURCE)/lib/.libs/libafpclient.so + +all: $(SO_NAME) + +$(TARBALLS_LOCATION)/$(ARCHIVE): + $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE) + +$(SOURCE): $(TARBALLS_LOCATION)/$(ARCHIVE) + rm -rf $(SOURCE) + $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) + echo $(SOURCE) > .gitignore + cd $(SOURCE); patch -p1 <../fix_afpfs-ng_includes.patch + cd $(SOURCE); patch -p1 <../01-gcrypt.patch + cd $(SOURCE); patch -p1 <../02-pointer.patch + cd $(SOURCE); patch -p1 <../04-boxee1.patch + cd $(SOURCE); patch -p1 <../05-boxee2.patch + cd $(SOURCE); patch -p1 <../06-boxee3.patch + cd $(SOURCE); patch -p1 <../07-boxee4.patch + cd $(SOURCE); patch -p1 <../08-boxee5.patch + cd $(SOURCE); patch -p1 <../10-fix-errno.patch + cd $(SOURCE); patch -p1 <../11-fix-stat.patch + cd $(SOURCE); patch -p1 <../12-fix-even-more-pointers.patch + cd $(SOURCE); autoreconf -vif + cd $(SOURCE); $(CONFIGURE) + +$(SO_NAME): $(SOURCE) + make -j 1 -C $(SOURCE) + +install: + make -C $(SOURCE) install + +clean: + make -C $(SOURCE) clean + +distclean:: + rm -rf $(SOURCE) $(ARCHIVE) diff --git a/lib/afpfs-ng/fix_afpfs-ng_includes.patch b/lib/afpfs-ng/fix_afpfs-ng_includes.patch new file mode 100644 index 0000000..f507a48 --- /dev/null +++ b/lib/afpfs-ng/fix_afpfs-ng_includes.patch @@ -0,0 +1,3082 @@ +diff -Naur afpfs-ng-0.8.1/cmdline/cmdline_afp.c afpfs-ng-0.8.1.patch/cmdline/cmdline_afp.c +--- afpfs-ng-0.8.1/cmdline/cmdline_afp.c 2008-02-19 02:54:19.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/cmdline/cmdline_afp.c 2011-09-10 12:13:50.102124369 +0200 +@@ -3,9 +3,9 @@ + + */ + +-#include "afp.h" +-#include "midlevel.h" +-#include "map_def.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/midlevel.h" ++#include "afpfs-ng/map_def.h" + + #include + #include +diff -Naur afpfs-ng-0.8.1/cmdline/cmdline_testafp.c afpfs-ng-0.8.1.patch/cmdline/cmdline_testafp.c +--- afpfs-ng-0.8.1/cmdline/cmdline_testafp.c 2008-03-04 21:16:50.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/cmdline/cmdline_testafp.c 2011-09-10 12:13:50.102124369 +0200 +@@ -3,8 +3,8 @@ + + */ + +-#include "afp.h" +-#include "midlevel.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/midlevel.h" + + #include "cmdline_main.h" + +diff -Naur afpfs-ng-0.8.1/cmdline/getstatus.c afpfs-ng-0.8.1.patch/cmdline/getstatus.c +--- afpfs-ng-0.8.1/cmdline/getstatus.c 2008-02-18 04:28:09.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/cmdline/getstatus.c 2011-09-10 12:13:50.109124463 +0200 +@@ -2,7 +2,7 @@ + #include + #include + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + + static int getstatus(char * address_string, unsigned int port) + { +diff -Naur afpfs-ng-0.8.1/configure.ac afpfs-ng-0.8.1.patch/configure.ac +--- afpfs-ng-0.8.1/configure.ac 2008-03-08 17:23:12.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/configure.ac 2011-09-10 12:13:50.109124463 +0200 +@@ -11,6 +11,7 @@ + AC_PROG_CC + AC_PROG_INSTALL + AC_PROG_LIBTOOL ++AM_PROG_CC_C_O + + # Checks for libraries. + # FIXME: Replace `main' with a function in `-lncurses': +@@ -105,7 +106,7 @@ + + + +-AC_CONFIG_FILES([lib/Makefile fuse/Makefile cmdline/Makefile Makefile docs/Makefile]) ++AC_CONFIG_FILES([lib/Makefile fuse/Makefile cmdline/Makefile Makefile include/Makefile include/afpfs-ng/Makefile docs/Makefile]) + + AC_OUTPUT + +diff -Naur afpfs-ng-0.8.1/fuse/client.c afpfs-ng-0.8.1.patch/fuse/client.c +--- afpfs-ng-0.8.1/fuse/client.c 2008-03-08 03:44:16.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/fuse/client.c 2011-09-10 12:13:50.110124477 +0200 +@@ -12,11 +12,11 @@ + #include + + #include "config.h" +-#include ++#include + #include "afp_server.h" +-#include "uams_def.h" +-#include "map_def.h" +-#include "libafpclient.h" ++#include "afpfs-ng/uams_def.h" ++#include "afpfs-ng/map_def.h" ++#include "afpfs-ng/libafpclient.h" + + #define default_uam "Cleartxt Passwrd" + +diff -Naur afpfs-ng-0.8.1/fuse/commands.c afpfs-ng-0.8.1.patch/fuse/commands.c +--- afpfs-ng-0.8.1/fuse/commands.c 2008-03-08 17:06:25.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/fuse/commands.c 2011-09-10 12:13:50.110124477 +0200 +@@ -19,15 +19,15 @@ + #include + #include + +-#include "afp.h" +-#include "dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/dsi.h" + #include "afp_server.h" +-#include "utils.h" ++#include "afpfs-ng/utils.h" + #include "daemon.h" +-#include "uams_def.h" +-#include "codepage.h" +-#include "libafpclient.h" +-#include "map_def.h" ++#include "afpfs-ng/uams_def.h" ++#include "afpfs-ng/codepage.h" ++#include "afpfs-ng/libafpclient.h" ++#include "afpfs-ng/map_def.h" + #include "fuse_int.h" + #include "fuse_error.h" + #include "fuse_internal.h" +diff -Naur afpfs-ng-0.8.1/fuse/daemon.c afpfs-ng-0.8.1.patch/fuse/daemon.c +--- afpfs-ng-0.8.1/fuse/daemon.c 2008-03-04 18:26:05.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/fuse/daemon.c 2011-09-10 12:13:50.110124477 +0200 +@@ -23,11 +23,11 @@ + #include + #include + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + +-#include "dsi.h" ++#include "afpfs-ng/dsi.h" + #include "afp_server.h" +-#include "utils.h" ++#include "afpfs-ng/utils.h" + #include "daemon.h" + #include "commands.h" + +diff -Naur afpfs-ng-0.8.1/fuse/fuse_error.c afpfs-ng-0.8.1.patch/fuse/fuse_error.c +--- afpfs-ng-0.8.1/fuse/fuse_error.c 2008-01-18 05:40:10.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/fuse/fuse_error.c 2011-09-10 12:13:50.111124491 +0200 +@@ -4,7 +4,7 @@ + #include + #include + #include +-#include "libafpclient.h" ++#include "afpfs-ng/libafpclient.h" + #include "fuse_internal.h" + + #define TMP_FILE "/tmp/fuse_stderr" +diff -Naur afpfs-ng-0.8.1/fuse/fuse_int.c afpfs-ng-0.8.1.patch/fuse/fuse_int.c +--- afpfs-ng-0.8.1/fuse/fuse_int.c 2008-03-02 06:06:24.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/fuse/fuse_int.c 2011-09-10 12:13:50.111124491 +0200 +@@ -18,7 +18,7 @@ + #define FUSE_USE_VERSION 25 + + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + + #include + #include +@@ -39,10 +39,10 @@ + #include + #include + +-#include "dsi.h" +-#include "afp_protocol.h" +-#include "codepage.h" +-#include "midlevel.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp_protocol.h" ++#include "afpfs-ng/codepage.h" ++#include "afpfs-ng/midlevel.h" + #include "fuse_error.h" + + /* Uncomment the following line to enable full debugging: */ +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/afp.h afpfs-ng-0.8.1.patch/include/afpfs-ng/afp.h +--- afpfs-ng-0.8.1/include/afpfs-ng/afp.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/afp.h 2011-09-10 12:13:50.112124505 +0200 +@@ -0,0 +1,533 @@ ++ ++#ifndef _AFP_H_ ++#define _AFP_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define AFPFS_VERSION "0.8.1" ++ ++/* This is the maximum AFP version this library supports */ ++#define AFP_MAX_SUPPORTED_VERSION 32 ++ ++/* afp_url is used to pass locations around */ ++struct afp_url { ++ enum {TCPIP,AT} protocol; ++ char username[AFP_MAX_USERNAME_LEN]; ++ char uamname[50]; ++ char password[AFP_MAX_PASSWORD_LEN]; ++ char servername[AFP_SERVER_NAME_UTF8_LEN]; ++ int port; ++ char volumename[AFP_VOLUME_NAME_UTF8_LEN]; ++ char path[AFP_MAX_PATH]; ++ ++ int requested_version; ++ char zone[AFP_ZONE_LEN]; /* Only used for Appletalk */ ++ char volpassword[9];; ++}; ++ ++struct afp_token { ++ unsigned int length; ++ char data[AFP_TOKEN_MAX_LEN]; ++}; ++ ++#define SERVER_MAX_VERSIONS 10 ++#define SERVER_MAX_UAMS 10 ++ ++struct afp_rx_buffer { ++ unsigned int size; ++ unsigned int maxsize; ++ char * data; ++ int errorcode; ++}; ++ ++ ++struct afp_file_info { ++ unsigned short attributes; ++ unsigned int did; ++ unsigned int creation_date; ++ unsigned int modification_date; ++ unsigned int backup_date; ++ unsigned int fileid; ++ unsigned short offspring; ++ char sync; ++ char finderinfo[32]; ++ char name[AFP_MAX_PATH]; ++ char basename[AFP_MAX_PATH]; ++ char translated_name[AFP_MAX_PATH]; ++ struct afp_unixprivs unixprivs; ++ unsigned int accessrights; ++ struct afp_file_info * next; ++ struct afp_file_info * largelist_next; ++ unsigned char isdir; ++ unsigned long long size; ++ unsigned short resourcesize; ++ unsigned int resource; ++ unsigned short forkid; ++ struct afp_icon * icon; ++ int eof; ++}; ++ ++ ++#define VOLUME_EXTRA_FLAGS_VOL_CHMOD_KNOWN 0x1 ++#define VOLUME_EXTRA_FLAGS_VOL_CHMOD_BROKEN 0x2 ++#define VOLUME_EXTRA_FLAGS_SHOW_APPLEDOUBLE 0x4 ++#define VOLUME_EXTRA_FLAGS_VOL_SUPPORTS_UNIX 0x8 ++#define VOLUME_EXTRA_FLAGS_NO_LOCKING 0x10 ++#define VOLUME_EXTRA_FLAGS_IGNORE_UNIXPRIVS 0x20 ++#define VOLUME_EXTRA_FLAGS_READONLY 0x40 ++ ++#define AFP_VOLUME_UNMOUNTED 0 ++#define AFP_VOLUME_MOUNTED 1 ++#define AFP_VOLUME_UNMOUNTING 2 ++ ++struct afp_volume { ++ unsigned short volid; ++ char flags; /* This is from afpGetSrvrParms */ ++ unsigned short attributes; /* This is from VolOpen */ ++ unsigned short signature; /* This is fixed or variable */ ++ unsigned int creation_date; ++ unsigned int modification_date; ++ unsigned int backup_date; ++ struct statvfs stat; ++ unsigned char mounted; ++ char mountpoint[255]; ++ struct afp_server * server; ++ char volume_name[AFP_VOLUME_NAME_LEN]; ++ char volume_name_printable[AFP_VOLUME_NAME_UTF8_LEN]; ++ unsigned short dtrefnum; ++ char volpassword[AFP_VOLPASS_LEN]; ++ unsigned int extra_flags; /* This is an afpfs-ng specific field */ ++ ++ /* Our directory ID cache */ ++ struct did_cache_entry * did_cache_base; ++ pthread_mutex_t did_cache_mutex; ++ ++ /* Our journal of open forks */ ++ struct afp_file_info * open_forks; ++ pthread_mutex_t open_forks_mutex; ++ ++ /* Used to trigger startup */ ++ pthread_cond_t startup_condition_cond; ++ ++ struct { ++ uint64_t hits; ++ uint64_t misses; ++ uint64_t expired; ++ uint64_t force_removed; ++ } did_cache_stats; ++ ++ void * priv; /* This is a private structure for fuse/cmdline, etc */ ++ pthread_t thread; /* This is the per-volume thread */ ++ ++ int mapping; ++ ++}; ++ ++#define SERVER_STATE_CONNECTED 1 ++#define SERVER_STATE_DISCONNECTED 2 ++ ++enum server_type{ ++ AFPFS_SERVER_TYPE_UNKNOWN, ++ AFPFS_SERVER_TYPE_NETATALK, ++ AFPFS_SERVER_TYPE_AIRPORT, ++ AFPFS_SERVER_TYPE_MACINTOSH, ++}; ++ ++#define is_netatalk(x) ( (x)->machine_type == AFPFS_SERVER_TYPE_NETATALK ) ++#define is_airport(x) ( (x)->machine_type == AFPFS_SERVER_TYPE_AIRPORT ) ++#define is_macintosh(x) ( (x)->machine_type == AFPFS_SERVER_TYPE_MACINTOSH ) ++ ++ ++ ++struct afp_versions { ++ char *av_name; ++ int av_number; ++}; ++extern struct afp_versions afp_versions[]; ++ ++struct afp_server { ++ ++ /* Our buffer sizes */ ++ unsigned int tx_quantum; ++ unsigned int rx_quantum; ++ ++ unsigned int tx_delay; ++ ++ /* Connection information */ ++ struct sockaddr_in address; ++ int fd; ++ ++ /* Some stats, for information only */ ++ struct { ++ uint64_t runt_packets; ++ uint64_t incoming_dsi; ++ uint64_t rx_bytes; ++ uint64_t tx_bytes; ++ uint64_t requests_pending; ++ } stats; ++ ++ /* General information */ ++ char server_name[AFP_SERVER_NAME_LEN]; ++ char server_name_utf8[AFP_SERVER_NAME_UTF8_LEN]; ++ char server_name_printable[AFP_SERVER_NAME_UTF8_LEN]; ++ ++ char machine_type[17]; ++ char icon[256]; ++ char signature[16]; ++ unsigned short flags; ++ int connect_state; ++ enum server_type server_type; ++ ++ /* This is the time we connected */ ++ time_t connect_time; ++ ++ /* UAMs */ ++ unsigned int supported_uams; ++ unsigned int using_uam; ++ ++ /* Authentication */ ++ char username[AFP_MAX_USERNAME_LEN]; ++ char password[AFP_MAX_PASSWORD_LEN]; ++ ++ /* Session */ ++ struct afp_token token; ++ char need_resume; ++ ++ /* Versions */ ++ unsigned char requested_version; ++ unsigned char versions[SERVER_MAX_VERSIONS]; ++ struct afp_versions *using_version; ++ ++ /* Volumes */ ++ unsigned char num_volumes; ++ struct afp_volume * volumes; ++ ++ void * dsi; ++ unsigned int exit_flag; ++ ++ /* Our DSI request queue */ ++ pthread_mutex_t requestid_mutex; ++ pthread_mutex_t request_queue_mutex; ++ unsigned short lastrequestid; ++ unsigned short expectedrequestid; ++ struct dsi_request * command_requests; ++ ++ ++ char loginmesg[200]; ++ char servermesg[200]; ++ char path_encoding; ++ ++ /* This is the data for the incoming buffer */ ++ char * incoming_buffer; ++ int data_read; ++ int bufsize; ++ ++ /* And this is for the outgoing queue */ ++ pthread_mutex_t send_mutex; ++ ++ /* This is for user mapping */ ++ struct passwd passwd; ++ unsigned int server_uid, server_gid; ++ int server_gid_valid; ++ ++ struct afp_server *next; ++ ++ /* These are for DSI attention packets */ ++ unsigned int attention_quantum; ++ unsigned int attention_len; ++ char * attention_buffer; ++ ++}; ++ ++struct afp_extattr_info { ++ unsigned int maxsize; ++ unsigned int size; ++ char data[1024]; ++}; ++struct afp_comment { ++ unsigned int maxsize; ++ unsigned int size; ++ char *data; ++}; ++ ++struct afp_icon { ++ unsigned int maxsize; ++ unsigned int size; ++ char *data; ++}; ++ ++#define AFP_DEFAULT_ATTENTION_QUANTUM 1024 ++ ++void afp_unixpriv_to_stat(struct afp_file_info *fp, ++ struct stat *stat); ++ ++int init_uams(void) ; ++ ++unsigned int find_uam_by_name(const char * name); ++char * uam_bitmap_to_string(unsigned int bitmap); ++ ++ ++char * get_uam_names_list(void); ++ ++unsigned int default_uams_mask(void); ++ ++struct afp_volume * find_volume_by_name(struct afp_server * server, ++ const char * volname); ++ ++struct afp_connection_request { ++ unsigned int uam_mask; ++ struct afp_url url; ++}; ++ ++void afp_default_url(struct afp_url *url); ++int afp_parse_url(struct afp_url * url, const char * toparse, int verbose); ++void afp_print_url(struct afp_url * url); ++int afp_url_validate(char * url_string, struct afp_url * valid_url); ++ ++int afp_list_volnames(struct afp_server * server, char * names, int max); ++ ++/* User mapping */ ++int afp_detect_mapping(struct afp_volume * volume); ++ ++/* These are some functions that help with simple status text generation */ ++ ++int afp_status_header(char * text, int * len); ++int afp_status_server(struct afp_server * s,char * text, int * len); ++ ++ ++struct afp_server * afp_server_full_connect(void * priv, struct afp_connection_request * req); ++ ++void * just_end_it_now(void *other); ++void add_fd_and_signal(int fd); ++void loop_disconnect(struct afp_server *s); ++void afp_wait_for_started_loop(void); ++ ++ ++struct afp_versions * pick_version(unsigned char *versions, ++ unsigned char requested) ; ++int pick_uam(unsigned int u1, unsigned int u2); ++ ++int afp_server_login(struct afp_server *server, ++ char * mesg, unsigned int *l, unsigned int max); ++ ++ ++int afp_dologin(struct afp_server *server, ++ unsigned int uam, char * username, char * passwd); ++ ++void afp_free_server(struct afp_server **server); ++ ++struct afp_server * afp_server_init(struct sockaddr_in * address); ++int afp_get_address(void * priv, const char * hostname, unsigned int port, ++ struct sockaddr_in * address); ++ ++ ++int afp_main_loop(int command_fd); ++int afp_main_quick_startup(pthread_t * thread); ++ ++int afp_server_destroy(struct afp_server *s) ; ++int afp_server_reconnect(struct afp_server * s, char * mesg, ++ unsigned int *l, unsigned int max); ++int afp_server_connect(struct afp_server *s, int full); ++ ++struct afp_server * afp_server_complete_connection( ++ void * priv, ++ struct afp_server * server, ++ struct sockaddr_in * address, unsigned char * versions, ++ unsigned int uams, char * username, char * password, ++ unsigned int requested_version, unsigned int uam_mask); ++ ++int afp_connect_volume(struct afp_volume * volume, struct afp_server * server, ++ char * mesg, unsigned int * l, unsigned int max); ++int something_is_mounted(struct afp_server * server); ++ ++int add_cache_entry(struct afp_file_info * file) ; ++struct afp_file_info * get_cache_by_name(char * name); ++struct afp_server * find_server_by_address(struct sockaddr_in * address); ++struct afp_server * find_server_by_signature(char * signature); ++struct afp_server * find_server_by_name(char * name); ++int server_still_valid(struct afp_server * server); ++ ++ ++struct afp_server * get_server_base(void); ++int afp_server_remove(struct afp_server * server); ++ ++int afp_unmount_volume(struct afp_volume * volume); ++int afp_unmount_all_volumes(struct afp_server * server); ++ ++#define volume_is_readonly(x) (((x)->attributes&kReadOnly) || \ ++ ((x)->extra_flags & VOLUME_EXTRA_FLAGS_READONLY)) ++ ++int afp_opendt(struct afp_volume *volume, unsigned short * refnum); ++ ++int afp_closedt(struct afp_server * server, unsigned short * refnum); ++ ++int afp_getcomment(struct afp_volume *volume, unsigned int did, ++ const char * pathname, struct afp_comment * comment); ++ ++int afp_addcomment(struct afp_volume *volume, unsigned int did, ++ const char * pathname, char * comment,uint64_t *size); ++ ++int afp_geticon(struct afp_volume * volume, unsigned int filecreator, ++ unsigned int filetype, unsigned char icontype, ++ unsigned short length, struct afp_icon * icon); ++ ++/* Things you want to do to a server */ ++ ++int afp_getsrvrmsg(struct afp_server *server, unsigned short messagetype,unsigned char utf8, unsigned char block, char * mesg); ++ ++int afp_login(struct afp_server *server, char * uaname, ++ char * userauthinfo, unsigned int userauthinfo_len, ++ struct afp_rx_buffer *rx); ++ ++int afp_changepassword(struct afp_server *server, char * uaname, ++ char * userauthinfo, unsigned int userauthinfo_len, ++ struct afp_rx_buffer *rx); ++ ++int afp_logincont(struct afp_server *server, unsigned short id, ++ char * userauthinfo, unsigned int userauthinfo_len, ++ struct afp_rx_buffer *rx); ++ ++int afp_getsessiontoken(struct afp_server * server, int type, ++ unsigned int timestamp, struct afp_token *outgoing_token, ++ struct afp_token * incoming_token); ++ ++int afp_getsrvrparms(struct afp_server *server); ++ ++int afp_logout(struct afp_server *server,unsigned char wait); ++ ++int afp_mapname(struct afp_server * server, unsigned char subfunction, ++ char * name, unsigned int * id); ++ ++int afp_mapid(struct afp_server * server, unsigned char subfunction, ++ unsigned int id, char *name); ++ ++int afp_getuserinfo(struct afp_server * server, int thisuser, ++ unsigned int userid, unsigned short bitmap, ++ unsigned int *newuid, unsigned int *newgid); ++ ++int afp_zzzzz(struct afp_server *server); ++ ++int afp_volopen(struct afp_volume * volume, ++ unsigned short bitmap, char * password); ++ ++int afp_flush(struct afp_volume * volume); ++ ++int afp_getfiledirparms(struct afp_volume *volume, unsigned int did, ++ unsigned int filebitmap, unsigned int dirbitmap, const char * pathname, ++ struct afp_file_info *fp); ++ ++int afp_enumerate(struct afp_volume * volume, ++ unsigned int dirid, ++ unsigned int filebitmap, unsigned int dirbitmap, ++ unsigned short reqcount, ++ unsigned short startindex, ++ char * path, ++ struct afp_file_info ** file_p); ++ ++int afp_enumerateext2(struct afp_volume * volume, ++ unsigned int dirid, ++ unsigned int filebitmap, unsigned int dirbitmap, ++ unsigned short reqcount, ++ unsigned long startindex, ++ char * path, ++ struct afp_file_info ** file_p); ++ ++int afp_openfork(struct afp_volume * volume, ++ unsigned char forktype, ++ unsigned int dirid, ++ unsigned short accessmode, ++ char * filename, ++ struct afp_file_info *fp); ++ ++int afp_read(struct afp_volume * volume, unsigned short forkid, ++ uint32_t offset, ++ uint32_t count, struct afp_rx_buffer * rx); ++ ++int afp_readext(struct afp_volume * volume, unsigned short forkid, ++ uint64_t offset, ++ uint64_t count, struct afp_rx_buffer * rx); ++ ++int afp_getvolparms(struct afp_volume * volume, unsigned short bitmap); ++ ++ ++int afp_createdir(struct afp_volume * volume, unsigned int dirid, const char * pathname, unsigned int *did_p); ++ ++int afp_delete(struct afp_volume * volume, ++ unsigned int dirid, char * pathname); ++ ++ ++int afp_createfile(struct afp_volume * volume, unsigned char flag, ++ unsigned int did, char * pathname); ++ ++int afp_write(struct afp_volume * volume, unsigned short forkid, ++ uint32_t offset, uint32_t reqcount, ++ char * data, uint32_t * written); ++ ++int afp_writeext(struct afp_volume * volume, unsigned short forkid, ++ uint64_t offset, uint64_t reqcount, ++ char * data, uint64_t * written); ++ ++int afp_flushfork(struct afp_volume * volume, unsigned short forkid); ++ ++int afp_closefork(struct afp_volume * volume, unsigned short forkid); ++int afp_setfileparms(struct afp_volume * volume, ++ unsigned int dirid, const char * pathname, unsigned short bitmap, ++ struct afp_file_info *fp); ++int afp_setfiledirparms(struct afp_volume * volume, ++ unsigned int dirid, const char * pathname, unsigned short bitmap, ++ struct afp_file_info *fp); ++ ++int afp_setdirparms(struct afp_volume * volume, ++ unsigned int dirid, const char * pathname, unsigned short bitmap, ++ struct afp_file_info *fp); ++ ++int afp_volclose(struct afp_volume * volume); ++ ++ ++int afp_setforkparms(struct afp_volume *volume, ++ unsigned short forkid, unsigned short bitmap, unsigned long len); ++ ++int afp_byterangelock(struct afp_volume * volume, ++ unsigned char flag, ++ unsigned short forkid, ++ uint32_t offset, ++ uint32_t len, uint32_t *generated_offset); ++ ++int afp_byterangelockext(struct afp_volume * volume, ++ unsigned char flag, ++ unsigned short forkid, ++ uint64_t offset, ++ uint64_t len, uint64_t *generated_offset); ++ ++int afp_moveandrename(struct afp_volume *volume, ++ unsigned int src_did, ++ unsigned int dst_did, ++ char * src_path, char * dst_path, char *new_name); ++ ++int afp_rename(struct afp_volume * volume, ++ unsigned int dirid, ++ char * path_from, char * path_to); ++ ++int afp_listextattr(struct afp_volume * volume, ++ unsigned int dirid, unsigned short bitmap, ++ char * pathname, struct afp_extattr_info * info); ++ ++/* This is a currently undocumented command */ ++int afp_newcommand76(struct afp_volume * volume, unsigned int dlen, char * data); ++ ++/* For debugging */ ++char * afp_get_command_name(char code); ++ ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/afp_protocol.h afpfs-ng-0.8.1.patch/include/afpfs-ng/afp_protocol.h +--- afpfs-ng-0.8.1/include/afpfs-ng/afp_protocol.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/afp_protocol.h 2011-09-10 12:13:50.112124505 +0200 +@@ -0,0 +1,361 @@ ++ ++#ifndef _AFP_PROTOCOL_H_ ++#define _AFP_PROTOCOL_H_ ++ ++#include ++#include ++#include ++#include ++ ++/* This file defines constants for the Apple File Protocol. ++ All page references are from "Apple Filing Protocol Programming" version 3.2. ++ except where noted. ++*/ ++ ++#define AFP_SERVER_NAME_LEN 33 ++#define AFP_SERVER_NAME_UTF8_LEN 255 ++#define AFP_VOLUME_NAME_LEN 33 ++#define AFP_VOLUME_NAME_UTF8_LEN 33 ++#define AFP_SIGNATURE_LEN 16 ++#define AFP_MACHINETYPE_LEN 33 ++#define AFP_LOGINMESG_LEN 200 ++#define AFP_VOLPASS_LEN 8 ++#define AFP_HOSTNAME_LEN 255 ++/* This is actually just a guess, and only used for appletalk */ ++#define AFP_ZONE_LEN 255 ++ ++#define AFP_SERVER_ICON_LEN 256 ++ ++ ++#define AFP_MAX_USERNAME_LEN 127 ++#define AFP_MAX_PASSWORD_LEN 127 ++ ++ ++/* This is the maximum length of any UAM string */ ++#define AFP_UAM_LENGTH 24 ++ ++/* This is the maximum length of any path description */ ++#define AFP_MAX_PATH 768 ++ ++#define AFP_VOL_FLAT 1 ++#define AFP_VOL_FIXED 2 ++#define AFP_VOL_VARIABLE 3 ++ ++/* The root directory ID, p.26 */ ++ ++#define AFP_ROOT_DID 2 ++ ++/* Path type constants, p.249 */ ++ ++enum { ++kFPShortName = 1, ++kFPLongName = 2, ++kFPUTF8Name = 3 ++}; ++ ++/* fork types */ ++ ++#define AFP_FORKTYPE_DATA 0x0 ++#define AFP_FORKTYPE_RESOURCE 0x80 ++ ++/* openfork access modes, from p.196 */ ++ ++#define AFP_OPENFORK_ALLOWREAD 1 ++#define AFP_OPENFORK_ALLOWWRITE 2 ++#define AFP_OPENFORK_DENYREAD 0x10 ++#define AFP_OPENFORK_DENYWRITE 0x20 ++ ++/* Message type for getsrvmesg, p. 169*/ ++ ++typedef enum { ++ AFPMESG_LOGIN = 0, ++ AFPMESG_SERVER = 1 ++} afpmessage_t; ++ ++/* Message bitmap for getsrvrmsg */ ++ ++#define AFP_GETSRVRMSG_UTF8 0x2 ++#define AFP_GETSRVRMSG_GETMSG 0x1 ++ ++ ++/* Maximum Version length, p.17 */ ++#define AFP_MAX_VERSION_LENGTH 16 ++ ++/* Maximum length of a token, this is undocumented */ ++#define AFP_TOKEN_MAX_LEN 256 ++ ++/* The maximum size of a file for AFP 2 */ ++#define AFP_MAX_AFP2_FILESIZE (4294967296) ++ ++/* Unix privs, p.240 */ ++ ++struct afp_unixprivs { ++ uint32_t uid __attribute__((__packed__)); ++ uint32_t gid __attribute__((__packed__)); ++ uint32_t permissions __attribute__((__packed__)); ++ uint32_t ua_permissions __attribute__((__packed__)); ++ ++}; ++ ++ ++/* AFP Volume attributes bitmap, p.241 */ ++ ++enum { ++ kReadOnly = 0x01, ++ kHasVolumePassword = 0x02, ++ kSupportsFileIDs = 0x04, ++ kSupportsCatSearch = 0x08, ++ kSupportsBlankAccessPrivs = 0x10, ++ kSupportsUnixPrivs = 0x20, ++ kSupportsUTF8Names = 0x40, ++ kNoNetworkUserIDs = 0x80, ++ kDefaultPrivsFromParent = 0x100, ++ kNoExchangeFiles = 0x200, ++ kSupportsExtAttrs = 0x400, ++ kSupportsACLs=0x800 ++}; ++ ++/* AFP file creation constantes, p.250 */ ++enum { ++kFPSoftCreate = 0, ++kFPHardCreate = 0x80 ++}; ++ ++/* AFP Directory attributes, taken from the protocol guide p.236 */ ++ ++enum { ++ kFPAttributeBit = 0x1, ++ kFPParentDirIDBit = 0x2, ++ kFPCreateDateBit = 0x4, ++ kFPModDateBit = 0x8, ++ kFPBackupDateBit = 0x10, ++ kFPFinderInfoBit = 0x20, ++ kFPLongNameBit = 0x40, ++ kFPShortNameBit = 0x80, ++ kFPNodeIDBit = 0x100, ++ kFPOffspringCountBit = 0x0200, ++ kFPOwnerIDBit = 0x0400, ++ kFPGroupIDBit = 0x0800, ++ kFPAccessRightsBit = 0x1000, ++ kFPProDOSInfoBit = 0x2000, // AFP version 2.2 and earlier ++ kFPUTF8NameBit = 0x2000, // AFP version 3.0 and later ++ kFPUnixPrivsBit = 0x8000 // AFP version 3.0 and later ++}; ++ ++/* AFP File bitmap, p.238. These are the ones not in the AFP Directory ++ attributes map. */ ++ ++enum { ++ kFPDataForkLenBit = 0x0200, ++ kFPRsrcForkLenBit = 0x0400, ++ kFPExtDataForkLenBit = 0x0800, // AFP version 3.0 and later ++ kFPLaunchLimitBit = 0x1000, ++ kFPExtRsrcForkLenBit = 0x4000, // AFP version 3.0 and later ++}; ++ ++/* AFP Extended Attributes Bitmap, p.238 */ ++ ++enum { ++ kXAttrNoFollow = 0x1, ++ kXAttrCreate = 0x2, ++ kXAttrREplace=0x4 ++}; ++ ++ ++/* AFP function codes */ ++enum AFPFunction ++{ ++ afpByteRangeLock = 1, afpCloseVol, afpCloseDir, afpCloseFork, ++ afpCopyFile, afpCreateDir, afpCreateFile, ++ afpDelete, afpEnumerate, afpFlush, afpFlushFork, ++ afpGetForkParms = 14, afpGetSrvrInfo, afpGetSrvrParms, ++ afpGetVolParms, afpLogin, afpLoginCont, afpLogout, afpMapID, ++ afpMapName, afpMoveAndRename, afpOpenVol, afpOpenDir, afpOpenFork, ++ afpRead, afpRename, afpSetDirParms, afpSetFileParms, ++ afpSetForkParms, afpSetVolParms, afpWrite, afpGetFileDirParms, ++ afpSetFileDirParms, afpChangePassword, ++ afpGetUserInfo=37,afpGetSrvrMsg = 38, ++ afpOpenDT=48, ++ afpCloseDT=49, ++ afpGetIcon=51, afpGetIconInfo=52, ++ afpAddComment=56, afpRemoveComment=57, afpGetComment=58, ++ afpByteRangeLockExt=59, afpReadExt, afpWriteExt, ++ afpGetAuthMethods=62, ++ afp_LoginExt=63, ++ afpGetSessionToken=64, ++ afpDisconnectOldSession=65, ++ afpEnumerateExt=66, ++ afpCatSearchExt = 67, ++ afpEnumerateExt2 = 68, afpGetExtAttr, afpSetExtAttr, ++ afpRemoveExtAttr , afpListExtAttrs, ++ afpZzzzz = 122, ++ afpAddIcon=192, ++}; ++ ++/* AFP Volume bitmap. Take from 242 of the protocol guide. */ ++enum { ++ kFPBadVolPre222Bitmap = 0xFe00, ++ kFPBadVolBitmap = 0xF000, ++ kFPVolAttributeBit = 0x1, ++ kFPVolSignatureBit = 0x2, ++ kFPVolCreateDateBit = 0x4, ++ kFPVolModDateBit = 0x8, ++ kFPVolBackupDateBit = 0x10, ++ kFPVolIDBit = 0x20, ++ kFPVolBytesFreeBit = 0x40, ++ kFPVolBytesTotalBit = 0x80, ++ kFPVolNameBit = 0x100, ++ kFPVolExtBytesFreeBit = 0x200, ++ kFPVolExtBytesTotalBit = 0x400, ++ kFPVolBlockSizeBit = 0x800 ++}; ++ ++/* AFP Attention Codes -- 4 bits */ ++#define AFPATTN_SHUTDOWN (1 << 15) /* shutdown/disconnect */ ++#define AFPATTN_CRASH (1 << 14) /* server crashed */ ++#define AFPATTN_MESG (1 << 13) /* server has message */ ++#define AFPATTN_NORECONNECT (1 << 12) /* don't reconnect */ ++/* server notification */ ++#define AFPATTN_NOTIFY (AFPATTN_MESG | AFPATTN_NORECONNECT) ++ ++/* extended bitmap -- 12 bits. volchanged is only useful w/ a server ++ * notification, and time is only useful for shutdown. */ ++#define AFPATTN_VOLCHANGED (1 << 0) /* volume has changed */ ++#define AFPATTN_TIME(x) ((x) & 0xfff) /* time in minutes */ ++ ++#define kFPNoErr 0 ++ ++/* AFP result codes, p252 */ ++#define kASPSessClosed -1072 ++#define kFPAccessDenied -5000 ++#define kFPAuthContinue -5001 ++#define kFPBadUAM -5002 ++#define kFPBadVersNum -5003 ++#define kFPBitmapErr -5004 ++#define kFPCantMove -5005 ++#define kFPDenyConflict -5006 ++#define kFPDirNotEmpty -5007 ++#define kFPDiskFull -5008 ++#define kFPEOFErr -5009 ++#define kFPFileBusy -5010 ++#define kFPFlatVol -5011 ++#define kFPItemNotFound -5012 ++#define kFPLockErr -5013 ++#define kFPMiscErr -5014 ++#define kFPNoMoreLocks -5015 ++#define kFPNoServer -5016 ++#define kFPObjectExists -5017 ++#define kFPObjectNotFound -5018 ++#define kFPParamErr -5019 ++#define kFPRangeNotLocked -5020 ++#define kFPRangeOverlap -5021 ++#define kFPSessClosed -5022 ++#define kFPUserNotAuth -5023 ++#define kFPCallNotSupported -5024 ++#define kFPObjectTypeErr -5025 ++#define kFPTooManyFilesOpen -5026 ++#define kFPServerGoingDown -5027 ++#define kFPCantRename -5028 ++#define kFPDirNotFound -5029 ++#define kFPIconTypeError -5030 ++#define kFPVolLocked -5031 ++#define kFPObjectLocked -5032 ++#define kFPContainsSharedErr -5033 ++#define kFPIDNotFound -5034 ++#define kFPIDExists -5035 ++#define kFPDiffVolErr -5036 ++#define kFPCatalogChanged -5037 ++#define kFPSameObjectErr -5038 ++#define kFPBadIDErr -5039 ++#define kFPPwdSameErr -5040 ++#define kFPPwdTooShortErr -5041 ++#define kFPPwdExpiredErr -5042 ++#define kFPInsideSharedErr -5043 ++#define kFPInsideTrashErr -5044 ++#define kFPPwdNeedsChangeErr -5045 ++#define kFPPwdPolicyErr -5046 ++#define kFPDiskQuotaExceeded –5047 ++ ++ ++ ++/* These flags determine to lock or unlock in ByteRangeLock(Ext) */ ++ ++enum { ++ByteRangeLock_Lock = 0, ++ByteRangeLock_Unlock = 1 ++}; ++ ++/* These flags are used in volopen and getsrvrparm replies, p.171 */ ++ ++#define HasConfigInfo 0x1 ++#define HasPassword 0x80 ++ ++/* These are the subfunction for kFPMapID, as per p.248 */ ++ ++enum { ++kUserIDToName = 1, ++kGroupIDToName = 2, ++kUserIDToUTF8Name = 3, ++kGroupIDToUTF8Name = 4, ++kUserUUIDToUTF8Name = 5, ++kGroupUUIDToUTF8Name = 6 ++}; ++ ++ ++/* These are the subfunction flags described in the FPMapName command, p.286. ++ Note that this is different than what's described on p. 186. */ ++ ++enum { ++kNameToUserID = 1, ++kNameToGroupID = 2, ++kUTF8NameToUserID = 3, ++kUTF8NameToGroupID = 4, ++kUTF8NameToUserUUID = 5, ++kUTF8NameToGroupUUID = 6 ++}; ++ ++/* These are bits for FPGetUserInfo, p.173. */ ++#define kFPGetUserInfo_USER_ID 1 ++#define kFPGetUserInfo_PRI_GROUPID 2 ++ ++/* Flags for the replies of GetSrvrInfo and DSI GetStatus, p.240 */ ++ ++enum { ++ kSupportsCopyfile = 0x01, ++ kSupportsChgPwd = 0x02, ++ kDontAllowSavePwd = 0x04, ++ kSupportsSrvrMsg = 0x08, ++ kSrvrSig = 0x10, ++ kSupportsTCP = 0x20, ++ kSupportsSrvrNotify = 0x40, ++ kSupportsReconnect = 0x80, ++ kSupportsDirServices = 0x100, ++ kSupportsUTF8SrvrName = 0x200, ++ kSupportsUUIDs = 0x400, ++ kSupportsSuperClient = 0x8000 ++}; ++ ++ ++/* p.247 */ ++ ++enum { ++ kLoginWithoutID = 0, ++ kLoginWithID = 1, ++ kReconnWithID = 2, ++ kLoginWithTimeAndID = 3, ++ kReconnWithTimeAndID = 4, ++ kRecon1Login = 5, ++ kRecon1ReconnectLogin = 6, ++ kRecon1Refresh = 7, kGetKerberosSessionKey = 8 ++}; ++ ++ ++#define AFP_CHMOD_ALLOWED_BITS_22 \ ++ (S_IRUSR |S_IWUSR | S_IRGRP | S_IWGRP |S_IROTH | S_IWOTH | S_IFREG ) ++ ++ ++#endif ++ ++ ++ ++ +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/codepage.h afpfs-ng-0.8.1.patch/include/afpfs-ng/codepage.h +--- afpfs-ng-0.8.1/include/afpfs-ng/codepage.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/codepage.h 2011-09-10 12:13:50.113124518 +0200 +@@ -0,0 +1,11 @@ ++#ifndef __CODE_PAGE_H_ ++#define __CODE_PAGE_H_ ++int convert_utf8dec_to_utf8pre(const char *src, int src_len, ++ char * dest, int dest_len); ++int convert_utf8pre_to_utf8dec(const char * src, int src_len, ++ char * dest, int dest_len); ++int convert_path_to_unix(char encoding, char * dest, ++ char * src, int dest_len); ++int convert_path_to_afp(char encoding, char * dest, ++ char * src, int dest_len); ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/dsi.h afpfs-ng-0.8.1.patch/include/afpfs-ng/dsi.h +--- afpfs-ng-0.8.1/include/afpfs-ng/dsi.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/dsi.h 2011-09-10 12:13:50.115124544 +0200 +@@ -0,0 +1,33 @@ ++ ++#ifndef __DSI_H_ ++#define __DSI_H_ ++ ++#include "afpfs-ng/afp.h" ++ ++struct dsi_request ++{ ++ unsigned short requestid; ++ unsigned char subcommand; ++ void * other; ++ unsigned char wait; ++ pthread_cond_t condition_cond; ++ struct dsi_request * next; ++ int return_code; ++}; ++ ++int dsi_receive(struct afp_server * server, void * data, int size); ++int dsi_getstatus(struct afp_server * server); ++ ++int dsi_opensession(struct afp_server *server); ++ ++int dsi_send(struct afp_server *server, char * msg, int size,int wait,unsigned char subcommand, void ** other); ++struct dsi_session * dsi_create(struct afp_server *server); ++int dsi_restart(struct afp_server *server); ++int dsi_recv(struct afp_server * server); ++ ++#define DSI_BLOCK_TIMEOUT -1 ++#define DSI_DONT_WAIT 0 ++#define DSI_DEFAULT_TIMEOUT 5 ++ ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/libafpclient.h afpfs-ng-0.8.1.patch/include/afpfs-ng/libafpclient.h +--- afpfs-ng-0.8.1/include/afpfs-ng/libafpclient.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/libafpclient.h 2011-09-10 12:13:50.115124544 +0200 +@@ -0,0 +1,50 @@ ++ ++#ifndef __CLIENT_H_ ++#define __CLIENT_H_ ++ ++#include ++#include ++ ++#define MAX_CLIENT_RESPONSE 2048 ++ ++ ++enum loglevels { ++ AFPFSD, ++}; ++ ++struct afp_server; ++struct afp_volume; ++ ++struct libafpclient { ++ int (*unmount_volume) (struct afp_volume * volume); ++ void (*log_for_client)(void * priv, ++ enum loglevels loglevel, int logtype, const char *message); ++ void (*forced_ending_hook)(void); ++ int (*scan_extra_fds)(int command_fd,fd_set *set, int * max_fd); ++ void (*loop_started)(void); ++} ; ++ ++extern struct libafpclient * libafpclient; ++ ++void libafpclient_register(struct libafpclient * tmpclient); ++ ++ ++void signal_main_thread(void); ++ ++/* These are logging functions */ ++ ++#define MAXLOGSIZE 2048 ++ ++#define LOG_METHOD_SYSLOG 1 ++#define LOG_METHOD_STDOUT 2 ++ ++void set_log_method(int m); ++ ++ ++void log_for_client(void * priv, ++ enum loglevels loglevel, int logtype, char * message,...); ++ ++void stdout_log_for_client(void * priv, ++ enum loglevels loglevel, int logtype, const char *message); ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/Makefile.am afpfs-ng-0.8.1.patch/include/afpfs-ng/Makefile.am +--- afpfs-ng-0.8.1/include/afpfs-ng/Makefile.am 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/Makefile.am 2011-09-10 12:13:50.115124544 +0200 +@@ -0,0 +1,6 @@ ++## Process this file with automake to produce Makefile.in ++ ++afpfsincludedir = $(includedir)/afpfs-ng ++ ++afpfsinclude_HEADERS = afp.h afp_protocol.h libafpclient.h ++nodist_afpfsinclude_HEADERS = codepage.h dsi.h map_def.h midlevel.h uams_def.h utils.h +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/map_def.h afpfs-ng-0.8.1.patch/include/afpfs-ng/map_def.h +--- afpfs-ng-0.8.1/include/afpfs-ng/map_def.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/map_def.h 2011-09-10 12:13:50.116124557 +0200 +@@ -0,0 +1,15 @@ ++#ifndef __MAP_H_ ++#define __MAP_H_ ++ ++#include "afpfs-ng/afp.h" ++ ++#define AFP_MAPPING_UNKNOWN 0 ++#define AFP_MAPPING_COMMON 1 ++#define AFP_MAPPING_LOGINIDS 2 ++#define AFP_MAPPING_NAME 3 ++ ++unsigned int map_string_to_num(char * name); ++char * get_mapping_name(struct afp_volume * volume); ++ ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/midlevel.h afpfs-ng-0.8.1.patch/include/afpfs-ng/midlevel.h +--- afpfs-ng-0.8.1/include/afpfs-ng/midlevel.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/midlevel.h 2011-09-10 12:13:50.116124557 +0200 +@@ -0,0 +1,64 @@ ++#ifndef __MIDLEVEL_H_ ++#define __MIDLEVEL_H_ ++ ++#include ++#include "afpfs-ng/afp.h" ++ ++int ml_open(struct afp_volume * volume, const char *path, int flags, ++ struct afp_file_info **newfp); ++ ++int ml_creat(struct afp_volume * volume, const char *path,mode_t mode); ++ ++int ml_readdir(struct afp_volume * volume, ++ const char *path, ++ struct afp_file_info **base); ++ ++int ml_read(struct afp_volume * volume, const char *path, ++ char *buf, size_t size, off_t offset, ++ struct afp_file_info *fp, int * eof); ++ ++int ml_chmod(struct afp_volume * vol, const char * path, mode_t mode); ++ ++int ml_unlink(struct afp_volume * vol, const char *path); ++ ++int ml_mkdir(struct afp_volume * vol, const char * path, mode_t mode); ++ ++int ml_close(struct afp_volume * volume, const char * path, ++ struct afp_file_info * fp); ++ ++int ml_getattr(struct afp_volume * volume, const char *path, ++ struct stat *stbuf); ++ ++int ml_write(struct afp_volume * volume, const char * path, ++ const char *data, size_t size, off_t offset, ++ struct afp_file_info * fp, uid_t uid, ++ gid_t gid); ++ ++int ml_readlink(struct afp_volume * vol, const char * path, ++ char *buf, size_t size); ++ ++int ml_rmdir(struct afp_volume * vol, const char *path); ++ ++int ml_chown(struct afp_volume * vol, const char * path, ++ uid_t uid, gid_t gid); ++ ++int ml_truncate(struct afp_volume * vol, const char * path, off_t offset); ++ ++int ml_utime(struct afp_volume * vol, const char * path, ++ struct utimbuf * timebuf); ++ ++int ml_symlink(struct afp_volume *vol, const char * path1, const char * path2); ++ ++int ml_rename(struct afp_volume * vol, ++ const char * path_from, const char * path_to); ++ ++int ml_statfs(struct afp_volume * vol, const char *path, struct statvfs *stat); ++ ++void afp_ml_filebase_free(struct afp_file_info **filebase); ++ ++int ml_passwd(struct afp_server *server, ++ char * username, char * oldpasswd, char * newpasswd); ++ ++ ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/uams_def.h afpfs-ng-0.8.1.patch/include/afpfs-ng/uams_def.h +--- afpfs-ng-0.8.1/include/afpfs-ng/uams_def.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/uams_def.h 2011-09-10 12:13:50.116124557 +0200 +@@ -0,0 +1,16 @@ ++#ifndef __UAM_DEFS_H_ ++#define __UAM_DEFS_H_ ++ ++#define UAM_NOUSERAUTHENT 0x1 ++#define UAM_CLEARTXTPASSWRD 0x2 ++#define UAM_RANDNUMEXCHANGE 0x4 ++#define UAM_2WAYRANDNUM 0x8 ++#define UAM_DHCAST128 0x10 ++#define UAM_CLIENTKRB 0x20 ++#define UAM_DHX2 0x40 ++#define UAM_RECON1 0x80 ++ ++int uam_string_to_bitmap(char * name); ++char * uam_bitmap_to_string(unsigned int bitmap); ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/utils.h afpfs-ng-0.8.1.patch/include/afpfs-ng/utils.h +--- afpfs-ng-0.8.1/include/afpfs-ng/utils.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/utils.h 2011-09-10 12:13:50.116124557 +0200 +@@ -0,0 +1,43 @@ ++#ifndef __UTILS_H_ ++#define __UTILS_H_ ++#include ++ ++#include "afpfs-ng/afp.h" ++ ++#if BYTE_ORDER == BIG_ENDIAN ++#define hton64(x) (x) ++#define ntoh64(x) (x) ++#else /* BYTE_ORDER == BIG_ENDIAN */ ++#define hton64(x) ((u_int64_t) (htonl(((x) >> 32) & 0xffffffffLL)) | \ ++ (u_int64_t) ((htonl(x) & 0xffffffffLL) << 32)) ++#define ntoh64(x) (hton64(x)) ++#endif /* BYTE_ORDER == BIG_ENDIAN */ ++ ++#define min(a,b) (((a)<(b)) ? (a) : (b)) ++#define max(a,b) (((a)>(b)) ? (a) : (b)) ++ ++ ++ ++unsigned char unixpath_to_afppath( ++ struct afp_server * server, ++ char * buf); ++ ++unsigned char sizeof_path_header(struct afp_server * server); ++ ++ ++ ++unsigned char copy_from_pascal(char *dest, char *pascal,unsigned int max_len) ; ++unsigned short copy_from_pascal_two(char *dest, char *pascal,unsigned int max_len); ++ ++unsigned char copy_to_pascal(char *dest, const char *src); ++unsigned short copy_to_pascal_two(char *dest, const char *src); ++ ++void copy_path(struct afp_server * server, char * dest, const char * pathname, unsigned char len); ++ ++ ++char * create_path(struct afp_server * server, char * pathname, unsigned short * len); ++ ++ ++int invalid_filename(struct afp_server * server, const char * filename); ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afp.h afpfs-ng-0.8.1.patch/include/afp.h +--- afpfs-ng-0.8.1/include/afp.h 2008-03-08 17:08:18.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afp.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,533 +0,0 @@ +- +-#ifndef _AFP_H_ +-#define _AFP_H_ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +- +-#define AFPFS_VERSION "0.8.1" +- +-/* This is the maximum AFP version this library supports */ +-#define AFP_MAX_SUPPORTED_VERSION 32 +- +-/* afp_url is used to pass locations around */ +-struct afp_url { +- enum {TCPIP,AT} protocol; +- char username[AFP_MAX_USERNAME_LEN]; +- char uamname[50]; +- char password[AFP_MAX_PASSWORD_LEN]; +- char servername[AFP_SERVER_NAME_UTF8_LEN]; +- int port; +- char volumename[AFP_VOLUME_NAME_UTF8_LEN]; +- char path[AFP_MAX_PATH]; +- +- int requested_version; +- char zone[AFP_ZONE_LEN]; /* Only used for Appletalk */ +- char volpassword[9];; +-}; +- +-struct afp_token { +- unsigned int length; +- char data[AFP_TOKEN_MAX_LEN]; +-}; +- +-#define SERVER_MAX_VERSIONS 10 +-#define SERVER_MAX_UAMS 10 +- +-struct afp_rx_buffer { +- unsigned int size; +- unsigned int maxsize; +- char * data; +- int errorcode; +-}; +- +- +-struct afp_file_info { +- unsigned short attributes; +- unsigned int did; +- unsigned int creation_date; +- unsigned int modification_date; +- unsigned int backup_date; +- unsigned int fileid; +- unsigned short offspring; +- char sync; +- char finderinfo[32]; +- char name[AFP_MAX_PATH]; +- char basename[AFP_MAX_PATH]; +- char translated_name[AFP_MAX_PATH]; +- struct afp_unixprivs unixprivs; +- unsigned int accessrights; +- struct afp_file_info * next; +- struct afp_file_info * largelist_next; +- unsigned char isdir; +- unsigned long long size; +- unsigned short resourcesize; +- unsigned int resource; +- unsigned short forkid; +- struct afp_icon * icon; +- int eof; +-}; +- +- +-#define VOLUME_EXTRA_FLAGS_VOL_CHMOD_KNOWN 0x1 +-#define VOLUME_EXTRA_FLAGS_VOL_CHMOD_BROKEN 0x2 +-#define VOLUME_EXTRA_FLAGS_SHOW_APPLEDOUBLE 0x4 +-#define VOLUME_EXTRA_FLAGS_VOL_SUPPORTS_UNIX 0x8 +-#define VOLUME_EXTRA_FLAGS_NO_LOCKING 0x10 +-#define VOLUME_EXTRA_FLAGS_IGNORE_UNIXPRIVS 0x20 +-#define VOLUME_EXTRA_FLAGS_READONLY 0x40 +- +-#define AFP_VOLUME_UNMOUNTED 0 +-#define AFP_VOLUME_MOUNTED 1 +-#define AFP_VOLUME_UNMOUNTING 2 +- +-struct afp_volume { +- unsigned short volid; +- char flags; /* This is from afpGetSrvrParms */ +- unsigned short attributes; /* This is from VolOpen */ +- unsigned short signature; /* This is fixed or variable */ +- unsigned int creation_date; +- unsigned int modification_date; +- unsigned int backup_date; +- struct statvfs stat; +- unsigned char mounted; +- char mountpoint[255]; +- struct afp_server * server; +- char volume_name[AFP_VOLUME_NAME_LEN]; +- char volume_name_printable[AFP_VOLUME_NAME_UTF8_LEN]; +- unsigned short dtrefnum; +- char volpassword[AFP_VOLPASS_LEN]; +- unsigned int extra_flags; /* This is an afpfs-ng specific field */ +- +- /* Our directory ID cache */ +- struct did_cache_entry * did_cache_base; +- pthread_mutex_t did_cache_mutex; +- +- /* Our journal of open forks */ +- struct afp_file_info * open_forks; +- pthread_mutex_t open_forks_mutex; +- +- /* Used to trigger startup */ +- pthread_cond_t startup_condition_cond; +- +- struct { +- uint64_t hits; +- uint64_t misses; +- uint64_t expired; +- uint64_t force_removed; +- } did_cache_stats; +- +- void * priv; /* This is a private structure for fuse/cmdline, etc */ +- pthread_t thread; /* This is the per-volume thread */ +- +- int mapping; +- +-}; +- +-#define SERVER_STATE_CONNECTED 1 +-#define SERVER_STATE_DISCONNECTED 2 +- +-enum server_type{ +- AFPFS_SERVER_TYPE_UNKNOWN, +- AFPFS_SERVER_TYPE_NETATALK, +- AFPFS_SERVER_TYPE_AIRPORT, +- AFPFS_SERVER_TYPE_MACINTOSH, +-}; +- +-#define is_netatalk(x) ( (x)->machine_type == AFPFS_SERVER_TYPE_NETATALK ) +-#define is_airport(x) ( (x)->machine_type == AFPFS_SERVER_TYPE_AIRPORT ) +-#define is_macintosh(x) ( (x)->machine_type == AFPFS_SERVER_TYPE_MACINTOSH ) +- +- +- +-struct afp_versions { +- char *av_name; +- int av_number; +-}; +-extern struct afp_versions afp_versions[]; +- +-struct afp_server { +- +- /* Our buffer sizes */ +- unsigned int tx_quantum; +- unsigned int rx_quantum; +- +- unsigned int tx_delay; +- +- /* Connection information */ +- struct sockaddr_in address; +- int fd; +- +- /* Some stats, for information only */ +- struct { +- uint64_t runt_packets; +- uint64_t incoming_dsi; +- uint64_t rx_bytes; +- uint64_t tx_bytes; +- uint64_t requests_pending; +- } stats; +- +- /* General information */ +- char server_name[AFP_SERVER_NAME_LEN]; +- char server_name_utf8[AFP_SERVER_NAME_UTF8_LEN]; +- char server_name_printable[AFP_SERVER_NAME_UTF8_LEN]; +- +- char machine_type[17]; +- char icon[256]; +- char signature[16]; +- unsigned short flags; +- int connect_state; +- enum server_type server_type; +- +- /* This is the time we connected */ +- time_t connect_time; +- +- /* UAMs */ +- unsigned int supported_uams; +- unsigned int using_uam; +- +- /* Authentication */ +- char username[AFP_MAX_USERNAME_LEN]; +- char password[AFP_MAX_PASSWORD_LEN]; +- +- /* Session */ +- struct afp_token token; +- char need_resume; +- +- /* Versions */ +- unsigned char requested_version; +- unsigned char versions[SERVER_MAX_VERSIONS]; +- struct afp_versions *using_version; +- +- /* Volumes */ +- unsigned char num_volumes; +- struct afp_volume * volumes; +- +- void * dsi; +- unsigned int exit_flag; +- +- /* Our DSI request queue */ +- pthread_mutex_t requestid_mutex; +- pthread_mutex_t request_queue_mutex; +- unsigned short lastrequestid; +- unsigned short expectedrequestid; +- struct dsi_request * command_requests; +- +- +- char loginmesg[200]; +- char servermesg[200]; +- char path_encoding; +- +- /* This is the data for the incoming buffer */ +- char * incoming_buffer; +- int data_read; +- int bufsize; +- +- /* And this is for the outgoing queue */ +- pthread_mutex_t send_mutex; +- +- /* This is for user mapping */ +- struct passwd passwd; +- unsigned int server_uid, server_gid; +- int server_gid_valid; +- +- struct afp_server *next; +- +- /* These are for DSI attention packets */ +- unsigned int attention_quantum; +- unsigned int attention_len; +- char * attention_buffer; +- +-}; +- +-struct afp_extattr_info { +- unsigned int maxsize; +- unsigned int size; +- char data[1024]; +-}; +-struct afp_comment { +- unsigned int maxsize; +- unsigned int size; +- char *data; +-}; +- +-struct afp_icon { +- unsigned int maxsize; +- unsigned int size; +- char *data; +-}; +- +-#define AFP_DEFAULT_ATTENTION_QUANTUM 1024 +- +-void afp_unixpriv_to_stat(struct afp_file_info *fp, +- struct stat *stat); +- +-int init_uams(void) ; +- +-unsigned int find_uam_by_name(const char * name); +-char * uam_bitmap_to_string(unsigned int bitmap); +- +- +-char * get_uam_names_list(void); +- +-unsigned int default_uams_mask(void); +- +-struct afp_volume * find_volume_by_name(struct afp_server * server, +- const char * volname); +- +-struct afp_connection_request { +- unsigned int uam_mask; +- struct afp_url url; +-}; +- +-void afp_default_url(struct afp_url *url); +-int afp_parse_url(struct afp_url * url, const char * toparse, int verbose); +-void afp_print_url(struct afp_url * url); +-int afp_url_validate(char * url_string, struct afp_url * valid_url); +- +-int afp_list_volnames(struct afp_server * server, char * names, int max); +- +-/* User mapping */ +-int afp_detect_mapping(struct afp_volume * volume); +- +-/* These are some functions that help with simple status text generation */ +- +-int afp_status_header(char * text, int * len); +-int afp_status_server(struct afp_server * s,char * text, int * len); +- +- +-struct afp_server * afp_server_full_connect(void * priv, struct afp_connection_request * req); +- +-void * just_end_it_now(void *other); +-void add_fd_and_signal(int fd); +-void loop_disconnect(struct afp_server *s); +-void afp_wait_for_started_loop(void); +- +- +-struct afp_versions * pick_version(unsigned char *versions, +- unsigned char requested) ; +-int pick_uam(unsigned int u1, unsigned int u2); +- +-int afp_server_login(struct afp_server *server, +- char * mesg, unsigned int *l, unsigned int max); +- +- +-int afp_dologin(struct afp_server *server, +- unsigned int uam, char * username, char * passwd); +- +-void afp_free_server(struct afp_server **server); +- +-struct afp_server * afp_server_init(struct sockaddr_in * address); +-int afp_get_address(void * priv, const char * hostname, unsigned int port, +- struct sockaddr_in * address); +- +- +-int afp_main_loop(int command_fd); +-int afp_main_quick_startup(pthread_t * thread); +- +-int afp_server_destroy(struct afp_server *s) ; +-int afp_server_reconnect(struct afp_server * s, char * mesg, +- unsigned int *l, unsigned int max); +-int afp_server_connect(struct afp_server *s, int full); +- +-struct afp_server * afp_server_complete_connection( +- void * priv, +- struct afp_server * server, +- struct sockaddr_in * address, unsigned char * versions, +- unsigned int uams, char * username, char * password, +- unsigned int requested_version, unsigned int uam_mask); +- +-int afp_connect_volume(struct afp_volume * volume, struct afp_server * server, +- char * mesg, unsigned int * l, unsigned int max); +-int something_is_mounted(struct afp_server * server); +- +-int add_cache_entry(struct afp_file_info * file) ; +-struct afp_file_info * get_cache_by_name(char * name); +-struct afp_server * find_server_by_address(struct sockaddr_in * address); +-struct afp_server * find_server_by_signature(char * signature); +-struct afp_server * find_server_by_name(char * name); +-int server_still_valid(struct afp_server * server); +- +- +-struct afp_server * get_server_base(void); +-int afp_server_remove(struct afp_server * server); +- +-int afp_unmount_volume(struct afp_volume * volume); +-int afp_unmount_all_volumes(struct afp_server * server); +- +-#define volume_is_readonly(x) (((x)->attributes&kReadOnly) || \ +- ((x)->extra_flags & VOLUME_EXTRA_FLAGS_READONLY)) +- +-int afp_opendt(struct afp_volume *volume, unsigned short * refnum); +- +-int afp_closedt(struct afp_server * server, unsigned short * refnum); +- +-int afp_getcomment(struct afp_volume *volume, unsigned int did, +- const char * pathname, struct afp_comment * comment); +- +-int afp_addcomment(struct afp_volume *volume, unsigned int did, +- const char * pathname, char * comment,uint64_t *size); +- +-int afp_geticon(struct afp_volume * volume, unsigned int filecreator, +- unsigned int filetype, unsigned char icontype, +- unsigned short length, struct afp_icon * icon); +- +-/* Things you want to do to a server */ +- +-int afp_getsrvrmsg(struct afp_server *server, unsigned short messagetype,unsigned char utf8, unsigned char block, char * mesg); +- +-int afp_login(struct afp_server *server, char * uaname, +- char * userauthinfo, unsigned int userauthinfo_len, +- struct afp_rx_buffer *rx); +- +-int afp_changepassword(struct afp_server *server, char * uaname, +- char * userauthinfo, unsigned int userauthinfo_len, +- struct afp_rx_buffer *rx); +- +-int afp_logincont(struct afp_server *server, unsigned short id, +- char * userauthinfo, unsigned int userauthinfo_len, +- struct afp_rx_buffer *rx); +- +-int afp_getsessiontoken(struct afp_server * server, int type, +- unsigned int timestamp, struct afp_token *outgoing_token, +- struct afp_token * incoming_token); +- +-int afp_getsrvrparms(struct afp_server *server); +- +-int afp_logout(struct afp_server *server,unsigned char wait); +- +-int afp_mapname(struct afp_server * server, unsigned char subfunction, +- char * name, unsigned int * id); +- +-int afp_mapid(struct afp_server * server, unsigned char subfunction, +- unsigned int id, char *name); +- +-int afp_getuserinfo(struct afp_server * server, int thisuser, +- unsigned int userid, unsigned short bitmap, +- unsigned int *newuid, unsigned int *newgid); +- +-int afp_zzzzz(struct afp_server *server); +- +-int afp_volopen(struct afp_volume * volume, +- unsigned short bitmap, char * password); +- +-int afp_flush(struct afp_volume * volume); +- +-int afp_getfiledirparms(struct afp_volume *volume, unsigned int did, +- unsigned int filebitmap, unsigned int dirbitmap, const char * pathname, +- struct afp_file_info *fp); +- +-int afp_enumerate(struct afp_volume * volume, +- unsigned int dirid, +- unsigned int filebitmap, unsigned int dirbitmap, +- unsigned short reqcount, +- unsigned short startindex, +- char * path, +- struct afp_file_info ** file_p); +- +-int afp_enumerateext2(struct afp_volume * volume, +- unsigned int dirid, +- unsigned int filebitmap, unsigned int dirbitmap, +- unsigned short reqcount, +- unsigned long startindex, +- char * path, +- struct afp_file_info ** file_p); +- +-int afp_openfork(struct afp_volume * volume, +- unsigned char forktype, +- unsigned int dirid, +- unsigned short accessmode, +- char * filename, +- struct afp_file_info *fp); +- +-int afp_read(struct afp_volume * volume, unsigned short forkid, +- uint32_t offset, +- uint32_t count, struct afp_rx_buffer * rx); +- +-int afp_readext(struct afp_volume * volume, unsigned short forkid, +- uint64_t offset, +- uint64_t count, struct afp_rx_buffer * rx); +- +-int afp_getvolparms(struct afp_volume * volume, unsigned short bitmap); +- +- +-int afp_createdir(struct afp_volume * volume, unsigned int dirid, const char * pathname, unsigned int *did_p); +- +-int afp_delete(struct afp_volume * volume, +- unsigned int dirid, char * pathname); +- +- +-int afp_createfile(struct afp_volume * volume, unsigned char flag, +- unsigned int did, char * pathname); +- +-int afp_write(struct afp_volume * volume, unsigned short forkid, +- uint32_t offset, uint32_t reqcount, +- char * data, uint32_t * written); +- +-int afp_writeext(struct afp_volume * volume, unsigned short forkid, +- uint64_t offset, uint64_t reqcount, +- char * data, uint64_t * written); +- +-int afp_flushfork(struct afp_volume * volume, unsigned short forkid); +- +-int afp_closefork(struct afp_volume * volume, unsigned short forkid); +-int afp_setfileparms(struct afp_volume * volume, +- unsigned int dirid, const char * pathname, unsigned short bitmap, +- struct afp_file_info *fp); +-int afp_setfiledirparms(struct afp_volume * volume, +- unsigned int dirid, const char * pathname, unsigned short bitmap, +- struct afp_file_info *fp); +- +-int afp_setdirparms(struct afp_volume * volume, +- unsigned int dirid, const char * pathname, unsigned short bitmap, +- struct afp_file_info *fp); +- +-int afp_volclose(struct afp_volume * volume); +- +- +-int afp_setforkparms(struct afp_volume *volume, +- unsigned short forkid, unsigned short bitmap, unsigned long len); +- +-int afp_byterangelock(struct afp_volume * volume, +- unsigned char flag, +- unsigned short forkid, +- uint32_t offset, +- uint32_t len, uint32_t *generated_offset); +- +-int afp_byterangelockext(struct afp_volume * volume, +- unsigned char flag, +- unsigned short forkid, +- uint64_t offset, +- uint64_t len, uint64_t *generated_offset); +- +-int afp_moveandrename(struct afp_volume *volume, +- unsigned int src_did, +- unsigned int dst_did, +- char * src_path, char * dst_path, char *new_name); +- +-int afp_rename(struct afp_volume * volume, +- unsigned int dirid, +- char * path_from, char * path_to); +- +-int afp_listextattr(struct afp_volume * volume, +- unsigned int dirid, unsigned short bitmap, +- char * pathname, struct afp_extattr_info * info); +- +-/* This is a currently undocumented command */ +-int afp_newcommand76(struct afp_volume * volume, unsigned int dlen, char * data); +- +-/* For debugging */ +-char * afp_get_command_name(char code); +- +- +-#endif +diff -Naur afpfs-ng-0.8.1/include/afp_protocol.h afpfs-ng-0.8.1.patch/include/afp_protocol.h +--- afpfs-ng-0.8.1/include/afp_protocol.h 2008-02-18 04:33:43.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afp_protocol.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,361 +0,0 @@ +- +-#ifndef _AFP_PROTOCOL_H_ +-#define _AFP_PROTOCOL_H_ +- +-#include +-#include +-#include +-#include +- +-/* This file defines constants for the Apple File Protocol. +- All page references are from "Apple Filing Protocol Programming" version 3.2. +- except where noted. +-*/ +- +-#define AFP_SERVER_NAME_LEN 33 +-#define AFP_SERVER_NAME_UTF8_LEN 255 +-#define AFP_VOLUME_NAME_LEN 33 +-#define AFP_VOLUME_NAME_UTF8_LEN 33 +-#define AFP_SIGNATURE_LEN 16 +-#define AFP_MACHINETYPE_LEN 33 +-#define AFP_LOGINMESG_LEN 200 +-#define AFP_VOLPASS_LEN 8 +-#define AFP_HOSTNAME_LEN 255 +-/* This is actually just a guess, and only used for appletalk */ +-#define AFP_ZONE_LEN 255 +- +-#define AFP_SERVER_ICON_LEN 256 +- +- +-#define AFP_MAX_USERNAME_LEN 127 +-#define AFP_MAX_PASSWORD_LEN 127 +- +- +-/* This is the maximum length of any UAM string */ +-#define AFP_UAM_LENGTH 24 +- +-/* This is the maximum length of any path description */ +-#define AFP_MAX_PATH 768 +- +-#define AFP_VOL_FLAT 1 +-#define AFP_VOL_FIXED 2 +-#define AFP_VOL_VARIABLE 3 +- +-/* The root directory ID, p.26 */ +- +-#define AFP_ROOT_DID 2 +- +-/* Path type constants, p.249 */ +- +-enum { +-kFPShortName = 1, +-kFPLongName = 2, +-kFPUTF8Name = 3 +-}; +- +-/* fork types */ +- +-#define AFP_FORKTYPE_DATA 0x0 +-#define AFP_FORKTYPE_RESOURCE 0x80 +- +-/* openfork access modes, from p.196 */ +- +-#define AFP_OPENFORK_ALLOWREAD 1 +-#define AFP_OPENFORK_ALLOWWRITE 2 +-#define AFP_OPENFORK_DENYREAD 0x10 +-#define AFP_OPENFORK_DENYWRITE 0x20 +- +-/* Message type for getsrvmesg, p. 169*/ +- +-typedef enum { +- AFPMESG_LOGIN = 0, +- AFPMESG_SERVER = 1 +-} afpmessage_t; +- +-/* Message bitmap for getsrvrmsg */ +- +-#define AFP_GETSRVRMSG_UTF8 0x2 +-#define AFP_GETSRVRMSG_GETMSG 0x1 +- +- +-/* Maximum Version length, p.17 */ +-#define AFP_MAX_VERSION_LENGTH 16 +- +-/* Maximum length of a token, this is undocumented */ +-#define AFP_TOKEN_MAX_LEN 256 +- +-/* The maximum size of a file for AFP 2 */ +-#define AFP_MAX_AFP2_FILESIZE (4294967296) +- +-/* Unix privs, p.240 */ +- +-struct afp_unixprivs { +- uint32_t uid __attribute__((__packed__)); +- uint32_t gid __attribute__((__packed__)); +- uint32_t permissions __attribute__((__packed__)); +- uint32_t ua_permissions __attribute__((__packed__)); +- +-}; +- +- +-/* AFP Volume attributes bitmap, p.241 */ +- +-enum { +- kReadOnly = 0x01, +- kHasVolumePassword = 0x02, +- kSupportsFileIDs = 0x04, +- kSupportsCatSearch = 0x08, +- kSupportsBlankAccessPrivs = 0x10, +- kSupportsUnixPrivs = 0x20, +- kSupportsUTF8Names = 0x40, +- kNoNetworkUserIDs = 0x80, +- kDefaultPrivsFromParent = 0x100, +- kNoExchangeFiles = 0x200, +- kSupportsExtAttrs = 0x400, +- kSupportsACLs=0x800 +-}; +- +-/* AFP file creation constantes, p.250 */ +-enum { +-kFPSoftCreate = 0, +-kFPHardCreate = 0x80 +-}; +- +-/* AFP Directory attributes, taken from the protocol guide p.236 */ +- +-enum { +- kFPAttributeBit = 0x1, +- kFPParentDirIDBit = 0x2, +- kFPCreateDateBit = 0x4, +- kFPModDateBit = 0x8, +- kFPBackupDateBit = 0x10, +- kFPFinderInfoBit = 0x20, +- kFPLongNameBit = 0x40, +- kFPShortNameBit = 0x80, +- kFPNodeIDBit = 0x100, +- kFPOffspringCountBit = 0x0200, +- kFPOwnerIDBit = 0x0400, +- kFPGroupIDBit = 0x0800, +- kFPAccessRightsBit = 0x1000, +- kFPProDOSInfoBit = 0x2000, // AFP version 2.2 and earlier +- kFPUTF8NameBit = 0x2000, // AFP version 3.0 and later +- kFPUnixPrivsBit = 0x8000 // AFP version 3.0 and later +-}; +- +-/* AFP File bitmap, p.238. These are the ones not in the AFP Directory +- attributes map. */ +- +-enum { +- kFPDataForkLenBit = 0x0200, +- kFPRsrcForkLenBit = 0x0400, +- kFPExtDataForkLenBit = 0x0800, // AFP version 3.0 and later +- kFPLaunchLimitBit = 0x1000, +- kFPExtRsrcForkLenBit = 0x4000, // AFP version 3.0 and later +-}; +- +-/* AFP Extended Attributes Bitmap, p.238 */ +- +-enum { +- kXAttrNoFollow = 0x1, +- kXAttrCreate = 0x2, +- kXAttrREplace=0x4 +-}; +- +- +-/* AFP function codes */ +-enum AFPFunction +-{ +- afpByteRangeLock = 1, afpCloseVol, afpCloseDir, afpCloseFork, +- afpCopyFile, afpCreateDir, afpCreateFile, +- afpDelete, afpEnumerate, afpFlush, afpFlushFork, +- afpGetForkParms = 14, afpGetSrvrInfo, afpGetSrvrParms, +- afpGetVolParms, afpLogin, afpLoginCont, afpLogout, afpMapID, +- afpMapName, afpMoveAndRename, afpOpenVol, afpOpenDir, afpOpenFork, +- afpRead, afpRename, afpSetDirParms, afpSetFileParms, +- afpSetForkParms, afpSetVolParms, afpWrite, afpGetFileDirParms, +- afpSetFileDirParms, afpChangePassword, +- afpGetUserInfo=37,afpGetSrvrMsg = 38, +- afpOpenDT=48, +- afpCloseDT=49, +- afpGetIcon=51, afpGetIconInfo=52, +- afpAddComment=56, afpRemoveComment=57, afpGetComment=58, +- afpByteRangeLockExt=59, afpReadExt, afpWriteExt, +- afpGetAuthMethods=62, +- afp_LoginExt=63, +- afpGetSessionToken=64, +- afpDisconnectOldSession=65, +- afpEnumerateExt=66, +- afpCatSearchExt = 67, +- afpEnumerateExt2 = 68, afpGetExtAttr, afpSetExtAttr, +- afpRemoveExtAttr , afpListExtAttrs, +- afpZzzzz = 122, +- afpAddIcon=192, +-}; +- +-/* AFP Volume bitmap. Take from 242 of the protocol guide. */ +-enum { +- kFPBadVolPre222Bitmap = 0xFe00, +- kFPBadVolBitmap = 0xF000, +- kFPVolAttributeBit = 0x1, +- kFPVolSignatureBit = 0x2, +- kFPVolCreateDateBit = 0x4, +- kFPVolModDateBit = 0x8, +- kFPVolBackupDateBit = 0x10, +- kFPVolIDBit = 0x20, +- kFPVolBytesFreeBit = 0x40, +- kFPVolBytesTotalBit = 0x80, +- kFPVolNameBit = 0x100, +- kFPVolExtBytesFreeBit = 0x200, +- kFPVolExtBytesTotalBit = 0x400, +- kFPVolBlockSizeBit = 0x800 +-}; +- +-/* AFP Attention Codes -- 4 bits */ +-#define AFPATTN_SHUTDOWN (1 << 15) /* shutdown/disconnect */ +-#define AFPATTN_CRASH (1 << 14) /* server crashed */ +-#define AFPATTN_MESG (1 << 13) /* server has message */ +-#define AFPATTN_NORECONNECT (1 << 12) /* don't reconnect */ +-/* server notification */ +-#define AFPATTN_NOTIFY (AFPATTN_MESG | AFPATTN_NORECONNECT) +- +-/* extended bitmap -- 12 bits. volchanged is only useful w/ a server +- * notification, and time is only useful for shutdown. */ +-#define AFPATTN_VOLCHANGED (1 << 0) /* volume has changed */ +-#define AFPATTN_TIME(x) ((x) & 0xfff) /* time in minutes */ +- +-#define kFPNoErr 0 +- +-/* AFP result codes, p252 */ +-#define kASPSessClosed -1072 +-#define kFPAccessDenied -5000 +-#define kFPAuthContinue -5001 +-#define kFPBadUAM -5002 +-#define kFPBadVersNum -5003 +-#define kFPBitmapErr -5004 +-#define kFPCantMove -5005 +-#define kFPDenyConflict -5006 +-#define kFPDirNotEmpty -5007 +-#define kFPDiskFull -5008 +-#define kFPEOFErr -5009 +-#define kFPFileBusy -5010 +-#define kFPFlatVol -5011 +-#define kFPItemNotFound -5012 +-#define kFPLockErr -5013 +-#define kFPMiscErr -5014 +-#define kFPNoMoreLocks -5015 +-#define kFPNoServer -5016 +-#define kFPObjectExists -5017 +-#define kFPObjectNotFound -5018 +-#define kFPParamErr -5019 +-#define kFPRangeNotLocked -5020 +-#define kFPRangeOverlap -5021 +-#define kFPSessClosed -5022 +-#define kFPUserNotAuth -5023 +-#define kFPCallNotSupported -5024 +-#define kFPObjectTypeErr -5025 +-#define kFPTooManyFilesOpen -5026 +-#define kFPServerGoingDown -5027 +-#define kFPCantRename -5028 +-#define kFPDirNotFound -5029 +-#define kFPIconTypeError -5030 +-#define kFPVolLocked -5031 +-#define kFPObjectLocked -5032 +-#define kFPContainsSharedErr -5033 +-#define kFPIDNotFound -5034 +-#define kFPIDExists -5035 +-#define kFPDiffVolErr -5036 +-#define kFPCatalogChanged -5037 +-#define kFPSameObjectErr -5038 +-#define kFPBadIDErr -5039 +-#define kFPPwdSameErr -5040 +-#define kFPPwdTooShortErr -5041 +-#define kFPPwdExpiredErr -5042 +-#define kFPInsideSharedErr -5043 +-#define kFPInsideTrashErr -5044 +-#define kFPPwdNeedsChangeErr -5045 +-#define kFPPwdPolicyErr -5046 +-#define kFPDiskQuotaExceeded –5047 +- +- +- +-/* These flags determine to lock or unlock in ByteRangeLock(Ext) */ +- +-enum { +-ByteRangeLock_Lock = 0, +-ByteRangeLock_Unlock = 1 +-}; +- +-/* These flags are used in volopen and getsrvrparm replies, p.171 */ +- +-#define HasConfigInfo 0x1 +-#define HasPassword 0x80 +- +-/* These are the subfunction for kFPMapID, as per p.248 */ +- +-enum { +-kUserIDToName = 1, +-kGroupIDToName = 2, +-kUserIDToUTF8Name = 3, +-kGroupIDToUTF8Name = 4, +-kUserUUIDToUTF8Name = 5, +-kGroupUUIDToUTF8Name = 6 +-}; +- +- +-/* These are the subfunction flags described in the FPMapName command, p.286. +- Note that this is different than what's described on p. 186. */ +- +-enum { +-kNameToUserID = 1, +-kNameToGroupID = 2, +-kUTF8NameToUserID = 3, +-kUTF8NameToGroupID = 4, +-kUTF8NameToUserUUID = 5, +-kUTF8NameToGroupUUID = 6 +-}; +- +-/* These are bits for FPGetUserInfo, p.173. */ +-#define kFPGetUserInfo_USER_ID 1 +-#define kFPGetUserInfo_PRI_GROUPID 2 +- +-/* Flags for the replies of GetSrvrInfo and DSI GetStatus, p.240 */ +- +-enum { +- kSupportsCopyfile = 0x01, +- kSupportsChgPwd = 0x02, +- kDontAllowSavePwd = 0x04, +- kSupportsSrvrMsg = 0x08, +- kSrvrSig = 0x10, +- kSupportsTCP = 0x20, +- kSupportsSrvrNotify = 0x40, +- kSupportsReconnect = 0x80, +- kSupportsDirServices = 0x100, +- kSupportsUTF8SrvrName = 0x200, +- kSupportsUUIDs = 0x400, +- kSupportsSuperClient = 0x8000 +-}; +- +- +-/* p.247 */ +- +-enum { +- kLoginWithoutID = 0, +- kLoginWithID = 1, +- kReconnWithID = 2, +- kLoginWithTimeAndID = 3, +- kReconnWithTimeAndID = 4, +- kRecon1Login = 5, +- kRecon1ReconnectLogin = 6, +- kRecon1Refresh = 7, kGetKerberosSessionKey = 8 +-}; +- +- +-#define AFP_CHMOD_ALLOWED_BITS_22 \ +- (S_IRUSR |S_IWUSR | S_IRGRP | S_IWGRP |S_IROTH | S_IWOTH | S_IFREG ) +- +- +-#endif +- +- +- +- +diff -Naur afpfs-ng-0.8.1/include/codepage.h afpfs-ng-0.8.1.patch/include/codepage.h +--- afpfs-ng-0.8.1/include/codepage.h 2007-09-23 16:21:30.000000000 +0200 ++++ afpfs-ng-0.8.1.patch/include/codepage.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,11 +0,0 @@ +-#ifndef __CODE_PAGE_H_ +-#define __CODE_PAGE_H_ +-int convert_utf8dec_to_utf8pre(const char *src, int src_len, +- char * dest, int dest_len); +-int convert_utf8pre_to_utf8dec(const char * src, int src_len, +- char * dest, int dest_len); +-int convert_path_to_unix(char encoding, char * dest, +- char * src, int dest_len); +-int convert_path_to_afp(char encoding, char * dest, +- char * src, int dest_len); +-#endif +diff -Naur afpfs-ng-0.8.1/include/dsi.h afpfs-ng-0.8.1.patch/include/dsi.h +--- afpfs-ng-0.8.1/include/dsi.h 2008-02-18 04:33:24.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/dsi.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,33 +0,0 @@ +- +-#ifndef __DSI_H_ +-#define __DSI_H_ +- +-#include "afp.h" +- +-struct dsi_request +-{ +- unsigned short requestid; +- unsigned char subcommand; +- void * other; +- unsigned char wait; +- pthread_cond_t condition_cond; +- struct dsi_request * next; +- int return_code; +-}; +- +-int dsi_receive(struct afp_server * server, void * data, int size); +-int dsi_getstatus(struct afp_server * server); +- +-int dsi_opensession(struct afp_server *server); +- +-int dsi_send(struct afp_server *server, char * msg, int size,int wait,unsigned char subcommand, void ** other); +-struct dsi_session * dsi_create(struct afp_server *server); +-int dsi_restart(struct afp_server *server); +-int dsi_recv(struct afp_server * server); +- +-#define DSI_BLOCK_TIMEOUT -1 +-#define DSI_DONT_WAIT 0 +-#define DSI_DEFAULT_TIMEOUT 5 +- +- +-#endif +diff -Naur afpfs-ng-0.8.1/include/libafpclient.h afpfs-ng-0.8.1.patch/include/libafpclient.h +--- afpfs-ng-0.8.1/include/libafpclient.h 2008-01-30 05:37:59.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/libafpclient.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,50 +0,0 @@ +- +-#ifndef __CLIENT_H_ +-#define __CLIENT_H_ +- +-#include +-#include +- +-#define MAX_CLIENT_RESPONSE 2048 +- +- +-enum loglevels { +- AFPFSD, +-}; +- +-struct afp_server; +-struct afp_volume; +- +-struct libafpclient { +- int (*unmount_volume) (struct afp_volume * volume); +- void (*log_for_client)(void * priv, +- enum loglevels loglevel, int logtype, const char *message); +- void (*forced_ending_hook)(void); +- int (*scan_extra_fds)(int command_fd,fd_set *set, int * max_fd); +- void (*loop_started)(void); +-} ; +- +-extern struct libafpclient * libafpclient; +- +-void libafpclient_register(struct libafpclient * tmpclient); +- +- +-void signal_main_thread(void); +- +-/* These are logging functions */ +- +-#define MAXLOGSIZE 2048 +- +-#define LOG_METHOD_SYSLOG 1 +-#define LOG_METHOD_STDOUT 2 +- +-void set_log_method(int m); +- +- +-void log_for_client(void * priv, +- enum loglevels loglevel, int logtype, char * message,...); +- +-void stdout_log_for_client(void * priv, +- enum loglevels loglevel, int logtype, const char *message); +- +-#endif +diff -Naur afpfs-ng-0.8.1/include/Makefile.am afpfs-ng-0.8.1.patch/include/Makefile.am +--- afpfs-ng-0.8.1/include/Makefile.am 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/Makefile.am 2011-09-10 12:13:50.126124692 +0200 +@@ -0,0 +1,3 @@ ++## Process this file with automake to produce Makefile.in ++ ++SUBDIRS = afpfs-ng +diff -Naur afpfs-ng-0.8.1/include/map_def.h afpfs-ng-0.8.1.patch/include/map_def.h +--- afpfs-ng-0.8.1/include/map_def.h 2008-01-17 05:55:46.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/map_def.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,15 +0,0 @@ +-#ifndef __MAP_H_ +-#define __MAP_H_ +- +-#include "afp.h" +- +-#define AFP_MAPPING_UNKNOWN 0 +-#define AFP_MAPPING_COMMON 1 +-#define AFP_MAPPING_LOGINIDS 2 +-#define AFP_MAPPING_NAME 3 +- +-unsigned int map_string_to_num(char * name); +-char * get_mapping_name(struct afp_volume * volume); +- +- +-#endif +diff -Naur afpfs-ng-0.8.1/include/midlevel.h afpfs-ng-0.8.1.patch/include/midlevel.h +--- afpfs-ng-0.8.1/include/midlevel.h 2007-12-24 20:39:25.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/midlevel.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,64 +0,0 @@ +-#ifndef __MIDLEVEL_H_ +-#define __MIDLEVEL_H_ +- +-#include +-#include "afp.h" +- +-int ml_open(struct afp_volume * volume, const char *path, int flags, +- struct afp_file_info **newfp); +- +-int ml_creat(struct afp_volume * volume, const char *path,mode_t mode); +- +-int ml_readdir(struct afp_volume * volume, +- const char *path, +- struct afp_file_info **base); +- +-int ml_read(struct afp_volume * volume, const char *path, +- char *buf, size_t size, off_t offset, +- struct afp_file_info *fp, int * eof); +- +-int ml_chmod(struct afp_volume * vol, const char * path, mode_t mode); +- +-int ml_unlink(struct afp_volume * vol, const char *path); +- +-int ml_mkdir(struct afp_volume * vol, const char * path, mode_t mode); +- +-int ml_close(struct afp_volume * volume, const char * path, +- struct afp_file_info * fp); +- +-int ml_getattr(struct afp_volume * volume, const char *path, +- struct stat *stbuf); +- +-int ml_write(struct afp_volume * volume, const char * path, +- const char *data, size_t size, off_t offset, +- struct afp_file_info * fp, uid_t uid, +- gid_t gid); +- +-int ml_readlink(struct afp_volume * vol, const char * path, +- char *buf, size_t size); +- +-int ml_rmdir(struct afp_volume * vol, const char *path); +- +-int ml_chown(struct afp_volume * vol, const char * path, +- uid_t uid, gid_t gid); +- +-int ml_truncate(struct afp_volume * vol, const char * path, off_t offset); +- +-int ml_utime(struct afp_volume * vol, const char * path, +- struct utimbuf * timebuf); +- +-int ml_symlink(struct afp_volume *vol, const char * path1, const char * path2); +- +-int ml_rename(struct afp_volume * vol, +- const char * path_from, const char * path_to); +- +-int ml_statfs(struct afp_volume * vol, const char *path, struct statvfs *stat); +- +-void afp_ml_filebase_free(struct afp_file_info **filebase); +- +-int ml_passwd(struct afp_server *server, +- char * username, char * oldpasswd, char * newpasswd); +- +- +- +-#endif +diff -Naur afpfs-ng-0.8.1/include/uams_def.h afpfs-ng-0.8.1.patch/include/uams_def.h +--- afpfs-ng-0.8.1/include/uams_def.h 2007-09-07 15:10:51.000000000 +0200 ++++ afpfs-ng-0.8.1.patch/include/uams_def.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,16 +0,0 @@ +-#ifndef __UAM_DEFS_H_ +-#define __UAM_DEFS_H_ +- +-#define UAM_NOUSERAUTHENT 0x1 +-#define UAM_CLEARTXTPASSWRD 0x2 +-#define UAM_RANDNUMEXCHANGE 0x4 +-#define UAM_2WAYRANDNUM 0x8 +-#define UAM_DHCAST128 0x10 +-#define UAM_CLIENTKRB 0x20 +-#define UAM_DHX2 0x40 +-#define UAM_RECON1 0x80 +- +-int uam_string_to_bitmap(char * name); +-char * uam_bitmap_to_string(unsigned int bitmap); +- +-#endif +diff -Naur afpfs-ng-0.8.1/include/utils.h afpfs-ng-0.8.1.patch/include/utils.h +--- afpfs-ng-0.8.1/include/utils.h 2008-02-18 04:33:58.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/utils.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,43 +0,0 @@ +-#ifndef __UTILS_H_ +-#define __UTILS_H_ +-#include +- +-#include "afp.h" +- +-#if BYTE_ORDER == BIG_ENDIAN +-#define hton64(x) (x) +-#define ntoh64(x) (x) +-#else /* BYTE_ORDER == BIG_ENDIAN */ +-#define hton64(x) ((u_int64_t) (htonl(((x) >> 32) & 0xffffffffLL)) | \ +- (u_int64_t) ((htonl(x) & 0xffffffffLL) << 32)) +-#define ntoh64(x) (hton64(x)) +-#endif /* BYTE_ORDER == BIG_ENDIAN */ +- +-#define min(a,b) (((a)<(b)) ? (a) : (b)) +-#define max(a,b) (((a)>(b)) ? (a) : (b)) +- +- +- +-unsigned char unixpath_to_afppath( +- struct afp_server * server, +- char * buf); +- +-unsigned char sizeof_path_header(struct afp_server * server); +- +- +- +-unsigned char copy_from_pascal(char *dest, char *pascal,unsigned int max_len) ; +-unsigned short copy_from_pascal_two(char *dest, char *pascal,unsigned int max_len); +- +-unsigned char copy_to_pascal(char *dest, const char *src); +-unsigned short copy_to_pascal_two(char *dest, const char *src); +- +-void copy_path(struct afp_server * server, char * dest, const char * pathname, unsigned char len); +- +- +-char * create_path(struct afp_server * server, char * pathname, unsigned short * len); +- +- +-int invalid_filename(struct afp_server * server, const char * filename); +- +-#endif +diff -Naur afpfs-ng-0.8.1/lib/afp.c afpfs-ng-0.8.1.patch/lib/afp.c +--- afpfs-ng-0.8.1/lib/afp.c 2008-03-08 03:44:16.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/afp.c 2011-09-10 12:13:50.131124759 +0200 +@@ -9,7 +9,7 @@ + + + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + #include + + #include +@@ -21,17 +21,17 @@ + #include + #include + +-#include "afp_protocol.h" +-#include "libafpclient.h" ++#include "afpfs-ng/afp_protocol.h" ++#include "afpfs-ng/libafpclient.h" + #include "server.h" +-#include "dsi.h" ++#include "afpfs-ng/dsi.h" + #include "dsi_protocol.h" +-#include "utils.h" ++#include "afpfs-ng/utils.h" + #include "afp_replies.h" + #include "afp_internal.h" + #include "did.h" + #include "forklist.h" +-#include "codepage.h" ++#include "afpfs-ng/codepage.h" + + struct afp_versions afp_versions[] = { + { "AFPVersion 1.1", 11 }, +diff -Naur afpfs-ng-0.8.1/lib/afp_internal.h afpfs-ng-0.8.1.patch/lib/afp_internal.h +--- afpfs-ng-0.8.1/lib/afp_internal.h 2007-11-09 05:27:20.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/afp_internal.h 2011-09-10 12:13:50.132124772 +0200 +@@ -1,7 +1,7 @@ + #ifndef _AFP_INTERNAL_H_ + #define _AFP_INTERNAL_H_ + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + + extern struct afp_versions afp_versions[]; + +diff -Naur afpfs-ng-0.8.1/lib/afp_url.c afpfs-ng-0.8.1.patch/lib/afp_url.c +--- afpfs-ng-0.8.1/lib/afp_url.c 2008-03-04 21:16:49.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/afp_url.c 2011-09-10 12:13:50.132124772 +0200 +@@ -3,7 +3,7 @@ + #include + #include + #include +-#include "afp.h" ++#include "afpfs-ng/afp.h" + + void afp_default_url(struct afp_url *url) + { +diff -Naur afpfs-ng-0.8.1/lib/client.c afpfs-ng-0.8.1.patch/lib/client.c +--- afpfs-ng-0.8.1/lib/client.c 2008-02-18 04:36:30.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/client.c 2011-09-10 12:13:50.132124772 +0200 +@@ -1,5 +1,5 @@ +-#include +-#include ++#include ++#include + + + struct libafpclient * libafpclient = NULL; +diff -Naur afpfs-ng-0.8.1/lib/codepage.c afpfs-ng-0.8.1.patch/lib/codepage.c +--- afpfs-ng-0.8.1/lib/codepage.c 2008-02-18 04:36:54.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/codepage.c 2011-09-10 12:13:50.133124786 +0200 +@@ -14,8 +14,8 @@ + + #include + #include +-#include "afp_protocol.h" +-#include "utils.h" ++#include "afpfs-ng/afp_protocol.h" ++#include "afpfs-ng/utils.h" + #include "unicode.h" + + int convert_utf8dec_to_utf8pre(const char *src, int src_len, +diff -Naur afpfs-ng-0.8.1/lib/connect.c afpfs-ng-0.8.1.patch/lib/connect.c +--- afpfs-ng-0.8.1/lib/connect.c 2008-02-18 04:38:59.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/connect.c 2011-09-10 12:13:50.133124786 +0200 +@@ -10,13 +10,13 @@ + #include + #include + +-#include "afp.h" +-#include "dsi.h" +-#include "utils.h" +-#include "uams_def.h" +-#include "codepage.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/uams_def.h" ++#include "afpfs-ng/codepage.h" + #include "users.h" +-#include "libafpclient.h" ++#include "afpfs-ng/libafpclient.h" + #include "server.h" + + +diff -Naur afpfs-ng-0.8.1/lib/did.c afpfs-ng-0.8.1.patch/lib/did.c +--- afpfs-ng-0.8.1/lib/did.c 2008-02-18 04:39:17.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/did.c 2011-09-10 12:13:50.133124786 +0200 +@@ -9,8 +9,8 @@ + #include + #include + +-#include "afp.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/afp_protocol.h" + + #undef DID_CACHE_DISABLE + +diff -Naur afpfs-ng-0.8.1/lib/dsi.c afpfs-ng-0.8.1.patch/lib/dsi.c +--- afpfs-ng-0.8.1/lib/dsi.c 2008-02-18 04:53:03.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/dsi.c 2011-09-10 12:13:50.134124800 +0200 +@@ -19,12 +19,12 @@ + #include + #include + +-#include "utils.h" +-#include "dsi.h" +-#include "afp.h" +-#include "uams_def.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/uams_def.h" + #include "dsi_protocol.h" +-#include "libafpclient.h" ++#include "afpfs-ng/libafpclient.h" + #include "afp_internal.h" + #include "afp_replies.h" + +diff -Naur afpfs-ng-0.8.1/lib/forklist.c afpfs-ng-0.8.1.patch/lib/forklist.c +--- afpfs-ng-0.8.1/lib/forklist.c 2008-01-17 05:49:16.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/forklist.c 2011-09-10 12:13:50.135124814 +0200 +@@ -10,7 +10,7 @@ + */ + + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + + #include + #include +diff -Naur afpfs-ng-0.8.1/lib/log.c afpfs-ng-0.8.1.patch/lib/log.c +--- afpfs-ng-0.8.1/lib/log.c 2008-01-30 05:37:58.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/log.c 2011-09-10 12:13:50.135124814 +0200 +@@ -3,7 +3,7 @@ + #include + #include + #include +-#include "libafpclient.h" ++#include "afpfs-ng/libafpclient.h" + + void log_for_client(void * priv, + enum loglevels loglevel, int logtype, char *format, ...) { +diff -Naur afpfs-ng-0.8.1/lib/loop.c afpfs-ng-0.8.1.patch/lib/loop.c +--- afpfs-ng-0.8.1/lib/loop.c 2008-02-18 04:40:11.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/loop.c 2011-09-10 12:13:50.135124814 +0200 +@@ -16,9 +16,9 @@ + #include + #include + +-#include "afp.h" +-#include "dsi.h" +-#include "utils.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/utils.h" + + #define SIGNAL_TO_USE SIGUSR2 + +diff -Naur afpfs-ng-0.8.1/lib/lowlevel.c afpfs-ng-0.8.1.patch/lib/lowlevel.c +--- afpfs-ng-0.8.1/lib/lowlevel.c 2008-02-20 02:33:17.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/lowlevel.c 2011-09-10 12:13:50.136124828 +0200 +@@ -19,10 +19,10 @@ + #else + #include + #endif +-#include "afp.h" +-#include "afp_protocol.h" +-#include "codepage.h" +-#include "utils.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/afp_protocol.h" ++#include "afpfs-ng/codepage.h" ++#include "afpfs-ng/utils.h" + #include "did.h" + #include "users.h" + +diff -Naur afpfs-ng-0.8.1/lib/map_def.c afpfs-ng-0.8.1.patch/lib/map_def.c +--- afpfs-ng-0.8.1/lib/map_def.c 2007-09-07 15:10:59.000000000 +0200 ++++ afpfs-ng-0.8.1.patch/lib/map_def.c 2011-09-10 12:13:50.136124828 +0200 +@@ -1,6 +1,6 @@ + #include +-#include "afp.h" +-#include "map_def.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/map_def.h" + + static char *afp_map_strings[] = { + "Unknown", +diff -Naur afpfs-ng-0.8.1/lib/meta.c afpfs-ng-0.8.1.patch/lib/meta.c +--- afpfs-ng-0.8.1/lib/meta.c 2008-01-04 04:52:44.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/meta.c 2011-09-10 12:13:50.137124841 +0200 +@@ -17,10 +17,10 @@ + #include + #include + +-#include "afp.h" +-#include "dsi.h" +-#include "afp_protocol.h" +-#include "utils.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp_protocol.h" ++#include "afpfs-ng/utils.h" + + + int afp_meta_getattr(const char *path, struct stat *stbuf) +diff -Naur afpfs-ng-0.8.1/lib/midlevel.c afpfs-ng-0.8.1.patch/lib/midlevel.c +--- afpfs-ng-0.8.1/lib/midlevel.c 2008-03-08 17:08:18.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/midlevel.c 2011-09-10 12:13:50.160125150 +0200 +@@ -10,7 +10,7 @@ + */ + + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + + #include + #include +@@ -28,9 +28,9 @@ + #include "users.h" + #include "did.h" + #include "resource.h" +-#include "utils.h" +-#include "codepage.h" +-#include "midlevel.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/codepage.h" ++#include "afpfs-ng/midlevel.h" + #include "afp_internal.h" + #include "forklist.h" + #include "uams.h" +diff -Naur afpfs-ng-0.8.1/lib/proto_attr.c afpfs-ng-0.8.1.patch/lib/proto_attr.c +--- afpfs-ng-0.8.1/lib/proto_attr.c 2008-01-30 05:37:58.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_attr.c 2011-09-10 12:13:50.168125257 +0200 +@@ -7,10 +7,10 @@ + + #include + #include +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/afp_protocol.h" + #include "dsi_protocol.h" + + /* This is a new command, function 76. There are currently no docs, so this +diff -Naur afpfs-ng-0.8.1/lib/proto_desktop.c afpfs-ng-0.8.1.patch/lib/proto_desktop.c +--- afpfs-ng-0.8.1/lib/proto_desktop.c 2008-02-18 04:44:11.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_desktop.c 2011-09-10 12:13:50.168125257 +0200 +@@ -9,10 +9,10 @@ + #include + #include + +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/afp_protocol.h" + #include "dsi_protocol.h" + + /* closedt, addicon, geticoninfo, addappl, removeappl */ +diff -Naur afpfs-ng-0.8.1/lib/proto_directory.c afpfs-ng-0.8.1.patch/lib/proto_directory.c +--- afpfs-ng-0.8.1/lib/proto_directory.c 2008-02-19 03:39:29.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_directory.c 2011-09-10 12:13:50.168125257 +0200 +@@ -9,10 +9,10 @@ + #include + #include + +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/afp_protocol.h" + #include "dsi_protocol.h" + #include "afp_replies.h" + +diff -Naur afpfs-ng-0.8.1/lib/proto_files.c afpfs-ng-0.8.1.patch/lib/proto_files.c +--- afpfs-ng-0.8.1/lib/proto_files.c 2008-02-18 04:46:18.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_files.c 2011-09-10 12:13:50.169125270 +0200 +@@ -8,11 +8,11 @@ + + #include + #include +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "dsi_protocol.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/afp_protocol.h" + #include "afp_internal.h" + + /* afp_setfileparms, afp_setdirparms and afpsetfiledirparms are all remarkably +diff -Naur afpfs-ng-0.8.1/lib/proto_fork.c afpfs-ng-0.8.1.patch/lib/proto_fork.c +--- afpfs-ng-0.8.1/lib/proto_fork.c 2008-01-30 05:37:58.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_fork.c 2011-09-10 12:13:50.169125270 +0200 +@@ -9,11 +9,11 @@ + #include + #include + +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "dsi_protocol.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/afp_protocol.h" + + int afp_setforkparms(struct afp_volume * volume, + unsigned short forkid, unsigned short bitmap, unsigned long len) +diff -Naur afpfs-ng-0.8.1/lib/proto_login.c afpfs-ng-0.8.1.patch/lib/proto_login.c +--- afpfs-ng-0.8.1/lib/proto_login.c 2008-01-30 05:37:59.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_login.c 2011-09-10 12:13:50.169125270 +0200 +@@ -10,10 +10,10 @@ + + #include + #include +-#include "dsi.h" ++#include "afpfs-ng/dsi.h" + #include "dsi_protocol.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "afp_internal.h" + + +diff -Naur afpfs-ng-0.8.1/lib/proto_map.c afpfs-ng-0.8.1.patch/lib/proto_map.c +--- afpfs-ng-0.8.1/lib/proto_map.c 2008-01-30 05:37:59.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_map.c 2011-09-10 12:13:50.170125283 +0200 +@@ -9,11 +9,11 @@ + #include + #include + +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "dsi_protocol.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/afp_protocol.h" + + /* This is used to pass the return values back from afp_getuserinfo_reply() */ + struct uidgid { +diff -Naur afpfs-ng-0.8.1/lib/proto_replyblock.c afpfs-ng-0.8.1.patch/lib/proto_replyblock.c +--- afpfs-ng-0.8.1/lib/proto_replyblock.c 2008-02-18 04:46:19.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_replyblock.c 2011-09-10 12:13:50.170125283 +0200 +@@ -6,9 +6,9 @@ + */ + + #include +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "afp_internal.h" + + +diff -Naur afpfs-ng-0.8.1/lib/proto_server.c afpfs-ng-0.8.1.patch/lib/proto_server.c +--- afpfs-ng-0.8.1/lib/proto_server.c 2008-02-19 02:56:21.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_server.c 2011-09-10 12:13:50.170125283 +0200 +@@ -7,12 +7,12 @@ + */ + #include + #include +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "dsi_protocol.h" +-#include "afp_protocol.h" +-#include "codepage.h" ++#include "afpfs-ng/afp_protocol.h" ++#include "afpfs-ng/codepage.h" + #include "afp_internal.h" + + int afp_getsrvrparms(struct afp_server *server) +diff -Naur afpfs-ng-0.8.1/lib/proto_session.c afpfs-ng-0.8.1.patch/lib/proto_session.c +--- afpfs-ng-0.8.1/lib/proto_session.c 2008-02-18 04:46:19.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_session.c 2011-09-10 12:13:50.170125283 +0200 +@@ -8,10 +8,10 @@ + */ + #include + #include +-#include "dsi.h" ++#include "afpfs-ng/dsi.h" + #include "dsi_protocol.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + + int afp_getsessiontoken(struct afp_server * server, int type, + unsigned int timestamp, struct afp_token *outgoing_token, +diff -Naur afpfs-ng-0.8.1/lib/proto_volume.c afpfs-ng-0.8.1.patch/lib/proto_volume.c +--- afpfs-ng-0.8.1/lib/proto_volume.c 2008-02-18 04:47:48.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_volume.c 2011-09-10 12:13:50.171125296 +0200 +@@ -8,13 +8,13 @@ + + #include + #include +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "dsi_protocol.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/afp_protocol.h" + #include "afp_internal.h" +-#include "codepage.h" ++#include "afpfs-ng/codepage.h" + + static int parse_volbitmap_reply(struct afp_server * server, + struct afp_volume * tmpvol, +diff -Naur afpfs-ng-0.8.1/lib/resource.c afpfs-ng-0.8.1.patch/lib/resource.c +--- afpfs-ng-0.8.1/lib/resource.c 2008-02-18 04:46:56.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/resource.c 2011-09-10 12:13:50.171125296 +0200 +@@ -3,11 +3,11 @@ + #include + #include + #include +-#include "afp.h" ++#include "afpfs-ng/afp.h" + #include "resource.h" + #include "lowlevel.h" + #include "did.h" +-#include "midlevel.h" ++#include "afpfs-ng/midlevel.h" + + #define appledouble ".AppleDouble" + #define finderinfo_string ".finderinfo" +diff -Naur afpfs-ng-0.8.1/lib/server.c afpfs-ng-0.8.1.patch/lib/server.c +--- afpfs-ng-0.8.1/lib/server.c 2008-02-19 02:56:21.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/server.c 2011-09-10 12:13:50.172125310 +0200 +@@ -8,15 +8,15 @@ + #include + #include + +-#include "afp.h" +-#include "dsi.h" +-#include "utils.h" +-#include "uams_def.h" +-#include "codepage.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/uams_def.h" ++#include "afpfs-ng/codepage.h" + #include "users.h" +-#include "libafpclient.h" ++#include "afpfs-ng/libafpclient.h" + #include "afp_internal.h" +-#include "dsi.h" ++#include "afpfs-ng/dsi.h" + + + struct afp_server * afp_server_complete_connection( +diff -Naur afpfs-ng-0.8.1/lib/status.c afpfs-ng-0.8.1.patch/lib/status.c +--- afpfs-ng-0.8.1/lib/status.c 2008-03-08 17:08:38.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/status.c 2011-09-10 12:13:50.172125310 +0200 +@@ -1,8 +1,8 @@ + #include + #include +-#include "map_def.h" +-#include "dsi.h" +-#include "afp.h" ++#include "afpfs-ng/map_def.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" + + int afp_status_header(char * text, int * len) + { +diff -Naur afpfs-ng-0.8.1/lib/uams.c afpfs-ng-0.8.1.patch/lib/uams.c +--- afpfs-ng-0.8.1/lib/uams.c 2008-01-04 04:52:44.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/uams.c 2011-09-10 12:13:50.173125324 +0200 +@@ -8,10 +8,10 @@ + + #include + #include +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" +-#include "uams_def.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/uams_def.h" + #include "config.h" + + #ifdef HAVE_LIBGCRYPT +diff -Naur afpfs-ng-0.8.1/lib/users.c afpfs-ng-0.8.1.patch/lib/users.c +--- afpfs-ng-0.8.1/lib/users.c 2008-02-18 04:48:56.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/users.c 2011-09-10 12:13:50.174125338 +0200 +@@ -3,8 +3,8 @@ + #include + #include + +-#include "afp.h" +-#include "map_def.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/map_def.h" + + /* How mapping works + * +diff -Naur afpfs-ng-0.8.1/lib/utils.c afpfs-ng-0.8.1.patch/lib/utils.c +--- afpfs-ng-0.8.1/lib/utils.c 2008-02-18 04:53:37.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/utils.c 2011-09-10 12:13:50.174125338 +0200 +@@ -8,10 +8,10 @@ + #include + #include + #include +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "afp_internal.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/afp_protocol.h" + + struct afp_path_header_long { + unsigned char type; +diff -Naur afpfs-ng-0.8.1/Makefile.am afpfs-ng-0.8.1.patch/Makefile.am +--- afpfs-ng-0.8.1/Makefile.am 2008-02-18 04:24:14.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/Makefile.am 2011-09-10 12:13:50.176125365 +0200 +@@ -1,5 +1,5 @@ + if HAVE_LIBFUSE +-SUBDIRS = lib fuse cmdline docs ++SUBDIRS = lib fuse cmdline include docs + else +-SUBDIRS = lib cmdline docs ++SUBDIRS = lib cmdline include docs + endif diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj index 45e3df4..76dd44b 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -204,7 +204,6 @@ - @@ -215,16 +214,6 @@ - - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - @@ -325,6 +314,9 @@ + + + @@ -332,6 +324,8 @@ + + @@ -365,9 +359,14 @@ + + + + + @@ -383,6 +382,8 @@ + + @@ -529,7 +530,7 @@ - + @@ -648,7 +649,6 @@ - @@ -663,12 +663,14 @@ + - + + @@ -851,6 +853,7 @@ + true true @@ -863,10 +866,6 @@ true true - - true - true - true true @@ -886,7 +885,6 @@ - @@ -1153,11 +1151,8 @@ - - - @@ -1199,15 +1194,22 @@ + + + + + + + @@ -1231,7 +1233,13 @@ + + + + + + @@ -1241,6 +1249,8 @@ + + @@ -1259,6 +1269,9 @@ + + + @@ -1275,11 +1288,8 @@ - - - true true @@ -1288,10 +1298,6 @@ true true - - true - true - true true @@ -1326,8 +1332,10 @@ + + @@ -1336,6 +1344,7 @@ CompileAsCpp + @@ -1384,6 +1393,10 @@ true true + + true + true + true true @@ -1553,6 +1566,14 @@ true true + + true + true + + + true + true + @@ -1634,6 +1655,7 @@ + @@ -1641,6 +1663,7 @@ + @@ -1658,10 +1681,20 @@ + + + + + + + + + + @@ -1764,7 +1797,6 @@ - @@ -1942,6 +1974,7 @@ + @@ -1997,10 +2030,15 @@ + + + + + @@ -2114,6 +2152,7 @@ + true true @@ -2154,13 +2193,16 @@ + + + @@ -2243,7 +2285,6 @@ - @@ -2295,6 +2336,7 @@ + @@ -2303,6 +2345,7 @@ + @@ -2331,11 +2374,27 @@ + + + + + + + + + + + + + + + + @@ -2457,6 +2516,10 @@ true false + + {19b16cd0-3b47-47b7-ab0e-81ef2bf1b187} + false + {b2975495-fbe4-4f94-aac5-b21a9842bf50} false diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters index eaecbbf..d395ae7 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters @@ -480,6 +480,9 @@ cores\dvdplayer\DVDDemuxers + + cores\dvdplayer\DVDDemuxers + cores\dvdplayer\DVDDemuxers @@ -501,6 +504,9 @@ cores\dvdplayer\DVDInputStreams + + cores\dvdplayer\DVDInputStreams + cores\dvdplayer\DVDInputStreams @@ -546,6 +552,9 @@ cores\dvdplayer\DVDSubtitles + + cores\paplayer + cores\paplayer @@ -555,9 +564,36 @@ cores\paplayer + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + cores\paplayer + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + cores\DllLoader @@ -1111,6 +1147,9 @@ input + + input + input @@ -1195,6 +1234,9 @@ music\tags + + music\tags + music\tags @@ -1204,9 +1246,21 @@ music\tags + + music\tags + + + music\tags + music\tags + + music\tags + + + music\tags + network @@ -1375,6 +1429,9 @@ utils + + utils + utils @@ -1384,6 +1441,9 @@ utils + + utils + utils @@ -1846,6 +1906,9 @@ filesystem + + filesystem + network\httprequesthandler @@ -1888,6 +1951,12 @@ network\httprequesthandler + + filesystem + + + filesystem + filesystem @@ -1903,6 +1972,12 @@ filesystem + + filesystem + + + filesystem + filesystem @@ -1975,12 +2050,30 @@ filesystem + + filesystem + + + filesystem + + + filesystem + + + filesystem + filesystem filesystem + + filesystem + + + filesystem + filesystem @@ -2008,6 +2101,12 @@ filesystem + + filesystem + + + filesystem + filesystem @@ -2062,6 +2161,15 @@ filesystem + + filesystem + + + filesystem + + + filesystem + filesystem @@ -2201,6 +2309,7 @@ + @@ -2329,6 +2438,12 @@ utils\test + + utils\test + + + utils\test + utils\test @@ -2341,6 +2456,9 @@ utils\test + + utils\test + utils\test @@ -2996,9 +3114,6 @@ input - - music\tags - network\httprequesthandler\python @@ -3035,9 +3150,6 @@ addons - - addons - filesystem @@ -3374,6 +3486,9 @@ cores\dvdplayer\DVDDemuxers + + cores\dvdplayer\DVDDemuxers + cores\dvdplayer\DVDDemuxers @@ -3398,6 +3513,9 @@ cores\dvdplayer\DVDInputStreams + + cores\dvdplayer\DVDInputStreams + cores\dvdplayer\DVDInputStreams @@ -3476,21 +3594,69 @@ cores\dvdplayer\DVDSubtitles + + cores\paplayer + cores\paplayer cores\paplayer + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + cores\paplayer cores\paplayer + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + cores\paplayer + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + + + cores\paplayer + cores\DllLoader @@ -4087,6 +4253,9 @@ input + + input + input @@ -4198,6 +4367,9 @@ music\tags + + music\tags + music\tags @@ -4207,9 +4379,21 @@ music\tags + + music\tags + + + music\tags + music\tags + + music\tags + + + music\tags + network @@ -4387,12 +4571,18 @@ utils + + utils + utils utils + + utils + utils @@ -4402,6 +4592,9 @@ utils + + utils + utils @@ -4909,6 +5102,15 @@ filesystem + + filesystem + + + filesystem + + + filesystem + filesystem @@ -4921,6 +5123,12 @@ filesystem + + filesystem + + + filesystem + filesystem @@ -4933,6 +5141,12 @@ filesystem + + filesystem + + + filesystem + filesystem @@ -5002,9 +5216,27 @@ filesystem + + filesystem + + + filesystem + + + filesystem + + + filesystem + filesystem + + filesystem + + + filesystem + filesystem @@ -5032,6 +5264,12 @@ filesystem + + filesystem + + + filesystem + filesystem @@ -5086,6 +5324,15 @@ filesystem + + filesystem + + + filesystem + + + filesystem + filesystem @@ -5291,6 +5538,7 @@ + @@ -5992,15 +6240,9 @@ video\jobs - - music\tags - video\jobs - - music - utils diff --git a/tools/android/packaging/Makefile.in b/tools/android/packaging/Makefile.in index b9c6cca..9c5584e 100644 --- a/tools/android/packaging/Makefile.in +++ b/tools/android/packaging/Makefile.in @@ -2,6 +2,7 @@ include ../../depends/Makefile.include OBJS = libcurl.so \ librtmp.so \ + libafpclient.so \ libplist.so libshairplay.so \ libxbogg.so libxbvorbis.so libxbvorbisfile.so libxbmpeg2.so \ libxbmpeg2convert.so libnfs.so libass.so \ diff --git a/tools/depends/target/Makefile b/tools/depends/target/Makefile index ed17ca5..bc2bcbf 100644 --- a/tools/depends/target/Makefile +++ b/tools/depends/target/Makefile @@ -12,7 +12,7 @@ DEPENDS = \ libogg libvorbis libflac fribidi libmpeg2 \ libass libsquish \ libmodplug librtmp libxml2 yajl libmicrohttpd mysql libffi \ - python26 libshairplay \ + python26 afpfs-ng libshairplay \ libplist libcec libbluray boost tinyxml dummy-libxbmc \ libamplayer libssh taglib libusb libnfs \ pythonmodule-pil libxslt ffmpeg platform crossguid libdcadec giflib @@ -85,6 +85,7 @@ librtmp: openssl libmicrohttpd: gnutls libgcrypt libgpg-error python26: expat gettext libxml2 sqlite3 openssl libffi libcdio: $(ICONV) +afpfs-ng: libgcrypt $(ICONV) libplist: libxml2 $(ZLIB) libbluray: $(ICONV) libxml2 libssh: openssl $(ZLIB) diff --git a/tools/depends/target/afpfs-ng/01-gcrypt.patch b/tools/depends/target/afpfs-ng/01-gcrypt.patch new file mode 100644 index 0000000..7bcace2 --- /dev/null +++ b/tools/depends/target/afpfs-ng/01-gcrypt.patch @@ -0,0 +1,26 @@ +diff -ru afpfs-ng-0.8.1/configure.ac afpfs-ng-0.8.1+iPhone/configure.ac +--- afpfs-ng-0.8.1/configure.ac 2008-03-08 16:23:12.000000000 +0000 ++++ afpfs-ng-0.8.1+iPhone/configure.ac 2010-10-24 05:26:15.000000000 +0000 +@@ -50,21 +50,6 @@ + case $host in + *-*-darwin*) + AC_MSG_CHECKING([for correct gcrypt version]) +- AC_RUN_IFELSE( +- [AC_LANG_PROGRAM([ +- #include +- #include ],[ +- char*p= GCRYPT_VERSION; +- unsigned int vers; +- vers=atoi(p)*10000; +- p=strchr(p,'.')+1; +- vers+=atoi(p)*100; +- p=strchr(p,'.')+1; +- vers+=atoi(p); +- if (vers<10400) return 1; +- ])], +- [AC_MSG_RESULT([yes])], +- [AC_MSG_ERROR([version is < 1.4.0])]) + AM_CONDITIONAL(HAVE_LIBGCRYPT, true) + AC_DEFINE([HAVE_LIBGCRYPT], [1] ) + ;; + diff --git a/tools/depends/target/afpfs-ng/02-pointer.patch b/tools/depends/target/afpfs-ng/02-pointer.patch new file mode 100644 index 0000000..80507b5 --- /dev/null +++ b/tools/depends/target/afpfs-ng/02-pointer.patch @@ -0,0 +1,280 @@ +diff -up afpfs-ng-0.8.1/cmdline/getstatus.c.pointer afpfs-ng-0.8.1/cmdline/getstatus.c +--- afpfs-ng-0.8.1/cmdline/getstatus.c.pointer 2011-06-14 17:06:35.000000000 +0200 ++++ afpfs-ng-0.8.1/cmdline/getstatus.c 2011-06-14 17:07:25.000000000 +0200 +@@ -1,4 +1,5 @@ + #include ++#include + #include + #include + +diff -up afpfs-ng-0.8.1/fuse/client.c.pointer afpfs-ng-0.8.1/fuse/client.c +--- afpfs-ng-0.8.1/fuse/client.c.pointer 2008-03-08 03:44:16.000000000 +0100 ++++ afpfs-ng-0.8.1/fuse/client.c 2011-06-14 17:02:15.000000000 +0200 +@@ -61,8 +61,9 @@ static int start_afpfsd(void) + snprintf(filename, PATH_MAX, + "/usr/local/bin/%s",AFPFSD_FILENAME); + if (access(filename,X_OK)) { +- snprintf(filename, "/usr/bin/%s", ++ snprintf(filename, sizeof(filename), "/usr/bin/%s", + AFPFSD_FILENAME); ++ filename[sizeof(filename) - 1] = 0; + if (access(filename,X_OK)) { + printf("Could not find server (%s)\n", + filename); +diff -up afpfs-ng-0.8.1/fuse/fuse_int.c.pointer afpfs-ng-0.8.1/fuse/fuse_int.c +--- afpfs-ng-0.8.1/fuse/fuse_int.c.pointer 2008-03-02 06:06:24.000000000 +0100 ++++ afpfs-ng-0.8.1/fuse/fuse_int.c 2011-06-14 17:02:15.000000000 +0200 +@@ -197,7 +197,7 @@ static int fuse_open(const char *path, s + ret = ml_open(volume,path,flags,&fp); + + if (ret==0) +- fi->fh=(void *) fp; ++ fi->fh=(unsigned long) fp; + + return ret; + } +diff -up afpfs-ng-0.8.1/include/afpfs-ng/afp.h.pointer afpfs-ng-0.8.1/include/afp.h +--- afpfs-ng-0.8.1/include/afpfs-ng/afp.h.pointer 2008-03-08 17:08:18.000000000 +0100 ++++ afpfs-ng-0.8.1/include/afpfs-ng/afp.h 2011-06-14 17:02:15.000000000 +0200 +@@ -370,7 +370,7 @@ int afp_unmount_all_volumes(struct afp_s + + int afp_opendt(struct afp_volume *volume, unsigned short * refnum); + +-int afp_closedt(struct afp_server * server, unsigned short * refnum); ++int afp_closedt(struct afp_server * server, unsigned short refnum); + + int afp_getcomment(struct afp_volume *volume, unsigned int did, + const char * pathname, struct afp_comment * comment); +diff -up afpfs-ng-0.8.1/include/afpfs-gn/utils.h.pointer afpfs-ng-0.8.1/include/utils.h +--- afpfs-ng-0.8.1/include/afpfs-ng/utils.h.pointer 2008-02-18 04:33:58.000000000 +0100 ++++ afpfs-ng-0.8.1/include/afpfs-ng/utils.h 2011-06-14 17:02:15.000000000 +0200 +@@ -8,8 +8,8 @@ + #define hton64(x) (x) + #define ntoh64(x) (x) + #else /* BYTE_ORDER == BIG_ENDIAN */ +-#define hton64(x) ((u_int64_t) (htonl(((x) >> 32) & 0xffffffffLL)) | \ +- (u_int64_t) ((htonl(x) & 0xffffffffLL) << 32)) ++#define hton64(x) ((u_int64_t) (htonl((((unsigned long long)(x)) >> 32) & 0xffffffffLL)) | \ ++ (u_int64_t) ((htonl((unsigned long long)(x)) & 0xffffffffLL) << 32)) + #define ntoh64(x) (hton64(x)) + #endif /* BYTE_ORDER == BIG_ENDIAN */ + +diff -up afpfs-ng-0.8.1/lib/afp_url.c.pointer afpfs-ng-0.8.1/lib/afp_url.c +--- afpfs-ng-0.8.1/lib/afp_url.c.pointer 2008-03-04 21:16:49.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/afp_url.c 2011-06-14 17:02:15.000000000 +0200 +@@ -33,7 +33,7 @@ static int check_port(char * port) + static int check_uamname(const char * uam) + { + char * p; +- for (p=uam;*p;p++) { ++ for (p=(char *)uam;*p;p++) { + if (*p==' ') continue; + if ((*p<'A') || (*p>'z')) return -1; + } +@@ -188,7 +188,7 @@ int afp_parse_url(struct afp_url * url, + return -1; + + } +- if (p==NULL) p=toparse; ++ if (p==NULL) p=(char *)toparse; + + /* Now split on the first / */ + if (sscanf(p,"%[^/]/%[^$]", +diff -up afpfs-ng-0.8.1/lib/did.c.pointer afpfs-ng-0.8.1/lib/did.c +--- afpfs-ng-0.8.1/lib/did.c.pointer 2008-02-18 04:39:17.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/did.c 2011-06-14 17:02:15.000000000 +0200 +@@ -226,7 +226,7 @@ int get_dirid(struct afp_volume * volume + + + /* Go to the end of last known entry */ +- p=path+(p-copy); ++ p=(char *)path+(p-copy); + p2=p; + + while ((p=strchr(p+1,'/'))) { +diff -up afpfs-ng-0.8.1/lib/dsi.c.pointer afpfs-ng-0.8.1/lib/dsi.c +--- afpfs-ng-0.8.1/lib/dsi.c.pointer 2008-02-18 04:53:03.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/dsi.c 2011-06-14 17:02:15.000000000 +0200 +@@ -474,7 +474,7 @@ void dsi_getstatus_reply(struct afp_serv + } + server->flags=ntohs(reply1->flags); + +- p=(void *)((unsigned int) server->incoming_buffer + sizeof(*reply1)); ++ p=(void *)((unsigned long) server->incoming_buffer + sizeof(*reply1)); + p+=copy_from_pascal(server->server_name,p,AFP_SERVER_NAME_LEN)+1; + + /* Now work our way through the variable bits */ +@@ -757,7 +757,7 @@ gotenough: + printf("<<< read() of rest of AFP, %d bytes\n",amount_to_read); + #endif + ret = read(server->fd, (void *) +- (((unsigned int) server->incoming_buffer)+server->data_read), ++ (((unsigned long) server->incoming_buffer)+server->data_read), + amount_to_read); + if (ret<0) return -1; + if (ret==0) { +diff -up afpfs-ng-0.8.1/lib/loop.c.pointer afpfs-ng-0.8.1/lib/loop.c +--- afpfs-ng-0.8.1/lib/loop.c.pointer 2008-02-18 04:40:11.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/loop.c 2011-06-14 17:02:15.000000000 +0200 +@@ -25,7 +25,7 @@ + static unsigned char exit_program=0; + + static pthread_t ending_thread; +-static pthread_t main_thread = NULL; ++static pthread_t main_thread = (pthread_t)NULL; + + static int loop_started=0; + static pthread_cond_t loop_started_condition; +diff -up afpfs-ng-0.8.1/lib/lowlevel.c.pointer afpfs-ng-0.8.1/lib/lowlevel.c +--- afpfs-ng-0.8.1/lib/lowlevel.c.pointer 2008-02-20 02:33:17.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/lowlevel.c 2011-06-14 17:02:15.000000000 +0200 +@@ -582,7 +582,7 @@ int ll_getattr(struct afp_volume * volum + if (volume->server->using_version->av_number>=30) + stbuf->st_mode |= fp.unixprivs.permissions; + else +- set_nonunix_perms(stbuf,&fp); ++ set_nonunix_perms(&stbuf->st_mode,&fp); + + stbuf->st_uid=fp.unixprivs.uid; + stbuf->st_gid=fp.unixprivs.gid; +diff -up afpfs-ng-0.8.1/lib/midlevel.c.pointer afpfs-ng-0.8.1/lib/midlevel.c +--- afpfs-ng-0.8.1/lib/midlevel.c.pointer 2008-03-08 17:08:18.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/midlevel.c 2011-06-14 17:02:15.000000000 +0200 +@@ -713,7 +713,7 @@ int ml_write(struct afp_volume * volume, + { + + int ret,err=0; +- int totalwritten = 0; ++ size_t totalwritten = 0; + uint64_t sizetowrite, ignored; + unsigned char flags = 0; + unsigned int max_packet_size=volume->server->tx_quantum; +diff -up afpfs-ng-0.8.1/lib/proto_attr.c.pointer afpfs-ng-0.8.1/lib/proto_attr.c +--- afpfs-ng-0.8.1/lib/proto_attr.c.pointer 2008-01-30 05:37:58.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/proto_attr.c 2011-06-14 17:02:15.000000000 +0200 +@@ -166,7 +166,7 @@ int afp_getextattr(struct afp_volume * v + copy_path(server,p,pathname,strlen(pathname)); + unixpath_to_afppath(server,p); + p2=p+sizeof_path_header(server)+strlen(pathname); +- if (((unsigned int ) p2) & 0x1) p2++; ++ if (((unsigned long) p2) & 0x1) p2++; + req2=(void *) p2; + + req2->len=htons(namelen); +diff -up afpfs-ng-0.8.1/lib/proto_desktop.c.pointer afpfs-ng-0.8.1/lib/proto_desktop.c +--- afpfs-ng-0.8.1/lib/proto_desktop.c.pointer 2008-02-18 04:44:11.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/proto_desktop.c 2011-06-14 17:02:15.000000000 +0200 +@@ -168,7 +168,7 @@ int afp_getcomment_reply(struct afp_serv + return 0; + } + +-int afp_closedt(struct afp_server * server, unsigned short * refnum) ++int afp_closedt(struct afp_server * server, unsigned short refnum) + { + struct { + struct dsi_header dsi_header __attribute__((__packed__)); +diff -up afpfs-ng-0.8.1/lib/proto_directory.c.pointer afpfs-ng-0.8.1/lib/proto_directory.c +--- afpfs-ng-0.8.1/lib/proto_directory.c.pointer 2008-02-19 03:39:29.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/proto_directory.c 2011-06-14 17:02:15.000000000 +0200 +@@ -248,6 +248,7 @@ int afp_enumerate_reply(struct afp_serve + + return 0; + } ++ + int afp_enumerateext2_reply(struct afp_server *server, char * buf, unsigned int size, void * other) + { + +@@ -266,8 +267,7 @@ int afp_enumerateext2_reply(struct afp_s + char * p = buf + sizeof(*reply); + int i; + char *max=buf+size; +- struct afp_file_info * filebase = NULL, *filecur=NULL, *new_file=NULL; +- void ** x = other; ++ struct afp_file_info * filebase = NULL, *filecur = NULL, *new_file = NULL, **x = (struct afp_file_info **) other; + + if (reply->dsi_header.return_code.error_code) { + return reply->dsi_header.return_code.error_code; +diff -up afpfs-ng-0.8.1/lib/proto_map.c.pointer afpfs-ng-0.8.1/lib/proto_map.c +--- afpfs-ng-0.8.1/lib/proto_map.c.pointer 2008-01-30 05:37:59.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/proto_map.c 2011-06-14 17:02:15.000000000 +0200 +@@ -122,7 +122,7 @@ int afp_mapid_reply(struct afp_server *s + + if (reply->header.return_code.error_code!=kFPNoErr) return -1; + +- copy_from_pascal_two(name,&reply->name,255); ++ copy_from_pascal_two(name,reply->name,255); + + return 0; + } +diff -up afpfs-ng-0.8.1/lib/proto_session.c.pointer afpfs-ng-0.8.1/lib/proto_session.c +--- afpfs-ng-0.8.1/lib/proto_session.c.pointer 2008-02-18 04:46:19.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/proto_session.c 2011-06-14 17:02:15.000000000 +0200 +@@ -39,7 +39,7 @@ int afp_getsessiontoken(struct afp_serve + switch (type) { + case kLoginWithTimeAndID: + case kReconnWithTimeAndID: { +- uint32_t *p = (void *) (((unsigned int) request)+ ++ uint32_t *p = (void *) (((unsigned long) request)+ + sizeof(*request)); + + offset=sizeof(timestamp); +@@ -63,7 +63,7 @@ int afp_getsessiontoken(struct afp_serve + goto error; + } + +- data=(void *) (((unsigned int) request)+sizeof(*request)+offset); ++ data=(void *) (((unsigned long) request)+sizeof(*request)+offset); + request->idlength=htonl(datalen); + request->pad=0; + request->type=htons(type); +@@ -127,7 +127,7 @@ int afp_disconnectoldsession(struct afp_ + if ((request=malloc(sizeof(*request) + AFP_TOKEN_MAX_LEN))==NULL) + return -1; + +- token_data = request + sizeof(*request); ++ token_data = (char *)request + sizeof(*request); + + request->type=htons(type); + +diff -up afpfs-ng-0.8.1/lib/uams.c.pointer afpfs-ng-0.8.1/lib/uams.c +--- afpfs-ng-0.8.1/lib/uams.c.pointer 2008-01-04 04:52:44.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/uams.c 2011-06-14 17:02:15.000000000 +0200 +@@ -180,7 +180,7 @@ static int cleartxt_login(struct afp_ser + goto cleartxt_fail; + + p += copy_to_pascal(p, username) + 1; +- if ((int)p & 0x1) ++ if ((long)p & 0x1) + len--; + else + p++; +@@ -230,7 +230,7 @@ static int cleartxt_passwd(struct afp_se + goto cleartxt_fail; + + p += copy_to_pascal(p, username) + 1; +- if ((int)p & 0x1) ++ if ((long)p & 0x1) + len--; + else + p++; +@@ -580,7 +580,7 @@ static int dhx_login(struct afp_server * + if (ai == NULL) + goto dhx_noctx_fail; + d += copy_to_pascal(ai, username) + 1; +- if (((int)d) % 2) ++ if (((long)d) % 2) + d++; + else + ai_len--; +diff -up afpfs-ng-0.8.1/lib/utils.c.pointer afpfs-ng-0.8.1/lib/utils.c +--- afpfs-ng-0.8.1/lib/utils.c.pointer 2008-02-18 04:53:37.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/utils.c 2011-06-14 17:02:15.000000000 +0200 +@@ -196,7 +196,7 @@ int invalid_filename(struct afp_server * + maxlen=255; + + +- p=filename+1; ++ p=(char *)filename+1; + while ((q=strchr(p,'/'))) { + if (q>p+maxlen) + return 1; diff --git a/tools/depends/target/afpfs-ng/04-boxee1.patch b/tools/depends/target/afpfs-ng/04-boxee1.patch new file mode 100644 index 0000000..9f3c20f --- /dev/null +++ b/tools/depends/target/afpfs-ng/04-boxee1.patch @@ -0,0 +1,25 @@ +--- afpfs-ng-0.8.1/include/afpfs-ng/dsi.h 2008-02-18 04:33:24.000000000 +0100 ++++ afpfs-ng-0.8.1/include/afpfs-ng/dsi.h 2011-08-26 21:33:33.000000000 +0200 +@@ -6,13 +6,15 @@ + + struct dsi_request + { +- unsigned short requestid; +- unsigned char subcommand; +- void * other; +- unsigned char wait; +- pthread_cond_t condition_cond; +- struct dsi_request * next; +- int return_code; ++ unsigned short requestid; ++ unsigned char subcommand; ++ void * other; ++ int wait; ++ int done_waiting; ++ pthread_cond_t waiting_cond; ++ pthread_mutex_t waiting_mutex; ++ struct dsi_request * next; ++ int return_code; + }; + + int dsi_receive(struct afp_server * server, void * data, int size); diff --git a/tools/depends/target/afpfs-ng/05-boxee2.patch b/tools/depends/target/afpfs-ng/05-boxee2.patch new file mode 100644 index 0000000..50250bc --- /dev/null +++ b/tools/depends/target/afpfs-ng/05-boxee2.patch @@ -0,0 +1,89 @@ +--- afpfs-ng-0.8.1/lib/afp.c 2008-03-08 03:44:16.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/afp.c 2011-08-26 21:33:33.000000000 +0200 +@@ -68,7 +68,7 @@ + afp_getsessiontoken_reply,afp_blank_reply, NULL, NULL, + afp_enumerateext2_reply, NULL, NULL, NULL, /*64 - 71 */ + afp_listextattrs_reply, NULL, NULL, NULL, +- afp_blank_reply, NULL, NULL, NULL, /*72 - 79 */ ++ afp_blank_reply, NULL, afp_blank_reply, afp_blank_reply, /*72 - 79 */ + + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +@@ -320,8 +320,16 @@ + + struct dsi_request * p; + struct afp_server *s2; ++ ++ ++ if (s==NULL) ++ goto out; ++ + for (p=s->command_requests;p;p=p->next) { +- pthread_cond_signal(&p->condition_cond); ++ pthread_mutex_lock(&p->waiting_mutex); ++ p->done_waiting=1; ++ pthread_cond_signal(&p->waiting_cond); ++ pthread_mutex_unlock(&p->waiting_mutex); + } + + if (s==server_base) { +@@ -354,7 +362,7 @@ + s->exit_flag = 0; + s->path_encoding=kFPUTF8Name; /* This is a default */ + s->next=NULL; +- s->bufsize=2048; ++ s->bufsize=4096; + s->incoming_buffer=malloc(s->bufsize); + + s->attention_quantum=AFP_DEFAULT_ATTENTION_QUANTUM; +@@ -524,13 +532,14 @@ + kFPVolCreateDateBit|kFPVolIDBit | + kFPVolNameBit; + char new_encoding; ++ int ret; + + if (server->using_version->av_number>=30) + bitmap|= kFPVolNameBit|kFPVolBlockSizeBit; + +- switch (afp_volopen(volume,bitmap, +- (strlen(volume->volpassword)>0) ? volume->volpassword : NULL)) +- { ++ ret = afp_volopen(volume,bitmap, ++ (strlen(volume->volpassword)>0) ? volume->volpassword : NULL); ++ switch(ret){ + case kFPAccessDenied: + *l+=snprintf(mesg,max-*l, + "Incorrect volume password\n"); +@@ -544,6 +553,10 @@ + *l+=snprintf(mesg,max-*l, + "Could not open volume\n"); + goto error; ++ case ETIMEDOUT: ++ *l+=snprintf(mesg,max-*l, ++ "Timed out waiting to open volume\n"); ++ goto error; + } + + /* It is said that if a volume's encoding will be the same +@@ -641,7 +654,6 @@ + add_server(server); + + add_fd_and_signal(server->fd); +- + if (!full) { + return 0; + } +@@ -649,10 +661,13 @@ + /* Get the status, and calculate the transmit time. We use this to + * calculate our rx quantum. */ + gettimeofday(&t1,NULL); ++ + if ((error=dsi_getstatus(server))!=0) + goto error; + gettimeofday(&t2,NULL); + ++ afp_server_identify(server); ++ + if ((t2.tv_sec - t1.tv_sec) > 0) + server->tx_delay= (t2.tv_sec - t1.tv_sec) * 1000; + else diff --git a/tools/depends/target/afpfs-ng/06-boxee3.patch b/tools/depends/target/afpfs-ng/06-boxee3.patch new file mode 100644 index 0000000..4b7c916 --- /dev/null +++ b/tools/depends/target/afpfs-ng/06-boxee3.patch @@ -0,0 +1,141 @@ +--- afpfs-ng-0.8.1/lib/dsi.c 2011-08-26 17:27:16.000000000 +0200 ++++ afpfs-ng-0.8.1/lib/dsi.c 2011-08-26 21:33:33.000000000 +0200 +@@ -64,7 +64,7 @@ + rx.size=0; + dsi_setup_header(server,&header,DSI_DSIGetStatus); + /* We're intentionally ignoring the results */ +- ret=dsi_send(server,(char *) &header,sizeof(struct dsi_header),20, ++ ret=dsi_send(server,(char *) &header,sizeof(struct dsi_header),60, + 0,(void *) &rx); + + free(rx.data); +@@ -197,6 +197,7 @@ + new_request->other=other; + new_request->wait=wait; + new_request->next=NULL; ++ new_request->done_waiting=0; + + pthread_mutex_lock(&server->request_queue_mutex); + if (server->command_requests==NULL) { +@@ -208,7 +209,8 @@ + server->stats.requests_pending++; + pthread_mutex_unlock(&server->request_queue_mutex); + +- pthread_cond_init(&new_request->condition_cond,NULL); ++ pthread_cond_init(&new_request->waiting_cond,NULL); ++ pthread_mutex_init(&new_request->waiting_mutex,NULL); + + if (server->connect_state==SERVER_STATE_DISCONNECTED) { + char mesg[1024]; +@@ -240,16 +242,12 @@ + server->stats.tx_bytes+=size; + pthread_mutex_unlock(&server->send_mutex); + +- int tmpwait=new_request->wait; + #ifdef DEBUG_DSI + printf("=== Waiting for response for %d %s\n", + new_request->requestid, + afp_get_command_name(new_request->subcommand)); + #endif +- if (tmpwait<0) { +- +- pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +- pthread_mutex_lock(&mutex); ++ if (new_request->wait<0) { + + /* Wait forever */ + #ifdef DEBUG_DSI +@@ -258,14 +256,17 @@ + afp_get_command_name(new_request->subcommand)); + #endif + +- rc=pthread_cond_wait( +- &new_request->condition_cond, +- &mutex ); +- pthread_mutex_unlock(&mutex); +- +- } else if (tmpwait>0) { +- pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +- pthread_mutex_lock(&mutex); ++ pthread_mutex_lock(&new_request->waiting_mutex); ++ ++ if (new_request->done_waiting==0) ++ rc=pthread_cond_wait( ++ &new_request->waiting_cond, ++ &new_request->waiting_mutex ); ++ ++ pthread_mutex_unlock(&new_request->waiting_mutex); ++ ++ } else if (new_request->wait>0) { ++ /* wait for new_request->wait seconds */ + + #ifdef DEBUG_DSI + printf("=== Waiting for %d %s, for %ds\n", +@@ -283,13 +284,15 @@ + printf("=== Changing my mind, no longer waiting for %d\n", + new_request->requestid); + #endif +- pthread_mutex_unlock(&mutex); + goto skip; + } +- rc=pthread_cond_timedwait( +- &new_request->condition_cond, +- &mutex,&ts); +- pthread_mutex_unlock(&mutex); ++ pthread_mutex_lock(&new_request->waiting_mutex); ++ if (new_request->done_waiting==0) ++ rc=pthread_cond_timedwait( ++ &new_request->waiting_cond, ++ &new_request->waiting_mutex,&ts); ++ pthread_mutex_unlock(&new_request->waiting_mutex); ++ + if (rc==ETIMEDOUT) { + /* FIXME: should handle this case properly */ + #ifdef DEBUG_DSI +@@ -299,6 +302,7 @@ + goto out; + } + } else { ++ /* Don't wait */ + #ifdef DEBUG_DSI + printf("=== Skipping wait altogether for %d\n",new_request->requestid); + #endif +@@ -474,7 +478,7 @@ + } + server->flags=ntohs(reply1->flags); + +- p=(void *)((unsigned long) server->incoming_buffer + sizeof(*reply1)); ++ p=(void *)((unsigned int) server->incoming_buffer + sizeof(*reply1)); + p+=copy_from_pascal(server->server_name,p,AFP_SERVER_NAME_LEN)+1; + + /* Now work our way through the variable bits */ +@@ -577,6 +581,7 @@ + unsigned char mins=0; + unsigned char checkmessage=0; + ++ memset(mesg,0,AFP_LOGINMESG_LEN); + + /* The logic here's undocumented. If we get an attention packet and + there's no flag, then go check the message. Also, go check the +@@ -757,7 +762,7 @@ + printf("<<< read() of rest of AFP, %d bytes\n",amount_to_read); + #endif + ret = read(server->fd, (void *) +- (((unsigned long) server->incoming_buffer)+server->data_read), ++ (((unsigned int) server->incoming_buffer)+server->data_read), + amount_to_read); + if (ret<0) return -1; + if (ret==0) { +@@ -862,8 +867,11 @@ + #ifdef DEBUG_DSI + printf("<<< Signalling %d, returning %d or %d\n",request->requestid,request->return_code,rc); + #endif ++ pthread_mutex_lock(&request->waiting_mutex); + request->wait=0; +- pthread_cond_signal(&request->condition_cond); ++ request->done_waiting=1; ++ pthread_cond_signal(&request->waiting_cond); ++ pthread_mutex_unlock(&request->waiting_mutex); + } else { + dsi_remove_from_request_queue(server,request); + } diff --git a/tools/depends/target/afpfs-ng/07-boxee4.patch b/tools/depends/target/afpfs-ng/07-boxee4.patch new file mode 100644 index 0000000..3e09f40 --- /dev/null +++ b/tools/depends/target/afpfs-ng/07-boxee4.patch @@ -0,0 +1,27 @@ +--- afpfs-ng-0.8.1/lib/identify.c 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/identify.c 2011-08-26 21:33:33.000000000 +0200 +@@ -0,0 +1,24 @@ ++#include ++#include ++ ++ ++/* ++ * afp_server_identify() ++ * ++ * Identifies a server ++ * ++ * Right now, this only does identification using the machine_type ++ * given in getsrvrinfo, but this could later use mDNS to get ++ * more details. ++ */ ++void afp_server_identify(struct afp_server * s) ++{ ++ if (strcmp(s->machine_type,"Netatalk")==0) ++ s->server_type=AFPFS_SERVER_TYPE_NETATALK; ++ else if (strcmp(s->machine_type,"AirPort")==0) ++ s->server_type=AFPFS_SERVER_TYPE_AIRPORT; ++ else if (strcmp(s->machine_type,"Macintosh")==0) ++ s->server_type=AFPFS_SERVER_TYPE_MACINTOSH; ++ else ++ s->server_type=AFPFS_SERVER_TYPE_UNKNOWN; ++} diff --git a/tools/depends/target/afpfs-ng/08-boxee5.patch b/tools/depends/target/afpfs-ng/08-boxee5.patch new file mode 100644 index 0000000..253fb05 --- /dev/null +++ b/tools/depends/target/afpfs-ng/08-boxee5.patch @@ -0,0 +1,11 @@ +--- afpfs-ng-0.8.1/lib/Makefile.am 2008-02-18 04:34:32.000000000 +0100 ++++ afpfs-ng-0.8.1/lib/Makefile.am 2011-08-26 21:33:33.000000000 +0200 +@@ -4,7 +4,7 @@ + + lib_LTLIBRARIES = libafpclient.la + +-libafpclient_la_SOURCES = afp.c codepage.c did.c dsi.c map_def.c uams.c uams_def.c unicode.c users.c utils.c resource.c log.c client.c server.c connect.c loop.c midlevel.c proto_attr.c proto_desktop.c proto_directory.c proto_files.c proto_fork.c proto_login.c proto_map.c proto_replyblock.c proto_server.c proto_volume.c proto_session.c afp_url.c status.c forklist.c debug.c lowlevel.c ++libafpclient_la_SOURCES = afp.c codepage.c did.c dsi.c map_def.c uams.c uams_def.c unicode.c users.c utils.c resource.c log.c client.c server.c connect.c loop.c midlevel.c proto_attr.c proto_desktop.c proto_directory.c proto_files.c proto_fork.c proto_login.c proto_map.c proto_replyblock.c proto_server.c proto_volume.c proto_session.c afp_url.c status.c forklist.c debug.c lowlevel.c identify.c + + # libafpclient_la_LDFLAGS = -module -avoid-version + diff --git a/tools/depends/target/afpfs-ng/10-fix-errno.patch b/tools/depends/target/afpfs-ng/10-fix-errno.patch new file mode 100644 index 0000000..ff7ce44 --- /dev/null +++ b/tools/depends/target/afpfs-ng/10-fix-errno.patch @@ -0,0 +1,23 @@ +--- afpfs-ng-0.8.1/lib/afp.c 2011-09-04 19:42:42.000000000 +0200 ++++ afpfs-ng-0.8.1/lib/afp.c 2011-09-04 19:39:44.000000000 +0200 +@@ -19,7 +19,6 @@ + #include + #include + #include +-#include + + #include + #include +--- afpfs-ng-0.8.1/lib/afp_url.c 2011-09-04 19:42:42.000000000 +0200 ++++ afpfs-ng-0.8.1/lib/afp_url.c 2011-09-04 19:40:27.000000000 +0200 +@@ -21,7 +21,9 @@ + + static int check_port(char * port) + { +- long long ret = strtol(port,NULL,10); ++ long long ret = 0; ++ errno = 0; ++ ret = strtol(port,NULL,10); + if ((ret<0) || (ret>32767)) return -1; + if (errno) { + printf("port error\n"); diff --git a/tools/depends/target/afpfs-ng/11-fix-stat.patch b/tools/depends/target/afpfs-ng/11-fix-stat.patch new file mode 100644 index 0000000..09e9a35 --- /dev/null +++ b/tools/depends/target/afpfs-ng/11-fix-stat.patch @@ -0,0 +1,11 @@ +--- afpfs-ng-0.8.1/lib/lowlevel.c 2011-10-01 20:36:55.000000000 +0200 ++++ afpfs-ng-0.8.1/lib/lowlevel.c 2011-10-01 20:46:00.000000000 +0200 +@@ -579,7 +579,7 @@ + return -EIO; + } + +- if (volume->server->using_version->av_number>=30) ++ if (volume->server->using_version->av_number>=30 && fp.unixprivs.permissions != 0) + stbuf->st_mode |= fp.unixprivs.permissions; + else + set_nonunix_perms(&stbuf->st_mode,&fp); diff --git a/tools/depends/target/afpfs-ng/Makefile b/tools/depends/target/afpfs-ng/Makefile new file mode 100644 index 0000000..1b6a664 --- /dev/null +++ b/tools/depends/target/afpfs-ng/Makefile @@ -0,0 +1,62 @@ +include ../../Makefile.include +DEPS= ../../Makefile.include 01-gcrypt.patch 02-pointer.patch 04-boxee1.patch \ + 05-boxee2.patch 06-boxee3.patch 07-boxee4.patch \ + 08-boxee5.patch 10-fix-errno.patch 11-fix-stat.patch \ + android.patch fix_afpfs-ng_includes.patch Makefile + +# lib name, version +LIBNAME=afpfs-ng +VERSION=0.8.1 +SOURCE=$(LIBNAME)-$(VERSION) +ARCHIVE=$(SOURCE).tar.bz2 + +# configuration settings +export LIBS+=$(LINK_ICONV) + +CONFIGURE=./configure --prefix=$(PREFIX) \ + --disable-fuse + +LIBDYLIB=$(PLATFORM)/lib/.libs/libafpclient.a + +all: .installed-$(PLATFORM) + +$(TARBALLS_LOCATION)/$(ARCHIVE): + cd $(TARBALLS_LOCATION); $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE) + +$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) + rm -rf $(PLATFORM); mkdir -p $(PLATFORM) + cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) + cd $(PLATFORM); patch -p1 <../fix_afpfs-ng_includes.patch + cd $(PLATFORM); patch -p1 <../01-gcrypt.patch + cd $(PLATFORM); patch -p1 <../02-pointer.patch + cd $(PLATFORM); patch -p1 <../04-boxee1.patch + cd $(PLATFORM); patch -p1 <../05-boxee2.patch + cd $(PLATFORM); patch -p1 <../06-boxee3.patch + cd $(PLATFORM); patch -p1 <../07-boxee4.patch + cd $(PLATFORM); patch -p1 <../08-boxee5.patch + cd $(PLATFORM); patch -p1 <../10-fix-errno.patch + cd $(PLATFORM); patch -p1 <../11-fix-stat.patch + cd $(PLATFORM); patch -p0 < ../android.patch + cd $(PLATFORM); $(AUTORECONF) -vif + cd $(PLATFORM); $(CONFIGURE) + +$(LIBDYLIB): $(PLATFORM) + $(MAKE) -j 1 -C $(PLATFORM)/lib + +.installed-$(PLATFORM): $(LIBDYLIB) + $(MAKE) -C $(PLATFORM)/lib install + $(MAKE) -C $(PLATFORM)/include install +ifeq ($(OS),android) + rm -f $(PREFIX)/lib/libafpclient.la $(PREFIX)/lib/libafpclient.so $(PREFIX)/lib/libafpclient.so.0 + mv -f $(PREFIX)/lib/libafpclient.so.0.0.0 $(PREFIX)/lib/libafpclient.so + $(RPL) -e "libafpclient.so.0" "libafpclient.so\x00\x00" $(PREFIX)/lib/libafpclient.so + -$(READELF) --dynamic $(PREFIX)/lib/libafpclient.so | grep ibrary +endif + touch $@ + +clean: + $(MAKE) -C $(PLATFORM) clean + rm -f .installed-$(PLATFORM) + +distclean:: + rm -rf $(PLATFORM) .installed-$(PLATFORM) diff --git a/tools/depends/target/afpfs-ng/android.patch b/tools/depends/target/afpfs-ng/android.patch new file mode 100644 index 0000000..85dcfce --- /dev/null +++ b/tools/depends/target/afpfs-ng/android.patch @@ -0,0 +1,70 @@ +--- include/afpfs-ng/afp.h 2012-06-03 22:47:49.014348648 -0400 ++++ include/afpfs-ng/afp.h 2012-06-03 22:46:28.924348698 -0400 +@@ -5,7 +5,13 @@ + #include + #include + #include ++#ifndef ANDROID + #include ++#else ++#include ++#define statvfs statfs ++#define fstatvfs fstatfs ++#endif + #include + #include + #include +--- lib/midlevel.c 2012-06-03 22:47:49.014348648 -0400 ++++ lib/midlevel.c 2012-06-03 22:46:28.924348698 -0400 +@@ -1388,10 +1388,12 @@ + stat->f_frsize=0; + stat->f_files=0; + stat->f_ffree=0; ++#ifndef ANDROID + stat->f_favail=0; + stat->f_fsid=0; + stat->f_flag=0; + stat->f_namemax=255; ++#endif + return 0; + + } +--- lib/lowlevel.c 2012-06-03 22:47:49.054348648 -0400 ++++ lib/lowlevel.c 2012-06-03 22:46:28.914348698 -0400 +@@ -612,7 +612,7 @@ + modification_date=fp.modification_date; + } + +-#ifdef __linux__ ++#if defined(__linux__) && !defined(ANDROID) + stbuf->st_ctim.tv_sec=creation_date; + stbuf->st_mtim.tv_sec=modification_date; + #else +--- lib/dsi.c 2012-06-03 23:24:15.454347269 -0400 ++++ lib/dsi.c 2012-06-03 23:25:01.634347240 -0400 +@@ -610,7 +610,11 @@ + afp_getsrvrmsg(server,AFPMESG_SERVER, + ((server->using_version->av_number>=30)?1:0), + DSI_DEFAULT_TIMEOUT,mesg); ++#if defined(ANDROID) ++ if(memcmp(mesg,"The server is going down for maintenance.",41)==0) ++#else + if(bcmp(mesg,"The server is going down for maintenance.",41)==0) ++#endif + shutdown=1; + } + +--- lib/afp.c 2012-06-03 23:24:15.474347269 -0400 ++++ lib/afp.c 2012-06-03 23:25:12.464347233 -0400 +@@ -205,7 +205,11 @@ + { + struct afp_server *s; + for (s=server_base;s;s=s->next) { ++#if defined(ANDROID) ++ if (memcmp(&s->address,address,sizeof(struct sockaddr_in))==0) ++#else + if (bcmp(&s->address,address,sizeof(struct sockaddr_in))==0) ++#endif + return s; + } + return NULL; diff --git a/tools/depends/target/afpfs-ng/fix_afpfs-ng_includes.patch b/tools/depends/target/afpfs-ng/fix_afpfs-ng_includes.patch new file mode 100644 index 0000000..08c6f02 --- /dev/null +++ b/tools/depends/target/afpfs-ng/fix_afpfs-ng_includes.patch @@ -0,0 +1,3092 @@ +diff -Naur afpfs-ng-0.8.1/cmdline/cmdline_afp.c afpfs-ng-0.8.1.patch/cmdline/cmdline_afp.c +--- afpfs-ng-0.8.1/cmdline/cmdline_afp.c 2008-02-19 02:54:19.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/cmdline/cmdline_afp.c 2011-09-10 12:13:50.102124369 +0200 +@@ -3,9 +3,9 @@ + + */ + +-#include "afp.h" +-#include "midlevel.h" +-#include "map_def.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/midlevel.h" ++#include "afpfs-ng/map_def.h" + + #include + #include +diff -Naur afpfs-ng-0.8.1/cmdline/cmdline_testafp.c afpfs-ng-0.8.1.patch/cmdline/cmdline_testafp.c +--- afpfs-ng-0.8.1/cmdline/cmdline_testafp.c 2008-03-04 21:16:50.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/cmdline/cmdline_testafp.c 2011-09-10 12:13:50.102124369 +0200 +@@ -3,8 +3,8 @@ + + */ + +-#include "afp.h" +-#include "midlevel.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/midlevel.h" + + #include "cmdline_main.h" + +diff -Naur afpfs-ng-0.8.1/cmdline/getstatus.c afpfs-ng-0.8.1.patch/cmdline/getstatus.c +--- afpfs-ng-0.8.1/cmdline/getstatus.c 2008-02-18 04:28:09.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/cmdline/getstatus.c 2011-09-10 12:13:50.109124463 +0200 +@@ -2,7 +2,7 @@ + #include + #include + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + + static int getstatus(char * address_string, unsigned int port) + { +diff -Naur afpfs-ng-0.8.1/configure.ac afpfs-ng-0.8.1.patch/configure.ac +--- afpfs-ng-0.8.1/configure.ac 2008-03-08 17:23:12.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/configure.ac 2011-09-10 12:13:50.109124463 +0200 +@@ -11,6 +11,7 @@ + AC_PROG_CC + AC_PROG_INSTALL + AC_PROG_LIBTOOL ++AM_PROG_CC_C_O + + # Checks for libraries. + # FIXME: Replace `main' with a function in `-lncurses': +@@ -105,7 +106,7 @@ + + + +-AC_CONFIG_FILES([lib/Makefile fuse/Makefile cmdline/Makefile Makefile docs/Makefile]) ++AC_CONFIG_FILES([lib/Makefile fuse/Makefile cmdline/Makefile Makefile include/Makefile include/afpfs-ng/Makefile docs/Makefile]) + + AC_OUTPUT + +diff -Naur afpfs-ng-0.8.1/fuse/client.c afpfs-ng-0.8.1.patch/fuse/client.c +--- afpfs-ng-0.8.1/fuse/client.c 2008-03-08 03:44:16.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/fuse/client.c 2011-09-10 12:13:50.110124477 +0200 +@@ -12,11 +12,11 @@ + #include + + #include "config.h" +-#include ++#include + #include "afp_server.h" +-#include "uams_def.h" +-#include "map_def.h" +-#include "libafpclient.h" ++#include "afpfs-ng/uams_def.h" ++#include "afpfs-ng/map_def.h" ++#include "afpfs-ng/libafpclient.h" + + #define default_uam "Cleartxt Passwrd" + +diff -Naur afpfs-ng-0.8.1/fuse/commands.c afpfs-ng-0.8.1.patch/fuse/commands.c +--- afpfs-ng-0.8.1/fuse/commands.c 2008-03-08 17:06:25.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/fuse/commands.c 2011-09-10 12:13:50.110124477 +0200 +@@ -19,15 +19,15 @@ + #include + #include + +-#include "afp.h" +-#include "dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/dsi.h" + #include "afp_server.h" +-#include "utils.h" ++#include "afpfs-ng/utils.h" + #include "daemon.h" +-#include "uams_def.h" +-#include "codepage.h" +-#include "libafpclient.h" +-#include "map_def.h" ++#include "afpfs-ng/uams_def.h" ++#include "afpfs-ng/codepage.h" ++#include "afpfs-ng/libafpclient.h" ++#include "afpfs-ng/map_def.h" + #include "fuse_int.h" + #include "fuse_error.h" + #include "fuse_internal.h" +diff -Naur afpfs-ng-0.8.1/fuse/daemon.c afpfs-ng-0.8.1.patch/fuse/daemon.c +--- afpfs-ng-0.8.1/fuse/daemon.c 2008-03-04 18:26:05.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/fuse/daemon.c 2011-09-10 12:13:50.110124477 +0200 +@@ -23,11 +23,11 @@ + #include + #include + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + +-#include "dsi.h" ++#include "afpfs-ng/dsi.h" + #include "afp_server.h" +-#include "utils.h" ++#include "afpfs-ng/utils.h" + #include "daemon.h" + #include "commands.h" + +diff -Naur afpfs-ng-0.8.1/fuse/fuse_error.c afpfs-ng-0.8.1.patch/fuse/fuse_error.c +--- afpfs-ng-0.8.1/fuse/fuse_error.c 2008-01-18 05:40:10.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/fuse/fuse_error.c 2011-09-10 12:13:50.111124491 +0200 +@@ -4,7 +4,7 @@ + #include + #include + #include +-#include "libafpclient.h" ++#include "afpfs-ng/libafpclient.h" + #include "fuse_internal.h" + + #define TMP_FILE "/tmp/fuse_stderr" +diff -Naur afpfs-ng-0.8.1/fuse/fuse_int.c afpfs-ng-0.8.1.patch/fuse/fuse_int.c +--- afpfs-ng-0.8.1/fuse/fuse_int.c 2008-03-02 06:06:24.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/fuse/fuse_int.c 2011-09-10 12:13:50.111124491 +0200 +@@ -18,7 +18,7 @@ + #define FUSE_USE_VERSION 25 + + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + + #include + #include +@@ -39,10 +39,10 @@ + #include + #include + +-#include "dsi.h" +-#include "afp_protocol.h" +-#include "codepage.h" +-#include "midlevel.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp_protocol.h" ++#include "afpfs-ng/codepage.h" ++#include "afpfs-ng/midlevel.h" + #include "fuse_error.h" + + /* Uncomment the following line to enable full debugging: */ +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/afp.h afpfs-ng-0.8.1.patch/include/afpfs-ng/afp.h +--- afpfs-ng-0.8.1/include/afpfs-ng/afp.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/afp.h 2011-09-10 12:13:50.112124505 +0200 +@@ -0,0 +1,533 @@ ++ ++#ifndef _AFP_H_ ++#define _AFP_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define AFPFS_VERSION "0.8.1" ++ ++/* This is the maximum AFP version this library supports */ ++#define AFP_MAX_SUPPORTED_VERSION 32 ++ ++/* afp_url is used to pass locations around */ ++struct afp_url { ++ enum {TCPIP,AT} protocol; ++ char username[AFP_MAX_USERNAME_LEN]; ++ char uamname[50]; ++ char password[AFP_MAX_PASSWORD_LEN]; ++ char servername[AFP_SERVER_NAME_UTF8_LEN]; ++ int port; ++ char volumename[AFP_VOLUME_NAME_UTF8_LEN]; ++ char path[AFP_MAX_PATH]; ++ ++ int requested_version; ++ char zone[AFP_ZONE_LEN]; /* Only used for Appletalk */ ++ char volpassword[9];; ++}; ++ ++struct afp_token { ++ unsigned int length; ++ char data[AFP_TOKEN_MAX_LEN]; ++}; ++ ++#define SERVER_MAX_VERSIONS 10 ++#define SERVER_MAX_UAMS 10 ++ ++struct afp_rx_buffer { ++ unsigned int size; ++ unsigned int maxsize; ++ char * data; ++ int errorcode; ++}; ++ ++ ++struct afp_file_info { ++ unsigned short attributes; ++ unsigned int did; ++ unsigned int creation_date; ++ unsigned int modification_date; ++ unsigned int backup_date; ++ unsigned int fileid; ++ unsigned short offspring; ++ char sync; ++ char finderinfo[32]; ++ char name[AFP_MAX_PATH]; ++ char basename[AFP_MAX_PATH]; ++ char translated_name[AFP_MAX_PATH]; ++ struct afp_unixprivs unixprivs; ++ unsigned int accessrights; ++ struct afp_file_info * next; ++ struct afp_file_info * largelist_next; ++ unsigned char isdir; ++ unsigned long long size; ++ unsigned short resourcesize; ++ unsigned int resource; ++ unsigned short forkid; ++ struct afp_icon * icon; ++ int eof; ++}; ++ ++ ++#define VOLUME_EXTRA_FLAGS_VOL_CHMOD_KNOWN 0x1 ++#define VOLUME_EXTRA_FLAGS_VOL_CHMOD_BROKEN 0x2 ++#define VOLUME_EXTRA_FLAGS_SHOW_APPLEDOUBLE 0x4 ++#define VOLUME_EXTRA_FLAGS_VOL_SUPPORTS_UNIX 0x8 ++#define VOLUME_EXTRA_FLAGS_NO_LOCKING 0x10 ++#define VOLUME_EXTRA_FLAGS_IGNORE_UNIXPRIVS 0x20 ++#define VOLUME_EXTRA_FLAGS_READONLY 0x40 ++ ++#define AFP_VOLUME_UNMOUNTED 0 ++#define AFP_VOLUME_MOUNTED 1 ++#define AFP_VOLUME_UNMOUNTING 2 ++ ++struct afp_volume { ++ unsigned short volid; ++ char flags; /* This is from afpGetSrvrParms */ ++ unsigned short attributes; /* This is from VolOpen */ ++ unsigned short signature; /* This is fixed or variable */ ++ unsigned int creation_date; ++ unsigned int modification_date; ++ unsigned int backup_date; ++ struct statvfs stat; ++ unsigned char mounted; ++ char mountpoint[255]; ++ struct afp_server * server; ++ char volume_name[AFP_VOLUME_NAME_LEN]; ++ char volume_name_printable[AFP_VOLUME_NAME_UTF8_LEN]; ++ unsigned short dtrefnum; ++ char volpassword[AFP_VOLPASS_LEN]; ++ unsigned int extra_flags; /* This is an afpfs-ng specific field */ ++ ++ /* Our directory ID cache */ ++ struct did_cache_entry * did_cache_base; ++ pthread_mutex_t did_cache_mutex; ++ ++ /* Our journal of open forks */ ++ struct afp_file_info * open_forks; ++ pthread_mutex_t open_forks_mutex; ++ ++ /* Used to trigger startup */ ++ pthread_cond_t startup_condition_cond; ++ ++ struct { ++ uint64_t hits; ++ uint64_t misses; ++ uint64_t expired; ++ uint64_t force_removed; ++ } did_cache_stats; ++ ++ void * priv; /* This is a private structure for fuse/cmdline, etc */ ++ pthread_t thread; /* This is the per-volume thread */ ++ ++ int mapping; ++ ++}; ++ ++#define SERVER_STATE_CONNECTED 1 ++#define SERVER_STATE_DISCONNECTED 2 ++ ++enum server_type{ ++ AFPFS_SERVER_TYPE_UNKNOWN, ++ AFPFS_SERVER_TYPE_NETATALK, ++ AFPFS_SERVER_TYPE_AIRPORT, ++ AFPFS_SERVER_TYPE_MACINTOSH, ++}; ++ ++#define is_netatalk(x) ( (x)->machine_type == AFPFS_SERVER_TYPE_NETATALK ) ++#define is_airport(x) ( (x)->machine_type == AFPFS_SERVER_TYPE_AIRPORT ) ++#define is_macintosh(x) ( (x)->machine_type == AFPFS_SERVER_TYPE_MACINTOSH ) ++ ++ ++ ++struct afp_versions { ++ char *av_name; ++ int av_number; ++}; ++extern struct afp_versions afp_versions[]; ++ ++struct afp_server { ++ ++ /* Our buffer sizes */ ++ unsigned int tx_quantum; ++ unsigned int rx_quantum; ++ ++ unsigned int tx_delay; ++ ++ /* Connection information */ ++ struct sockaddr_in address; ++ int fd; ++ ++ /* Some stats, for information only */ ++ struct { ++ uint64_t runt_packets; ++ uint64_t incoming_dsi; ++ uint64_t rx_bytes; ++ uint64_t tx_bytes; ++ uint64_t requests_pending; ++ } stats; ++ ++ /* General information */ ++ char server_name[AFP_SERVER_NAME_LEN]; ++ char server_name_utf8[AFP_SERVER_NAME_UTF8_LEN]; ++ char server_name_printable[AFP_SERVER_NAME_UTF8_LEN]; ++ ++ char machine_type[17]; ++ char icon[256]; ++ char signature[16]; ++ unsigned short flags; ++ int connect_state; ++ enum server_type server_type; ++ ++ /* This is the time we connected */ ++ time_t connect_time; ++ ++ /* UAMs */ ++ unsigned int supported_uams; ++ unsigned int using_uam; ++ ++ /* Authentication */ ++ char username[AFP_MAX_USERNAME_LEN]; ++ char password[AFP_MAX_PASSWORD_LEN]; ++ ++ /* Session */ ++ struct afp_token token; ++ char need_resume; ++ ++ /* Versions */ ++ unsigned char requested_version; ++ unsigned char versions[SERVER_MAX_VERSIONS]; ++ struct afp_versions *using_version; ++ ++ /* Volumes */ ++ unsigned char num_volumes; ++ struct afp_volume * volumes; ++ ++ void * dsi; ++ unsigned int exit_flag; ++ ++ /* Our DSI request queue */ ++ pthread_mutex_t requestid_mutex; ++ pthread_mutex_t request_queue_mutex; ++ unsigned short lastrequestid; ++ unsigned short expectedrequestid; ++ struct dsi_request * command_requests; ++ ++ ++ char loginmesg[200]; ++ char servermesg[200]; ++ char path_encoding; ++ ++ /* This is the data for the incoming buffer */ ++ char * incoming_buffer; ++ int data_read; ++ int bufsize; ++ ++ /* And this is for the outgoing queue */ ++ pthread_mutex_t send_mutex; ++ ++ /* This is for user mapping */ ++ struct passwd passwd; ++ unsigned int server_uid, server_gid; ++ int server_gid_valid; ++ ++ struct afp_server *next; ++ ++ /* These are for DSI attention packets */ ++ unsigned int attention_quantum; ++ unsigned int attention_len; ++ char * attention_buffer; ++ ++}; ++ ++struct afp_extattr_info { ++ unsigned int maxsize; ++ unsigned int size; ++ char data[1024]; ++}; ++struct afp_comment { ++ unsigned int maxsize; ++ unsigned int size; ++ char *data; ++}; ++ ++struct afp_icon { ++ unsigned int maxsize; ++ unsigned int size; ++ char *data; ++}; ++ ++#define AFP_DEFAULT_ATTENTION_QUANTUM 1024 ++ ++void afp_unixpriv_to_stat(struct afp_file_info *fp, ++ struct stat *stat); ++ ++int init_uams(void) ; ++ ++unsigned int find_uam_by_name(const char * name); ++char * uam_bitmap_to_string(unsigned int bitmap); ++ ++ ++char * get_uam_names_list(void); ++ ++unsigned int default_uams_mask(void); ++ ++struct afp_volume * find_volume_by_name(struct afp_server * server, ++ const char * volname); ++ ++struct afp_connection_request { ++ unsigned int uam_mask; ++ struct afp_url url; ++}; ++ ++void afp_default_url(struct afp_url *url); ++int afp_parse_url(struct afp_url * url, const char * toparse, int verbose); ++void afp_print_url(struct afp_url * url); ++int afp_url_validate(char * url_string, struct afp_url * valid_url); ++ ++int afp_list_volnames(struct afp_server * server, char * names, int max); ++ ++/* User mapping */ ++int afp_detect_mapping(struct afp_volume * volume); ++ ++/* These are some functions that help with simple status text generation */ ++ ++int afp_status_header(char * text, int * len); ++int afp_status_server(struct afp_server * s,char * text, int * len); ++ ++ ++struct afp_server * afp_server_full_connect(void * priv, struct afp_connection_request * req); ++ ++void just_end_it_now(void *other); ++void add_fd_and_signal(int fd); ++void loop_disconnect(struct afp_server *s); ++void afp_wait_for_started_loop(void); ++ ++ ++struct afp_versions * pick_version(unsigned char *versions, ++ unsigned char requested) ; ++int pick_uam(unsigned int u1, unsigned int u2); ++ ++int afp_server_login(struct afp_server *server, ++ char * mesg, unsigned int *l, unsigned int max); ++ ++ ++int afp_dologin(struct afp_server *server, ++ unsigned int uam, char * username, char * passwd); ++ ++void afp_free_server(struct afp_server **server); ++ ++struct afp_server * afp_server_init(struct sockaddr_in * address); ++int afp_get_address(void * priv, const char * hostname, unsigned int port, ++ struct sockaddr_in * address); ++ ++ ++int afp_main_loop(int command_fd); ++int afp_main_quick_startup(pthread_t * thread); ++ ++int afp_server_destroy(struct afp_server *s) ; ++int afp_server_reconnect(struct afp_server * s, char * mesg, ++ unsigned int *l, unsigned int max); ++int afp_server_connect(struct afp_server *s, int full); ++ ++struct afp_server * afp_server_complete_connection( ++ void * priv, ++ struct afp_server * server, ++ struct sockaddr_in * address, unsigned char * versions, ++ unsigned int uams, char * username, char * password, ++ unsigned int requested_version, unsigned int uam_mask); ++ ++int afp_connect_volume(struct afp_volume * volume, struct afp_server * server, ++ char * mesg, unsigned int * l, unsigned int max); ++int something_is_mounted(struct afp_server * server); ++ ++int add_cache_entry(struct afp_file_info * file) ; ++struct afp_file_info * get_cache_by_name(char * name); ++struct afp_server * find_server_by_address(struct sockaddr_in * address); ++struct afp_server * find_server_by_signature(char * signature); ++struct afp_server * find_server_by_name(char * name); ++int server_still_valid(struct afp_server * server); ++ ++ ++struct afp_server * get_server_base(void); ++int afp_server_remove(struct afp_server * server); ++ ++int afp_unmount_volume(struct afp_volume * volume); ++int afp_unmount_all_volumes(struct afp_server * server); ++ ++#define volume_is_readonly(x) (((x)->attributes&kReadOnly) || \ ++ ((x)->extra_flags & VOLUME_EXTRA_FLAGS_READONLY)) ++ ++int afp_opendt(struct afp_volume *volume, unsigned short * refnum); ++ ++int afp_closedt(struct afp_server * server, unsigned short * refnum); ++ ++int afp_getcomment(struct afp_volume *volume, unsigned int did, ++ const char * pathname, struct afp_comment * comment); ++ ++int afp_addcomment(struct afp_volume *volume, unsigned int did, ++ const char * pathname, char * comment,uint64_t *size); ++ ++int afp_geticon(struct afp_volume * volume, unsigned int filecreator, ++ unsigned int filetype, unsigned char icontype, ++ unsigned short length, struct afp_icon * icon); ++ ++/* Things you want to do to a server */ ++ ++int afp_getsrvrmsg(struct afp_server *server, unsigned short messagetype,unsigned char utf8, unsigned char block, char * mesg); ++ ++int afp_login(struct afp_server *server, char * uaname, ++ char * userauthinfo, unsigned int userauthinfo_len, ++ struct afp_rx_buffer *rx); ++ ++int afp_changepassword(struct afp_server *server, char * uaname, ++ char * userauthinfo, unsigned int userauthinfo_len, ++ struct afp_rx_buffer *rx); ++ ++int afp_logincont(struct afp_server *server, unsigned short id, ++ char * userauthinfo, unsigned int userauthinfo_len, ++ struct afp_rx_buffer *rx); ++ ++int afp_getsessiontoken(struct afp_server * server, int type, ++ unsigned int timestamp, struct afp_token *outgoing_token, ++ struct afp_token * incoming_token); ++ ++int afp_getsrvrparms(struct afp_server *server); ++ ++int afp_logout(struct afp_server *server,unsigned char wait); ++ ++int afp_mapname(struct afp_server * server, unsigned char subfunction, ++ char * name, unsigned int * id); ++ ++int afp_mapid(struct afp_server * server, unsigned char subfunction, ++ unsigned int id, char *name); ++ ++int afp_getuserinfo(struct afp_server * server, int thisuser, ++ unsigned int userid, unsigned short bitmap, ++ unsigned int *newuid, unsigned int *newgid); ++ ++int afp_zzzzz(struct afp_server *server); ++ ++int afp_volopen(struct afp_volume * volume, ++ unsigned short bitmap, char * password); ++ ++int afp_flush(struct afp_volume * volume); ++ ++int afp_getfiledirparms(struct afp_volume *volume, unsigned int did, ++ unsigned int filebitmap, unsigned int dirbitmap, const char * pathname, ++ struct afp_file_info *fp); ++ ++int afp_enumerate(struct afp_volume * volume, ++ unsigned int dirid, ++ unsigned int filebitmap, unsigned int dirbitmap, ++ unsigned short reqcount, ++ unsigned short startindex, ++ char * path, ++ struct afp_file_info ** file_p); ++ ++int afp_enumerateext2(struct afp_volume * volume, ++ unsigned int dirid, ++ unsigned int filebitmap, unsigned int dirbitmap, ++ unsigned short reqcount, ++ unsigned long startindex, ++ char * path, ++ struct afp_file_info ** file_p); ++ ++int afp_openfork(struct afp_volume * volume, ++ unsigned char forktype, ++ unsigned int dirid, ++ unsigned short accessmode, ++ char * filename, ++ struct afp_file_info *fp); ++ ++int afp_read(struct afp_volume * volume, unsigned short forkid, ++ uint32_t offset, ++ uint32_t count, struct afp_rx_buffer * rx); ++ ++int afp_readext(struct afp_volume * volume, unsigned short forkid, ++ uint64_t offset, ++ uint64_t count, struct afp_rx_buffer * rx); ++ ++int afp_getvolparms(struct afp_volume * volume, unsigned short bitmap); ++ ++ ++int afp_createdir(struct afp_volume * volume, unsigned int dirid, const char * pathname, unsigned int *did_p); ++ ++int afp_delete(struct afp_volume * volume, ++ unsigned int dirid, char * pathname); ++ ++ ++int afp_createfile(struct afp_volume * volume, unsigned char flag, ++ unsigned int did, char * pathname); ++ ++int afp_write(struct afp_volume * volume, unsigned short forkid, ++ uint32_t offset, uint32_t reqcount, ++ char * data, uint32_t * written); ++ ++int afp_writeext(struct afp_volume * volume, unsigned short forkid, ++ uint64_t offset, uint64_t reqcount, ++ char * data, uint64_t * written); ++ ++int afp_flushfork(struct afp_volume * volume, unsigned short forkid); ++ ++int afp_closefork(struct afp_volume * volume, unsigned short forkid); ++int afp_setfileparms(struct afp_volume * volume, ++ unsigned int dirid, const char * pathname, unsigned short bitmap, ++ struct afp_file_info *fp); ++int afp_setfiledirparms(struct afp_volume * volume, ++ unsigned int dirid, const char * pathname, unsigned short bitmap, ++ struct afp_file_info *fp); ++ ++int afp_setdirparms(struct afp_volume * volume, ++ unsigned int dirid, const char * pathname, unsigned short bitmap, ++ struct afp_file_info *fp); ++ ++int afp_volclose(struct afp_volume * volume); ++ ++ ++int afp_setforkparms(struct afp_volume *volume, ++ unsigned short forkid, unsigned short bitmap, unsigned long len); ++ ++int afp_byterangelock(struct afp_volume * volume, ++ unsigned char flag, ++ unsigned short forkid, ++ uint32_t offset, ++ uint32_t len, uint32_t *generated_offset); ++ ++int afp_byterangelockext(struct afp_volume * volume, ++ unsigned char flag, ++ unsigned short forkid, ++ uint64_t offset, ++ uint64_t len, uint64_t *generated_offset); ++ ++int afp_moveandrename(struct afp_volume *volume, ++ unsigned int src_did, ++ unsigned int dst_did, ++ char * src_path, char * dst_path, char *new_name); ++ ++int afp_rename(struct afp_volume * volume, ++ unsigned int dirid, ++ char * path_from, char * path_to); ++ ++int afp_listextattr(struct afp_volume * volume, ++ unsigned int dirid, unsigned short bitmap, ++ char * pathname, struct afp_extattr_info * info); ++ ++/* This is a currently undocumented command */ ++int afp_newcommand76(struct afp_volume * volume, unsigned int dlen, char * data); ++ ++/* For debugging */ ++char * afp_get_command_name(char code); ++ ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/afp_protocol.h afpfs-ng-0.8.1.patch/include/afpfs-ng/afp_protocol.h +--- afpfs-ng-0.8.1/include/afpfs-ng/afp_protocol.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/afp_protocol.h 2011-09-10 12:13:50.112124505 +0200 +@@ -0,0 +1,361 @@ ++ ++#ifndef _AFP_PROTOCOL_H_ ++#define _AFP_PROTOCOL_H_ ++ ++#include ++#include ++#include ++#include ++ ++/* This file defines constants for the Apple File Protocol. ++ All page references are from "Apple Filing Protocol Programming" version 3.2. ++ except where noted. ++*/ ++ ++#define AFP_SERVER_NAME_LEN 33 ++#define AFP_SERVER_NAME_UTF8_LEN 255 ++#define AFP_VOLUME_NAME_LEN 33 ++#define AFP_VOLUME_NAME_UTF8_LEN 33 ++#define AFP_SIGNATURE_LEN 16 ++#define AFP_MACHINETYPE_LEN 33 ++#define AFP_LOGINMESG_LEN 200 ++#define AFP_VOLPASS_LEN 8 ++#define AFP_HOSTNAME_LEN 255 ++/* This is actually just a guess, and only used for appletalk */ ++#define AFP_ZONE_LEN 255 ++ ++#define AFP_SERVER_ICON_LEN 256 ++ ++ ++#define AFP_MAX_USERNAME_LEN 127 ++#define AFP_MAX_PASSWORD_LEN 127 ++ ++ ++/* This is the maximum length of any UAM string */ ++#define AFP_UAM_LENGTH 24 ++ ++/* This is the maximum length of any path description */ ++#define AFP_MAX_PATH 768 ++ ++#define AFP_VOL_FLAT 1 ++#define AFP_VOL_FIXED 2 ++#define AFP_VOL_VARIABLE 3 ++ ++/* The root directory ID, p.26 */ ++ ++#define AFP_ROOT_DID 2 ++ ++/* Path type constants, p.249 */ ++ ++enum { ++kFPShortName = 1, ++kFPLongName = 2, ++kFPUTF8Name = 3 ++}; ++ ++/* fork types */ ++ ++#define AFP_FORKTYPE_DATA 0x0 ++#define AFP_FORKTYPE_RESOURCE 0x80 ++ ++/* openfork access modes, from p.196 */ ++ ++#define AFP_OPENFORK_ALLOWREAD 1 ++#define AFP_OPENFORK_ALLOWWRITE 2 ++#define AFP_OPENFORK_DENYREAD 0x10 ++#define AFP_OPENFORK_DENYWRITE 0x20 ++ ++/* Message type for getsrvmesg, p. 169*/ ++ ++typedef enum { ++ AFPMESG_LOGIN = 0, ++ AFPMESG_SERVER = 1 ++} afpmessage_t; ++ ++/* Message bitmap for getsrvrmsg */ ++ ++#define AFP_GETSRVRMSG_UTF8 0x2 ++#define AFP_GETSRVRMSG_GETMSG 0x1 ++ ++ ++/* Maximum Version length, p.17 */ ++#define AFP_MAX_VERSION_LENGTH 16 ++ ++/* Maximum length of a token, this is undocumented */ ++#define AFP_TOKEN_MAX_LEN 256 ++ ++/* The maximum size of a file for AFP 2 */ ++#define AFP_MAX_AFP2_FILESIZE (4294967296) ++ ++/* Unix privs, p.240 */ ++ ++struct afp_unixprivs { ++ uint32_t uid __attribute__((__packed__)); ++ uint32_t gid __attribute__((__packed__)); ++ uint32_t permissions __attribute__((__packed__)); ++ uint32_t ua_permissions __attribute__((__packed__)); ++ ++}; ++ ++ ++/* AFP Volume attributes bitmap, p.241 */ ++ ++enum { ++ kReadOnly = 0x01, ++ kHasVolumePassword = 0x02, ++ kSupportsFileIDs = 0x04, ++ kSupportsCatSearch = 0x08, ++ kSupportsBlankAccessPrivs = 0x10, ++ kSupportsUnixPrivs = 0x20, ++ kSupportsUTF8Names = 0x40, ++ kNoNetworkUserIDs = 0x80, ++ kDefaultPrivsFromParent = 0x100, ++ kNoExchangeFiles = 0x200, ++ kSupportsExtAttrs = 0x400, ++ kSupportsACLs=0x800 ++}; ++ ++/* AFP file creation constantes, p.250 */ ++enum { ++kFPSoftCreate = 0, ++kFPHardCreate = 0x80 ++}; ++ ++/* AFP Directory attributes, taken from the protocol guide p.236 */ ++ ++enum { ++ kFPAttributeBit = 0x1, ++ kFPParentDirIDBit = 0x2, ++ kFPCreateDateBit = 0x4, ++ kFPModDateBit = 0x8, ++ kFPBackupDateBit = 0x10, ++ kFPFinderInfoBit = 0x20, ++ kFPLongNameBit = 0x40, ++ kFPShortNameBit = 0x80, ++ kFPNodeIDBit = 0x100, ++ kFPOffspringCountBit = 0x0200, ++ kFPOwnerIDBit = 0x0400, ++ kFPGroupIDBit = 0x0800, ++ kFPAccessRightsBit = 0x1000, ++ kFPProDOSInfoBit = 0x2000, // AFP version 2.2 and earlier ++ kFPUTF8NameBit = 0x2000, // AFP version 3.0 and later ++ kFPUnixPrivsBit = 0x8000 // AFP version 3.0 and later ++}; ++ ++/* AFP File bitmap, p.238. These are the ones not in the AFP Directory ++ attributes map. */ ++ ++enum { ++ kFPDataForkLenBit = 0x0200, ++ kFPRsrcForkLenBit = 0x0400, ++ kFPExtDataForkLenBit = 0x0800, // AFP version 3.0 and later ++ kFPLaunchLimitBit = 0x1000, ++ kFPExtRsrcForkLenBit = 0x4000, // AFP version 3.0 and later ++}; ++ ++/* AFP Extended Attributes Bitmap, p.238 */ ++ ++enum { ++ kXAttrNoFollow = 0x1, ++ kXAttrCreate = 0x2, ++ kXAttrREplace=0x4 ++}; ++ ++ ++/* AFP function codes */ ++enum AFPFunction ++{ ++ afpByteRangeLock = 1, afpCloseVol, afpCloseDir, afpCloseFork, ++ afpCopyFile, afpCreateDir, afpCreateFile, ++ afpDelete, afpEnumerate, afpFlush, afpFlushFork, ++ afpGetForkParms = 14, afpGetSrvrInfo, afpGetSrvrParms, ++ afpGetVolParms, afpLogin, afpLoginCont, afpLogout, afpMapID, ++ afpMapName, afpMoveAndRename, afpOpenVol, afpOpenDir, afpOpenFork, ++ afpRead, afpRename, afpSetDirParms, afpSetFileParms, ++ afpSetForkParms, afpSetVolParms, afpWrite, afpGetFileDirParms, ++ afpSetFileDirParms, afpChangePassword, ++ afpGetUserInfo=37,afpGetSrvrMsg = 38, ++ afpOpenDT=48, ++ afpCloseDT=49, ++ afpGetIcon=51, afpGetIconInfo=52, ++ afpAddComment=56, afpRemoveComment=57, afpGetComment=58, ++ afpByteRangeLockExt=59, afpReadExt, afpWriteExt, ++ afpGetAuthMethods=62, ++ afp_LoginExt=63, ++ afpGetSessionToken=64, ++ afpDisconnectOldSession=65, ++ afpEnumerateExt=66, ++ afpCatSearchExt = 67, ++ afpEnumerateExt2 = 68, afpGetExtAttr, afpSetExtAttr, ++ afpRemoveExtAttr , afpListExtAttrs, ++ afpZzzzz = 122, ++ afpAddIcon=192, ++}; ++ ++/* AFP Volume bitmap. Take from 242 of the protocol guide. */ ++enum { ++ kFPBadVolPre222Bitmap = 0xFe00, ++ kFPBadVolBitmap = 0xF000, ++ kFPVolAttributeBit = 0x1, ++ kFPVolSignatureBit = 0x2, ++ kFPVolCreateDateBit = 0x4, ++ kFPVolModDateBit = 0x8, ++ kFPVolBackupDateBit = 0x10, ++ kFPVolIDBit = 0x20, ++ kFPVolBytesFreeBit = 0x40, ++ kFPVolBytesTotalBit = 0x80, ++ kFPVolNameBit = 0x100, ++ kFPVolExtBytesFreeBit = 0x200, ++ kFPVolExtBytesTotalBit = 0x400, ++ kFPVolBlockSizeBit = 0x800 ++}; ++ ++/* AFP Attention Codes -- 4 bits */ ++#define AFPATTN_SHUTDOWN (1 << 15) /* shutdown/disconnect */ ++#define AFPATTN_CRASH (1 << 14) /* server crashed */ ++#define AFPATTN_MESG (1 << 13) /* server has message */ ++#define AFPATTN_NORECONNECT (1 << 12) /* don't reconnect */ ++/* server notification */ ++#define AFPATTN_NOTIFY (AFPATTN_MESG | AFPATTN_NORECONNECT) ++ ++/* extended bitmap -- 12 bits. volchanged is only useful w/ a server ++ * notification, and time is only useful for shutdown. */ ++#define AFPATTN_VOLCHANGED (1 << 0) /* volume has changed */ ++#define AFPATTN_TIME(x) ((x) & 0xfff) /* time in minutes */ ++ ++#define kFPNoErr 0 ++ ++/* AFP result codes, p252 */ ++#define kASPSessClosed -1072 ++#define kFPAccessDenied -5000 ++#define kFPAuthContinue -5001 ++#define kFPBadUAM -5002 ++#define kFPBadVersNum -5003 ++#define kFPBitmapErr -5004 ++#define kFPCantMove -5005 ++#define kFPDenyConflict -5006 ++#define kFPDirNotEmpty -5007 ++#define kFPDiskFull -5008 ++#define kFPEOFErr -5009 ++#define kFPFileBusy -5010 ++#define kFPFlatVol -5011 ++#define kFPItemNotFound -5012 ++#define kFPLockErr -5013 ++#define kFPMiscErr -5014 ++#define kFPNoMoreLocks -5015 ++#define kFPNoServer -5016 ++#define kFPObjectExists -5017 ++#define kFPObjectNotFound -5018 ++#define kFPParamErr -5019 ++#define kFPRangeNotLocked -5020 ++#define kFPRangeOverlap -5021 ++#define kFPSessClosed -5022 ++#define kFPUserNotAuth -5023 ++#define kFPCallNotSupported -5024 ++#define kFPObjectTypeErr -5025 ++#define kFPTooManyFilesOpen -5026 ++#define kFPServerGoingDown -5027 ++#define kFPCantRename -5028 ++#define kFPDirNotFound -5029 ++#define kFPIconTypeError -5030 ++#define kFPVolLocked -5031 ++#define kFPObjectLocked -5032 ++#define kFPContainsSharedErr -5033 ++#define kFPIDNotFound -5034 ++#define kFPIDExists -5035 ++#define kFPDiffVolErr -5036 ++#define kFPCatalogChanged -5037 ++#define kFPSameObjectErr -5038 ++#define kFPBadIDErr -5039 ++#define kFPPwdSameErr -5040 ++#define kFPPwdTooShortErr -5041 ++#define kFPPwdExpiredErr -5042 ++#define kFPInsideSharedErr -5043 ++#define kFPInsideTrashErr -5044 ++#define kFPPwdNeedsChangeErr -5045 ++#define kFPPwdPolicyErr -5046 ++#define kFPDiskQuotaExceeded –5047 ++ ++ ++ ++/* These flags determine to lock or unlock in ByteRangeLock(Ext) */ ++ ++enum { ++ByteRangeLock_Lock = 0, ++ByteRangeLock_Unlock = 1 ++}; ++ ++/* These flags are used in volopen and getsrvrparm replies, p.171 */ ++ ++#define HasConfigInfo 0x1 ++#define HasPassword 0x80 ++ ++/* These are the subfunction for kFPMapID, as per p.248 */ ++ ++enum { ++kUserIDToName = 1, ++kGroupIDToName = 2, ++kUserIDToUTF8Name = 3, ++kGroupIDToUTF8Name = 4, ++kUserUUIDToUTF8Name = 5, ++kGroupUUIDToUTF8Name = 6 ++}; ++ ++ ++/* These are the subfunction flags described in the FPMapName command, p.286. ++ Note that this is different than what's described on p. 186. */ ++ ++enum { ++kNameToUserID = 1, ++kNameToGroupID = 2, ++kUTF8NameToUserID = 3, ++kUTF8NameToGroupID = 4, ++kUTF8NameToUserUUID = 5, ++kUTF8NameToGroupUUID = 6 ++}; ++ ++/* These are bits for FPGetUserInfo, p.173. */ ++#define kFPGetUserInfo_USER_ID 1 ++#define kFPGetUserInfo_PRI_GROUPID 2 ++ ++/* Flags for the replies of GetSrvrInfo and DSI GetStatus, p.240 */ ++ ++enum { ++ kSupportsCopyfile = 0x01, ++ kSupportsChgPwd = 0x02, ++ kDontAllowSavePwd = 0x04, ++ kSupportsSrvrMsg = 0x08, ++ kSrvrSig = 0x10, ++ kSupportsTCP = 0x20, ++ kSupportsSrvrNotify = 0x40, ++ kSupportsReconnect = 0x80, ++ kSupportsDirServices = 0x100, ++ kSupportsUTF8SrvrName = 0x200, ++ kSupportsUUIDs = 0x400, ++ kSupportsSuperClient = 0x8000 ++}; ++ ++ ++/* p.247 */ ++ ++enum { ++ kLoginWithoutID = 0, ++ kLoginWithID = 1, ++ kReconnWithID = 2, ++ kLoginWithTimeAndID = 3, ++ kReconnWithTimeAndID = 4, ++ kRecon1Login = 5, ++ kRecon1ReconnectLogin = 6, ++ kRecon1Refresh = 7, kGetKerberosSessionKey = 8 ++}; ++ ++ ++#define AFP_CHMOD_ALLOWED_BITS_22 \ ++ (S_IRUSR |S_IWUSR | S_IRGRP | S_IWGRP |S_IROTH | S_IWOTH | S_IFREG ) ++ ++ ++#endif ++ ++ ++ ++ +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/codepage.h afpfs-ng-0.8.1.patch/include/afpfs-ng/codepage.h +--- afpfs-ng-0.8.1/include/afpfs-ng/codepage.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/codepage.h 2011-09-10 12:13:50.113124518 +0200 +@@ -0,0 +1,11 @@ ++#ifndef __CODE_PAGE_H_ ++#define __CODE_PAGE_H_ ++int convert_utf8dec_to_utf8pre(const char *src, int src_len, ++ char * dest, int dest_len); ++int convert_utf8pre_to_utf8dec(const char * src, int src_len, ++ char * dest, int dest_len); ++int convert_path_to_unix(char encoding, char * dest, ++ char * src, int dest_len); ++int convert_path_to_afp(char encoding, char * dest, ++ char * src, int dest_len); ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/dsi.h afpfs-ng-0.8.1.patch/include/afpfs-ng/dsi.h +--- afpfs-ng-0.8.1/include/afpfs-ng/dsi.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/dsi.h 2011-09-10 12:13:50.115124544 +0200 +@@ -0,0 +1,33 @@ ++ ++#ifndef __DSI_H_ ++#define __DSI_H_ ++ ++#include "afpfs-ng/afp.h" ++ ++struct dsi_request ++{ ++ unsigned short requestid; ++ unsigned char subcommand; ++ void * other; ++ unsigned char wait; ++ pthread_cond_t condition_cond; ++ struct dsi_request * next; ++ int return_code; ++}; ++ ++int dsi_receive(struct afp_server * server, void * data, int size); ++int dsi_getstatus(struct afp_server * server); ++ ++int dsi_opensession(struct afp_server *server); ++ ++int dsi_send(struct afp_server *server, char * msg, int size,int wait,unsigned char subcommand, void ** other); ++struct dsi_session * dsi_create(struct afp_server *server); ++int dsi_restart(struct afp_server *server); ++int dsi_recv(struct afp_server * server); ++ ++#define DSI_BLOCK_TIMEOUT -1 ++#define DSI_DONT_WAIT 0 ++#define DSI_DEFAULT_TIMEOUT 5 ++ ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/libafpclient.h afpfs-ng-0.8.1.patch/include/afpfs-ng/libafpclient.h +--- afpfs-ng-0.8.1/include/afpfs-ng/libafpclient.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/libafpclient.h 2011-09-10 12:13:50.115124544 +0200 +@@ -0,0 +1,50 @@ ++ ++#ifndef __CLIENT_H_ ++#define __CLIENT_H_ ++ ++#include ++#include ++ ++#define MAX_CLIENT_RESPONSE 2048 ++ ++ ++enum loglevels { ++ AFPFSD, ++}; ++ ++struct afp_server; ++struct afp_volume; ++ ++struct libafpclient { ++ int (*unmount_volume) (struct afp_volume * volume); ++ void (*log_for_client)(void * priv, ++ enum loglevels loglevel, int logtype, const char *message); ++ void (*forced_ending_hook)(void); ++ int (*scan_extra_fds)(int command_fd,fd_set *set, int * max_fd); ++ void (*loop_started)(void); ++} ; ++ ++extern struct libafpclient * libafpclient; ++ ++void libafpclient_register(struct libafpclient * tmpclient); ++ ++ ++void signal_main_thread(void); ++ ++/* These are logging functions */ ++ ++#define MAXLOGSIZE 2048 ++ ++#define LOG_METHOD_SYSLOG 1 ++#define LOG_METHOD_STDOUT 2 ++ ++void set_log_method(int m); ++ ++ ++void log_for_client(void * priv, ++ enum loglevels loglevel, int logtype, char * message,...); ++ ++void stdout_log_for_client(void * priv, ++ enum loglevels loglevel, int logtype, const char *message); ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/Makefile.am afpfs-ng-0.8.1.patch/include/afpfs-ng/Makefile.am +--- afpfs-ng-0.8.1/include/afpfs-ng/Makefile.am 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/Makefile.am 2011-09-10 12:13:50.115124544 +0200 +@@ -0,0 +1,6 @@ ++## Process this file with automake to produce Makefile.in ++ ++afpfsincludedir = $(includedir)/afpfs-ng ++ ++afpfsinclude_HEADERS = afp.h afp_protocol.h libafpclient.h ++nodist_afpfsinclude_HEADERS = codepage.h dsi.h map_def.h midlevel.h uams_def.h utils.h +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/map_def.h afpfs-ng-0.8.1.patch/include/afpfs-ng/map_def.h +--- afpfs-ng-0.8.1/include/afpfs-ng/map_def.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/map_def.h 2011-09-10 12:13:50.116124557 +0200 +@@ -0,0 +1,15 @@ ++#ifndef __MAP_H_ ++#define __MAP_H_ ++ ++#include "afpfs-ng/afp.h" ++ ++#define AFP_MAPPING_UNKNOWN 0 ++#define AFP_MAPPING_COMMON 1 ++#define AFP_MAPPING_LOGINIDS 2 ++#define AFP_MAPPING_NAME 3 ++ ++unsigned int map_string_to_num(char * name); ++char * get_mapping_name(struct afp_volume * volume); ++ ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/midlevel.h afpfs-ng-0.8.1.patch/include/afpfs-ng/midlevel.h +--- afpfs-ng-0.8.1/include/afpfs-ng/midlevel.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/midlevel.h 2011-09-10 12:13:50.116124557 +0200 +@@ -0,0 +1,64 @@ ++#ifndef __MIDLEVEL_H_ ++#define __MIDLEVEL_H_ ++ ++#include ++#include "afpfs-ng/afp.h" ++ ++int ml_open(struct afp_volume * volume, const char *path, int flags, ++ struct afp_file_info **newfp); ++ ++int ml_creat(struct afp_volume * volume, const char *path,mode_t mode); ++ ++int ml_readdir(struct afp_volume * volume, ++ const char *path, ++ struct afp_file_info **base); ++ ++int ml_read(struct afp_volume * volume, const char *path, ++ char *buf, size_t size, off_t offset, ++ struct afp_file_info *fp, int * eof); ++ ++int ml_chmod(struct afp_volume * vol, const char * path, mode_t mode); ++ ++int ml_unlink(struct afp_volume * vol, const char *path); ++ ++int ml_mkdir(struct afp_volume * vol, const char * path, mode_t mode); ++ ++int ml_close(struct afp_volume * volume, const char * path, ++ struct afp_file_info * fp); ++ ++int ml_getattr(struct afp_volume * volume, const char *path, ++ struct stat *stbuf); ++ ++int ml_write(struct afp_volume * volume, const char * path, ++ const char *data, size_t size, off_t offset, ++ struct afp_file_info * fp, uid_t uid, ++ gid_t gid); ++ ++int ml_readlink(struct afp_volume * vol, const char * path, ++ char *buf, size_t size); ++ ++int ml_rmdir(struct afp_volume * vol, const char *path); ++ ++int ml_chown(struct afp_volume * vol, const char * path, ++ uid_t uid, gid_t gid); ++ ++int ml_truncate(struct afp_volume * vol, const char * path, off_t offset); ++ ++int ml_utime(struct afp_volume * vol, const char * path, ++ struct utimbuf * timebuf); ++ ++int ml_symlink(struct afp_volume *vol, const char * path1, const char * path2); ++ ++int ml_rename(struct afp_volume * vol, ++ const char * path_from, const char * path_to); ++ ++int ml_statfs(struct afp_volume * vol, const char *path, struct statvfs *stat); ++ ++void afp_ml_filebase_free(struct afp_file_info **filebase); ++ ++int ml_passwd(struct afp_server *server, ++ char * username, char * oldpasswd, char * newpasswd); ++ ++ ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/uams_def.h afpfs-ng-0.8.1.patch/include/afpfs-ng/uams_def.h +--- afpfs-ng-0.8.1/include/afpfs-ng/uams_def.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/uams_def.h 2011-09-10 12:13:50.116124557 +0200 +@@ -0,0 +1,16 @@ ++#ifndef __UAM_DEFS_H_ ++#define __UAM_DEFS_H_ ++ ++#define UAM_NOUSERAUTHENT 0x1 ++#define UAM_CLEARTXTPASSWRD 0x2 ++#define UAM_RANDNUMEXCHANGE 0x4 ++#define UAM_2WAYRANDNUM 0x8 ++#define UAM_DHCAST128 0x10 ++#define UAM_CLIENTKRB 0x20 ++#define UAM_DHX2 0x40 ++#define UAM_RECON1 0x80 ++ ++int uam_string_to_bitmap(char * name); ++char * uam_bitmap_to_string(unsigned int bitmap); ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afpfs-ng/utils.h afpfs-ng-0.8.1.patch/include/afpfs-ng/utils.h +--- afpfs-ng-0.8.1/include/afpfs-ng/utils.h 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afpfs-ng/utils.h 2011-09-10 12:13:50.116124557 +0200 +@@ -0,0 +1,43 @@ ++#ifndef __UTILS_H_ ++#define __UTILS_H_ ++#include ++ ++#include "afpfs-ng/afp.h" ++ ++#if BYTE_ORDER == BIG_ENDIAN ++#define hton64(x) (x) ++#define ntoh64(x) (x) ++#else /* BYTE_ORDER == BIG_ENDIAN */ ++#define hton64(x) ((u_int64_t) (htonl(((x) >> 32) & 0xffffffffLL)) | \ ++ (u_int64_t) ((htonl(x) & 0xffffffffLL) << 32)) ++#define ntoh64(x) (hton64(x)) ++#endif /* BYTE_ORDER == BIG_ENDIAN */ ++ ++#define min(a,b) (((a)<(b)) ? (a) : (b)) ++#define max(a,b) (((a)>(b)) ? (a) : (b)) ++ ++ ++ ++unsigned char unixpath_to_afppath( ++ struct afp_server * server, ++ char * buf); ++ ++unsigned char sizeof_path_header(struct afp_server * server); ++ ++ ++ ++unsigned char copy_from_pascal(char *dest, char *pascal,unsigned int max_len) ; ++unsigned short copy_from_pascal_two(char *dest, char *pascal,unsigned int max_len); ++ ++unsigned char copy_to_pascal(char *dest, const char *src); ++unsigned short copy_to_pascal_two(char *dest, const char *src); ++ ++void copy_path(struct afp_server * server, char * dest, const char * pathname, unsigned char len); ++ ++ ++char * create_path(struct afp_server * server, char * pathname, unsigned short * len); ++ ++ ++int invalid_filename(struct afp_server * server, const char * filename); ++ ++#endif +diff -Naur afpfs-ng-0.8.1/include/afp.h afpfs-ng-0.8.1.patch/include/afp.h +--- afpfs-ng-0.8.1/include/afp.h 2008-03-08 17:08:18.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afp.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,533 +0,0 @@ +- +-#ifndef _AFP_H_ +-#define _AFP_H_ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +- +-#define AFPFS_VERSION "0.8.1" +- +-/* This is the maximum AFP version this library supports */ +-#define AFP_MAX_SUPPORTED_VERSION 32 +- +-/* afp_url is used to pass locations around */ +-struct afp_url { +- enum {TCPIP,AT} protocol; +- char username[AFP_MAX_USERNAME_LEN]; +- char uamname[50]; +- char password[AFP_MAX_PASSWORD_LEN]; +- char servername[AFP_SERVER_NAME_UTF8_LEN]; +- int port; +- char volumename[AFP_VOLUME_NAME_UTF8_LEN]; +- char path[AFP_MAX_PATH]; +- +- int requested_version; +- char zone[AFP_ZONE_LEN]; /* Only used for Appletalk */ +- char volpassword[9];; +-}; +- +-struct afp_token { +- unsigned int length; +- char data[AFP_TOKEN_MAX_LEN]; +-}; +- +-#define SERVER_MAX_VERSIONS 10 +-#define SERVER_MAX_UAMS 10 +- +-struct afp_rx_buffer { +- unsigned int size; +- unsigned int maxsize; +- char * data; +- int errorcode; +-}; +- +- +-struct afp_file_info { +- unsigned short attributes; +- unsigned int did; +- unsigned int creation_date; +- unsigned int modification_date; +- unsigned int backup_date; +- unsigned int fileid; +- unsigned short offspring; +- char sync; +- char finderinfo[32]; +- char name[AFP_MAX_PATH]; +- char basename[AFP_MAX_PATH]; +- char translated_name[AFP_MAX_PATH]; +- struct afp_unixprivs unixprivs; +- unsigned int accessrights; +- struct afp_file_info * next; +- struct afp_file_info * largelist_next; +- unsigned char isdir; +- unsigned long long size; +- unsigned short resourcesize; +- unsigned int resource; +- unsigned short forkid; +- struct afp_icon * icon; +- int eof; +-}; +- +- +-#define VOLUME_EXTRA_FLAGS_VOL_CHMOD_KNOWN 0x1 +-#define VOLUME_EXTRA_FLAGS_VOL_CHMOD_BROKEN 0x2 +-#define VOLUME_EXTRA_FLAGS_SHOW_APPLEDOUBLE 0x4 +-#define VOLUME_EXTRA_FLAGS_VOL_SUPPORTS_UNIX 0x8 +-#define VOLUME_EXTRA_FLAGS_NO_LOCKING 0x10 +-#define VOLUME_EXTRA_FLAGS_IGNORE_UNIXPRIVS 0x20 +-#define VOLUME_EXTRA_FLAGS_READONLY 0x40 +- +-#define AFP_VOLUME_UNMOUNTED 0 +-#define AFP_VOLUME_MOUNTED 1 +-#define AFP_VOLUME_UNMOUNTING 2 +- +-struct afp_volume { +- unsigned short volid; +- char flags; /* This is from afpGetSrvrParms */ +- unsigned short attributes; /* This is from VolOpen */ +- unsigned short signature; /* This is fixed or variable */ +- unsigned int creation_date; +- unsigned int modification_date; +- unsigned int backup_date; +- struct statvfs stat; +- unsigned char mounted; +- char mountpoint[255]; +- struct afp_server * server; +- char volume_name[AFP_VOLUME_NAME_LEN]; +- char volume_name_printable[AFP_VOLUME_NAME_UTF8_LEN]; +- unsigned short dtrefnum; +- char volpassword[AFP_VOLPASS_LEN]; +- unsigned int extra_flags; /* This is an afpfs-ng specific field */ +- +- /* Our directory ID cache */ +- struct did_cache_entry * did_cache_base; +- pthread_mutex_t did_cache_mutex; +- +- /* Our journal of open forks */ +- struct afp_file_info * open_forks; +- pthread_mutex_t open_forks_mutex; +- +- /* Used to trigger startup */ +- pthread_cond_t startup_condition_cond; +- +- struct { +- uint64_t hits; +- uint64_t misses; +- uint64_t expired; +- uint64_t force_removed; +- } did_cache_stats; +- +- void * priv; /* This is a private structure for fuse/cmdline, etc */ +- pthread_t thread; /* This is the per-volume thread */ +- +- int mapping; +- +-}; +- +-#define SERVER_STATE_CONNECTED 1 +-#define SERVER_STATE_DISCONNECTED 2 +- +-enum server_type{ +- AFPFS_SERVER_TYPE_UNKNOWN, +- AFPFS_SERVER_TYPE_NETATALK, +- AFPFS_SERVER_TYPE_AIRPORT, +- AFPFS_SERVER_TYPE_MACINTOSH, +-}; +- +-#define is_netatalk(x) ( (x)->machine_type == AFPFS_SERVER_TYPE_NETATALK ) +-#define is_airport(x) ( (x)->machine_type == AFPFS_SERVER_TYPE_AIRPORT ) +-#define is_macintosh(x) ( (x)->machine_type == AFPFS_SERVER_TYPE_MACINTOSH ) +- +- +- +-struct afp_versions { +- char *av_name; +- int av_number; +-}; +-extern struct afp_versions afp_versions[]; +- +-struct afp_server { +- +- /* Our buffer sizes */ +- unsigned int tx_quantum; +- unsigned int rx_quantum; +- +- unsigned int tx_delay; +- +- /* Connection information */ +- struct sockaddr_in address; +- int fd; +- +- /* Some stats, for information only */ +- struct { +- uint64_t runt_packets; +- uint64_t incoming_dsi; +- uint64_t rx_bytes; +- uint64_t tx_bytes; +- uint64_t requests_pending; +- } stats; +- +- /* General information */ +- char server_name[AFP_SERVER_NAME_LEN]; +- char server_name_utf8[AFP_SERVER_NAME_UTF8_LEN]; +- char server_name_printable[AFP_SERVER_NAME_UTF8_LEN]; +- +- char machine_type[17]; +- char icon[256]; +- char signature[16]; +- unsigned short flags; +- int connect_state; +- enum server_type server_type; +- +- /* This is the time we connected */ +- time_t connect_time; +- +- /* UAMs */ +- unsigned int supported_uams; +- unsigned int using_uam; +- +- /* Authentication */ +- char username[AFP_MAX_USERNAME_LEN]; +- char password[AFP_MAX_PASSWORD_LEN]; +- +- /* Session */ +- struct afp_token token; +- char need_resume; +- +- /* Versions */ +- unsigned char requested_version; +- unsigned char versions[SERVER_MAX_VERSIONS]; +- struct afp_versions *using_version; +- +- /* Volumes */ +- unsigned char num_volumes; +- struct afp_volume * volumes; +- +- void * dsi; +- unsigned int exit_flag; +- +- /* Our DSI request queue */ +- pthread_mutex_t requestid_mutex; +- pthread_mutex_t request_queue_mutex; +- unsigned short lastrequestid; +- unsigned short expectedrequestid; +- struct dsi_request * command_requests; +- +- +- char loginmesg[200]; +- char servermesg[200]; +- char path_encoding; +- +- /* This is the data for the incoming buffer */ +- char * incoming_buffer; +- int data_read; +- int bufsize; +- +- /* And this is for the outgoing queue */ +- pthread_mutex_t send_mutex; +- +- /* This is for user mapping */ +- struct passwd passwd; +- unsigned int server_uid, server_gid; +- int server_gid_valid; +- +- struct afp_server *next; +- +- /* These are for DSI attention packets */ +- unsigned int attention_quantum; +- unsigned int attention_len; +- char * attention_buffer; +- +-}; +- +-struct afp_extattr_info { +- unsigned int maxsize; +- unsigned int size; +- char data[1024]; +-}; +-struct afp_comment { +- unsigned int maxsize; +- unsigned int size; +- char *data; +-}; +- +-struct afp_icon { +- unsigned int maxsize; +- unsigned int size; +- char *data; +-}; +- +-#define AFP_DEFAULT_ATTENTION_QUANTUM 1024 +- +-void afp_unixpriv_to_stat(struct afp_file_info *fp, +- struct stat *stat); +- +-int init_uams(void) ; +- +-unsigned int find_uam_by_name(const char * name); +-char * uam_bitmap_to_string(unsigned int bitmap); +- +- +-char * get_uam_names_list(void); +- +-unsigned int default_uams_mask(void); +- +-struct afp_volume * find_volume_by_name(struct afp_server * server, +- const char * volname); +- +-struct afp_connection_request { +- unsigned int uam_mask; +- struct afp_url url; +-}; +- +-void afp_default_url(struct afp_url *url); +-int afp_parse_url(struct afp_url * url, const char * toparse, int verbose); +-void afp_print_url(struct afp_url * url); +-int afp_url_validate(char * url_string, struct afp_url * valid_url); +- +-int afp_list_volnames(struct afp_server * server, char * names, int max); +- +-/* User mapping */ +-int afp_detect_mapping(struct afp_volume * volume); +- +-/* These are some functions that help with simple status text generation */ +- +-int afp_status_header(char * text, int * len); +-int afp_status_server(struct afp_server * s,char * text, int * len); +- +- +-struct afp_server * afp_server_full_connect(void * priv, struct afp_connection_request * req); +- +-void * just_end_it_now(void *other); +-void add_fd_and_signal(int fd); +-void loop_disconnect(struct afp_server *s); +-void afp_wait_for_started_loop(void); +- +- +-struct afp_versions * pick_version(unsigned char *versions, +- unsigned char requested) ; +-int pick_uam(unsigned int u1, unsigned int u2); +- +-int afp_server_login(struct afp_server *server, +- char * mesg, unsigned int *l, unsigned int max); +- +- +-int afp_dologin(struct afp_server *server, +- unsigned int uam, char * username, char * passwd); +- +-void afp_free_server(struct afp_server **server); +- +-struct afp_server * afp_server_init(struct sockaddr_in * address); +-int afp_get_address(void * priv, const char * hostname, unsigned int port, +- struct sockaddr_in * address); +- +- +-int afp_main_loop(int command_fd); +-int afp_main_quick_startup(pthread_t * thread); +- +-int afp_server_destroy(struct afp_server *s) ; +-int afp_server_reconnect(struct afp_server * s, char * mesg, +- unsigned int *l, unsigned int max); +-int afp_server_connect(struct afp_server *s, int full); +- +-struct afp_server * afp_server_complete_connection( +- void * priv, +- struct afp_server * server, +- struct sockaddr_in * address, unsigned char * versions, +- unsigned int uams, char * username, char * password, +- unsigned int requested_version, unsigned int uam_mask); +- +-int afp_connect_volume(struct afp_volume * volume, struct afp_server * server, +- char * mesg, unsigned int * l, unsigned int max); +-int something_is_mounted(struct afp_server * server); +- +-int add_cache_entry(struct afp_file_info * file) ; +-struct afp_file_info * get_cache_by_name(char * name); +-struct afp_server * find_server_by_address(struct sockaddr_in * address); +-struct afp_server * find_server_by_signature(char * signature); +-struct afp_server * find_server_by_name(char * name); +-int server_still_valid(struct afp_server * server); +- +- +-struct afp_server * get_server_base(void); +-int afp_server_remove(struct afp_server * server); +- +-int afp_unmount_volume(struct afp_volume * volume); +-int afp_unmount_all_volumes(struct afp_server * server); +- +-#define volume_is_readonly(x) (((x)->attributes&kReadOnly) || \ +- ((x)->extra_flags & VOLUME_EXTRA_FLAGS_READONLY)) +- +-int afp_opendt(struct afp_volume *volume, unsigned short * refnum); +- +-int afp_closedt(struct afp_server * server, unsigned short * refnum); +- +-int afp_getcomment(struct afp_volume *volume, unsigned int did, +- const char * pathname, struct afp_comment * comment); +- +-int afp_addcomment(struct afp_volume *volume, unsigned int did, +- const char * pathname, char * comment,uint64_t *size); +- +-int afp_geticon(struct afp_volume * volume, unsigned int filecreator, +- unsigned int filetype, unsigned char icontype, +- unsigned short length, struct afp_icon * icon); +- +-/* Things you want to do to a server */ +- +-int afp_getsrvrmsg(struct afp_server *server, unsigned short messagetype,unsigned char utf8, unsigned char block, char * mesg); +- +-int afp_login(struct afp_server *server, char * uaname, +- char * userauthinfo, unsigned int userauthinfo_len, +- struct afp_rx_buffer *rx); +- +-int afp_changepassword(struct afp_server *server, char * uaname, +- char * userauthinfo, unsigned int userauthinfo_len, +- struct afp_rx_buffer *rx); +- +-int afp_logincont(struct afp_server *server, unsigned short id, +- char * userauthinfo, unsigned int userauthinfo_len, +- struct afp_rx_buffer *rx); +- +-int afp_getsessiontoken(struct afp_server * server, int type, +- unsigned int timestamp, struct afp_token *outgoing_token, +- struct afp_token * incoming_token); +- +-int afp_getsrvrparms(struct afp_server *server); +- +-int afp_logout(struct afp_server *server,unsigned char wait); +- +-int afp_mapname(struct afp_server * server, unsigned char subfunction, +- char * name, unsigned int * id); +- +-int afp_mapid(struct afp_server * server, unsigned char subfunction, +- unsigned int id, char *name); +- +-int afp_getuserinfo(struct afp_server * server, int thisuser, +- unsigned int userid, unsigned short bitmap, +- unsigned int *newuid, unsigned int *newgid); +- +-int afp_zzzzz(struct afp_server *server); +- +-int afp_volopen(struct afp_volume * volume, +- unsigned short bitmap, char * password); +- +-int afp_flush(struct afp_volume * volume); +- +-int afp_getfiledirparms(struct afp_volume *volume, unsigned int did, +- unsigned int filebitmap, unsigned int dirbitmap, const char * pathname, +- struct afp_file_info *fp); +- +-int afp_enumerate(struct afp_volume * volume, +- unsigned int dirid, +- unsigned int filebitmap, unsigned int dirbitmap, +- unsigned short reqcount, +- unsigned short startindex, +- char * path, +- struct afp_file_info ** file_p); +- +-int afp_enumerateext2(struct afp_volume * volume, +- unsigned int dirid, +- unsigned int filebitmap, unsigned int dirbitmap, +- unsigned short reqcount, +- unsigned long startindex, +- char * path, +- struct afp_file_info ** file_p); +- +-int afp_openfork(struct afp_volume * volume, +- unsigned char forktype, +- unsigned int dirid, +- unsigned short accessmode, +- char * filename, +- struct afp_file_info *fp); +- +-int afp_read(struct afp_volume * volume, unsigned short forkid, +- uint32_t offset, +- uint32_t count, struct afp_rx_buffer * rx); +- +-int afp_readext(struct afp_volume * volume, unsigned short forkid, +- uint64_t offset, +- uint64_t count, struct afp_rx_buffer * rx); +- +-int afp_getvolparms(struct afp_volume * volume, unsigned short bitmap); +- +- +-int afp_createdir(struct afp_volume * volume, unsigned int dirid, const char * pathname, unsigned int *did_p); +- +-int afp_delete(struct afp_volume * volume, +- unsigned int dirid, char * pathname); +- +- +-int afp_createfile(struct afp_volume * volume, unsigned char flag, +- unsigned int did, char * pathname); +- +-int afp_write(struct afp_volume * volume, unsigned short forkid, +- uint32_t offset, uint32_t reqcount, +- char * data, uint32_t * written); +- +-int afp_writeext(struct afp_volume * volume, unsigned short forkid, +- uint64_t offset, uint64_t reqcount, +- char * data, uint64_t * written); +- +-int afp_flushfork(struct afp_volume * volume, unsigned short forkid); +- +-int afp_closefork(struct afp_volume * volume, unsigned short forkid); +-int afp_setfileparms(struct afp_volume * volume, +- unsigned int dirid, const char * pathname, unsigned short bitmap, +- struct afp_file_info *fp); +-int afp_setfiledirparms(struct afp_volume * volume, +- unsigned int dirid, const char * pathname, unsigned short bitmap, +- struct afp_file_info *fp); +- +-int afp_setdirparms(struct afp_volume * volume, +- unsigned int dirid, const char * pathname, unsigned short bitmap, +- struct afp_file_info *fp); +- +-int afp_volclose(struct afp_volume * volume); +- +- +-int afp_setforkparms(struct afp_volume *volume, +- unsigned short forkid, unsigned short bitmap, unsigned long len); +- +-int afp_byterangelock(struct afp_volume * volume, +- unsigned char flag, +- unsigned short forkid, +- uint32_t offset, +- uint32_t len, uint32_t *generated_offset); +- +-int afp_byterangelockext(struct afp_volume * volume, +- unsigned char flag, +- unsigned short forkid, +- uint64_t offset, +- uint64_t len, uint64_t *generated_offset); +- +-int afp_moveandrename(struct afp_volume *volume, +- unsigned int src_did, +- unsigned int dst_did, +- char * src_path, char * dst_path, char *new_name); +- +-int afp_rename(struct afp_volume * volume, +- unsigned int dirid, +- char * path_from, char * path_to); +- +-int afp_listextattr(struct afp_volume * volume, +- unsigned int dirid, unsigned short bitmap, +- char * pathname, struct afp_extattr_info * info); +- +-/* This is a currently undocumented command */ +-int afp_newcommand76(struct afp_volume * volume, unsigned int dlen, char * data); +- +-/* For debugging */ +-char * afp_get_command_name(char code); +- +- +-#endif +diff -Naur afpfs-ng-0.8.1/include/afp_protocol.h afpfs-ng-0.8.1.patch/include/afp_protocol.h +--- afpfs-ng-0.8.1/include/afp_protocol.h 2008-02-18 04:33:43.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/afp_protocol.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,361 +0,0 @@ +- +-#ifndef _AFP_PROTOCOL_H_ +-#define _AFP_PROTOCOL_H_ +- +-#include +-#include +-#include +-#include +- +-/* This file defines constants for the Apple File Protocol. +- All page references are from "Apple Filing Protocol Programming" version 3.2. +- except where noted. +-*/ +- +-#define AFP_SERVER_NAME_LEN 33 +-#define AFP_SERVER_NAME_UTF8_LEN 255 +-#define AFP_VOLUME_NAME_LEN 33 +-#define AFP_VOLUME_NAME_UTF8_LEN 33 +-#define AFP_SIGNATURE_LEN 16 +-#define AFP_MACHINETYPE_LEN 33 +-#define AFP_LOGINMESG_LEN 200 +-#define AFP_VOLPASS_LEN 8 +-#define AFP_HOSTNAME_LEN 255 +-/* This is actually just a guess, and only used for appletalk */ +-#define AFP_ZONE_LEN 255 +- +-#define AFP_SERVER_ICON_LEN 256 +- +- +-#define AFP_MAX_USERNAME_LEN 127 +-#define AFP_MAX_PASSWORD_LEN 127 +- +- +-/* This is the maximum length of any UAM string */ +-#define AFP_UAM_LENGTH 24 +- +-/* This is the maximum length of any path description */ +-#define AFP_MAX_PATH 768 +- +-#define AFP_VOL_FLAT 1 +-#define AFP_VOL_FIXED 2 +-#define AFP_VOL_VARIABLE 3 +- +-/* The root directory ID, p.26 */ +- +-#define AFP_ROOT_DID 2 +- +-/* Path type constants, p.249 */ +- +-enum { +-kFPShortName = 1, +-kFPLongName = 2, +-kFPUTF8Name = 3 +-}; +- +-/* fork types */ +- +-#define AFP_FORKTYPE_DATA 0x0 +-#define AFP_FORKTYPE_RESOURCE 0x80 +- +-/* openfork access modes, from p.196 */ +- +-#define AFP_OPENFORK_ALLOWREAD 1 +-#define AFP_OPENFORK_ALLOWWRITE 2 +-#define AFP_OPENFORK_DENYREAD 0x10 +-#define AFP_OPENFORK_DENYWRITE 0x20 +- +-/* Message type for getsrvmesg, p. 169*/ +- +-typedef enum { +- AFPMESG_LOGIN = 0, +- AFPMESG_SERVER = 1 +-} afpmessage_t; +- +-/* Message bitmap for getsrvrmsg */ +- +-#define AFP_GETSRVRMSG_UTF8 0x2 +-#define AFP_GETSRVRMSG_GETMSG 0x1 +- +- +-/* Maximum Version length, p.17 */ +-#define AFP_MAX_VERSION_LENGTH 16 +- +-/* Maximum length of a token, this is undocumented */ +-#define AFP_TOKEN_MAX_LEN 256 +- +-/* The maximum size of a file for AFP 2 */ +-#define AFP_MAX_AFP2_FILESIZE (4294967296) +- +-/* Unix privs, p.240 */ +- +-struct afp_unixprivs { +- uint32_t uid __attribute__((__packed__)); +- uint32_t gid __attribute__((__packed__)); +- uint32_t permissions __attribute__((__packed__)); +- uint32_t ua_permissions __attribute__((__packed__)); +- +-}; +- +- +-/* AFP Volume attributes bitmap, p.241 */ +- +-enum { +- kReadOnly = 0x01, +- kHasVolumePassword = 0x02, +- kSupportsFileIDs = 0x04, +- kSupportsCatSearch = 0x08, +- kSupportsBlankAccessPrivs = 0x10, +- kSupportsUnixPrivs = 0x20, +- kSupportsUTF8Names = 0x40, +- kNoNetworkUserIDs = 0x80, +- kDefaultPrivsFromParent = 0x100, +- kNoExchangeFiles = 0x200, +- kSupportsExtAttrs = 0x400, +- kSupportsACLs=0x800 +-}; +- +-/* AFP file creation constantes, p.250 */ +-enum { +-kFPSoftCreate = 0, +-kFPHardCreate = 0x80 +-}; +- +-/* AFP Directory attributes, taken from the protocol guide p.236 */ +- +-enum { +- kFPAttributeBit = 0x1, +- kFPParentDirIDBit = 0x2, +- kFPCreateDateBit = 0x4, +- kFPModDateBit = 0x8, +- kFPBackupDateBit = 0x10, +- kFPFinderInfoBit = 0x20, +- kFPLongNameBit = 0x40, +- kFPShortNameBit = 0x80, +- kFPNodeIDBit = 0x100, +- kFPOffspringCountBit = 0x0200, +- kFPOwnerIDBit = 0x0400, +- kFPGroupIDBit = 0x0800, +- kFPAccessRightsBit = 0x1000, +- kFPProDOSInfoBit = 0x2000, // AFP version 2.2 and earlier +- kFPUTF8NameBit = 0x2000, // AFP version 3.0 and later +- kFPUnixPrivsBit = 0x8000 // AFP version 3.0 and later +-}; +- +-/* AFP File bitmap, p.238. These are the ones not in the AFP Directory +- attributes map. */ +- +-enum { +- kFPDataForkLenBit = 0x0200, +- kFPRsrcForkLenBit = 0x0400, +- kFPExtDataForkLenBit = 0x0800, // AFP version 3.0 and later +- kFPLaunchLimitBit = 0x1000, +- kFPExtRsrcForkLenBit = 0x4000, // AFP version 3.0 and later +-}; +- +-/* AFP Extended Attributes Bitmap, p.238 */ +- +-enum { +- kXAttrNoFollow = 0x1, +- kXAttrCreate = 0x2, +- kXAttrREplace=0x4 +-}; +- +- +-/* AFP function codes */ +-enum AFPFunction +-{ +- afpByteRangeLock = 1, afpCloseVol, afpCloseDir, afpCloseFork, +- afpCopyFile, afpCreateDir, afpCreateFile, +- afpDelete, afpEnumerate, afpFlush, afpFlushFork, +- afpGetForkParms = 14, afpGetSrvrInfo, afpGetSrvrParms, +- afpGetVolParms, afpLogin, afpLoginCont, afpLogout, afpMapID, +- afpMapName, afpMoveAndRename, afpOpenVol, afpOpenDir, afpOpenFork, +- afpRead, afpRename, afpSetDirParms, afpSetFileParms, +- afpSetForkParms, afpSetVolParms, afpWrite, afpGetFileDirParms, +- afpSetFileDirParms, afpChangePassword, +- afpGetUserInfo=37,afpGetSrvrMsg = 38, +- afpOpenDT=48, +- afpCloseDT=49, +- afpGetIcon=51, afpGetIconInfo=52, +- afpAddComment=56, afpRemoveComment=57, afpGetComment=58, +- afpByteRangeLockExt=59, afpReadExt, afpWriteExt, +- afpGetAuthMethods=62, +- afp_LoginExt=63, +- afpGetSessionToken=64, +- afpDisconnectOldSession=65, +- afpEnumerateExt=66, +- afpCatSearchExt = 67, +- afpEnumerateExt2 = 68, afpGetExtAttr, afpSetExtAttr, +- afpRemoveExtAttr , afpListExtAttrs, +- afpZzzzz = 122, +- afpAddIcon=192, +-}; +- +-/* AFP Volume bitmap. Take from 242 of the protocol guide. */ +-enum { +- kFPBadVolPre222Bitmap = 0xFe00, +- kFPBadVolBitmap = 0xF000, +- kFPVolAttributeBit = 0x1, +- kFPVolSignatureBit = 0x2, +- kFPVolCreateDateBit = 0x4, +- kFPVolModDateBit = 0x8, +- kFPVolBackupDateBit = 0x10, +- kFPVolIDBit = 0x20, +- kFPVolBytesFreeBit = 0x40, +- kFPVolBytesTotalBit = 0x80, +- kFPVolNameBit = 0x100, +- kFPVolExtBytesFreeBit = 0x200, +- kFPVolExtBytesTotalBit = 0x400, +- kFPVolBlockSizeBit = 0x800 +-}; +- +-/* AFP Attention Codes -- 4 bits */ +-#define AFPATTN_SHUTDOWN (1 << 15) /* shutdown/disconnect */ +-#define AFPATTN_CRASH (1 << 14) /* server crashed */ +-#define AFPATTN_MESG (1 << 13) /* server has message */ +-#define AFPATTN_NORECONNECT (1 << 12) /* don't reconnect */ +-/* server notification */ +-#define AFPATTN_NOTIFY (AFPATTN_MESG | AFPATTN_NORECONNECT) +- +-/* extended bitmap -- 12 bits. volchanged is only useful w/ a server +- * notification, and time is only useful for shutdown. */ +-#define AFPATTN_VOLCHANGED (1 << 0) /* volume has changed */ +-#define AFPATTN_TIME(x) ((x) & 0xfff) /* time in minutes */ +- +-#define kFPNoErr 0 +- +-/* AFP result codes, p252 */ +-#define kASPSessClosed -1072 +-#define kFPAccessDenied -5000 +-#define kFPAuthContinue -5001 +-#define kFPBadUAM -5002 +-#define kFPBadVersNum -5003 +-#define kFPBitmapErr -5004 +-#define kFPCantMove -5005 +-#define kFPDenyConflict -5006 +-#define kFPDirNotEmpty -5007 +-#define kFPDiskFull -5008 +-#define kFPEOFErr -5009 +-#define kFPFileBusy -5010 +-#define kFPFlatVol -5011 +-#define kFPItemNotFound -5012 +-#define kFPLockErr -5013 +-#define kFPMiscErr -5014 +-#define kFPNoMoreLocks -5015 +-#define kFPNoServer -5016 +-#define kFPObjectExists -5017 +-#define kFPObjectNotFound -5018 +-#define kFPParamErr -5019 +-#define kFPRangeNotLocked -5020 +-#define kFPRangeOverlap -5021 +-#define kFPSessClosed -5022 +-#define kFPUserNotAuth -5023 +-#define kFPCallNotSupported -5024 +-#define kFPObjectTypeErr -5025 +-#define kFPTooManyFilesOpen -5026 +-#define kFPServerGoingDown -5027 +-#define kFPCantRename -5028 +-#define kFPDirNotFound -5029 +-#define kFPIconTypeError -5030 +-#define kFPVolLocked -5031 +-#define kFPObjectLocked -5032 +-#define kFPContainsSharedErr -5033 +-#define kFPIDNotFound -5034 +-#define kFPIDExists -5035 +-#define kFPDiffVolErr -5036 +-#define kFPCatalogChanged -5037 +-#define kFPSameObjectErr -5038 +-#define kFPBadIDErr -5039 +-#define kFPPwdSameErr -5040 +-#define kFPPwdTooShortErr -5041 +-#define kFPPwdExpiredErr -5042 +-#define kFPInsideSharedErr -5043 +-#define kFPInsideTrashErr -5044 +-#define kFPPwdNeedsChangeErr -5045 +-#define kFPPwdPolicyErr -5046 +-#define kFPDiskQuotaExceeded –5047 +- +- +- +-/* These flags determine to lock or unlock in ByteRangeLock(Ext) */ +- +-enum { +-ByteRangeLock_Lock = 0, +-ByteRangeLock_Unlock = 1 +-}; +- +-/* These flags are used in volopen and getsrvrparm replies, p.171 */ +- +-#define HasConfigInfo 0x1 +-#define HasPassword 0x80 +- +-/* These are the subfunction for kFPMapID, as per p.248 */ +- +-enum { +-kUserIDToName = 1, +-kGroupIDToName = 2, +-kUserIDToUTF8Name = 3, +-kGroupIDToUTF8Name = 4, +-kUserUUIDToUTF8Name = 5, +-kGroupUUIDToUTF8Name = 6 +-}; +- +- +-/* These are the subfunction flags described in the FPMapName command, p.286. +- Note that this is different than what's described on p. 186. */ +- +-enum { +-kNameToUserID = 1, +-kNameToGroupID = 2, +-kUTF8NameToUserID = 3, +-kUTF8NameToGroupID = 4, +-kUTF8NameToUserUUID = 5, +-kUTF8NameToGroupUUID = 6 +-}; +- +-/* These are bits for FPGetUserInfo, p.173. */ +-#define kFPGetUserInfo_USER_ID 1 +-#define kFPGetUserInfo_PRI_GROUPID 2 +- +-/* Flags for the replies of GetSrvrInfo and DSI GetStatus, p.240 */ +- +-enum { +- kSupportsCopyfile = 0x01, +- kSupportsChgPwd = 0x02, +- kDontAllowSavePwd = 0x04, +- kSupportsSrvrMsg = 0x08, +- kSrvrSig = 0x10, +- kSupportsTCP = 0x20, +- kSupportsSrvrNotify = 0x40, +- kSupportsReconnect = 0x80, +- kSupportsDirServices = 0x100, +- kSupportsUTF8SrvrName = 0x200, +- kSupportsUUIDs = 0x400, +- kSupportsSuperClient = 0x8000 +-}; +- +- +-/* p.247 */ +- +-enum { +- kLoginWithoutID = 0, +- kLoginWithID = 1, +- kReconnWithID = 2, +- kLoginWithTimeAndID = 3, +- kReconnWithTimeAndID = 4, +- kRecon1Login = 5, +- kRecon1ReconnectLogin = 6, +- kRecon1Refresh = 7, kGetKerberosSessionKey = 8 +-}; +- +- +-#define AFP_CHMOD_ALLOWED_BITS_22 \ +- (S_IRUSR |S_IWUSR | S_IRGRP | S_IWGRP |S_IROTH | S_IWOTH | S_IFREG ) +- +- +-#endif +- +- +- +- +diff -Naur afpfs-ng-0.8.1/include/codepage.h afpfs-ng-0.8.1.patch/include/codepage.h +--- afpfs-ng-0.8.1/include/codepage.h 2007-09-23 16:21:30.000000000 +0200 ++++ afpfs-ng-0.8.1.patch/include/codepage.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,11 +0,0 @@ +-#ifndef __CODE_PAGE_H_ +-#define __CODE_PAGE_H_ +-int convert_utf8dec_to_utf8pre(const char *src, int src_len, +- char * dest, int dest_len); +-int convert_utf8pre_to_utf8dec(const char * src, int src_len, +- char * dest, int dest_len); +-int convert_path_to_unix(char encoding, char * dest, +- char * src, int dest_len); +-int convert_path_to_afp(char encoding, char * dest, +- char * src, int dest_len); +-#endif +diff -Naur afpfs-ng-0.8.1/include/dsi.h afpfs-ng-0.8.1.patch/include/dsi.h +--- afpfs-ng-0.8.1/include/dsi.h 2008-02-18 04:33:24.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/dsi.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,33 +0,0 @@ +- +-#ifndef __DSI_H_ +-#define __DSI_H_ +- +-#include "afp.h" +- +-struct dsi_request +-{ +- unsigned short requestid; +- unsigned char subcommand; +- void * other; +- unsigned char wait; +- pthread_cond_t condition_cond; +- struct dsi_request * next; +- int return_code; +-}; +- +-int dsi_receive(struct afp_server * server, void * data, int size); +-int dsi_getstatus(struct afp_server * server); +- +-int dsi_opensession(struct afp_server *server); +- +-int dsi_send(struct afp_server *server, char * msg, int size,int wait,unsigned char subcommand, void ** other); +-struct dsi_session * dsi_create(struct afp_server *server); +-int dsi_restart(struct afp_server *server); +-int dsi_recv(struct afp_server * server); +- +-#define DSI_BLOCK_TIMEOUT -1 +-#define DSI_DONT_WAIT 0 +-#define DSI_DEFAULT_TIMEOUT 5 +- +- +-#endif +diff -Naur afpfs-ng-0.8.1/include/libafpclient.h afpfs-ng-0.8.1.patch/include/libafpclient.h +--- afpfs-ng-0.8.1/include/libafpclient.h 2008-01-30 05:37:59.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/libafpclient.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,50 +0,0 @@ +- +-#ifndef __CLIENT_H_ +-#define __CLIENT_H_ +- +-#include +-#include +- +-#define MAX_CLIENT_RESPONSE 2048 +- +- +-enum loglevels { +- AFPFSD, +-}; +- +-struct afp_server; +-struct afp_volume; +- +-struct libafpclient { +- int (*unmount_volume) (struct afp_volume * volume); +- void (*log_for_client)(void * priv, +- enum loglevels loglevel, int logtype, const char *message); +- void (*forced_ending_hook)(void); +- int (*scan_extra_fds)(int command_fd,fd_set *set, int * max_fd); +- void (*loop_started)(void); +-} ; +- +-extern struct libafpclient * libafpclient; +- +-void libafpclient_register(struct libafpclient * tmpclient); +- +- +-void signal_main_thread(void); +- +-/* These are logging functions */ +- +-#define MAXLOGSIZE 2048 +- +-#define LOG_METHOD_SYSLOG 1 +-#define LOG_METHOD_STDOUT 2 +- +-void set_log_method(int m); +- +- +-void log_for_client(void * priv, +- enum loglevels loglevel, int logtype, char * message,...); +- +-void stdout_log_for_client(void * priv, +- enum loglevels loglevel, int logtype, const char *message); +- +-#endif +diff -Naur afpfs-ng-0.8.1/include/Makefile.am afpfs-ng-0.8.1.patch/include/Makefile.am +--- afpfs-ng-0.8.1/include/Makefile.am 1970-01-01 01:00:00.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/Makefile.am 2011-09-10 12:13:50.126124692 +0200 +@@ -0,0 +1,3 @@ ++## Process this file with automake to produce Makefile.in ++ ++SUBDIRS = afpfs-ng +diff -Naur afpfs-ng-0.8.1/include/map_def.h afpfs-ng-0.8.1.patch/include/map_def.h +--- afpfs-ng-0.8.1/include/map_def.h 2008-01-17 05:55:46.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/map_def.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,15 +0,0 @@ +-#ifndef __MAP_H_ +-#define __MAP_H_ +- +-#include "afp.h" +- +-#define AFP_MAPPING_UNKNOWN 0 +-#define AFP_MAPPING_COMMON 1 +-#define AFP_MAPPING_LOGINIDS 2 +-#define AFP_MAPPING_NAME 3 +- +-unsigned int map_string_to_num(char * name); +-char * get_mapping_name(struct afp_volume * volume); +- +- +-#endif +diff -Naur afpfs-ng-0.8.1/include/midlevel.h afpfs-ng-0.8.1.patch/include/midlevel.h +--- afpfs-ng-0.8.1/include/midlevel.h 2007-12-24 20:39:25.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/midlevel.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,64 +0,0 @@ +-#ifndef __MIDLEVEL_H_ +-#define __MIDLEVEL_H_ +- +-#include +-#include "afp.h" +- +-int ml_open(struct afp_volume * volume, const char *path, int flags, +- struct afp_file_info **newfp); +- +-int ml_creat(struct afp_volume * volume, const char *path,mode_t mode); +- +-int ml_readdir(struct afp_volume * volume, +- const char *path, +- struct afp_file_info **base); +- +-int ml_read(struct afp_volume * volume, const char *path, +- char *buf, size_t size, off_t offset, +- struct afp_file_info *fp, int * eof); +- +-int ml_chmod(struct afp_volume * vol, const char * path, mode_t mode); +- +-int ml_unlink(struct afp_volume * vol, const char *path); +- +-int ml_mkdir(struct afp_volume * vol, const char * path, mode_t mode); +- +-int ml_close(struct afp_volume * volume, const char * path, +- struct afp_file_info * fp); +- +-int ml_getattr(struct afp_volume * volume, const char *path, +- struct stat *stbuf); +- +-int ml_write(struct afp_volume * volume, const char * path, +- const char *data, size_t size, off_t offset, +- struct afp_file_info * fp, uid_t uid, +- gid_t gid); +- +-int ml_readlink(struct afp_volume * vol, const char * path, +- char *buf, size_t size); +- +-int ml_rmdir(struct afp_volume * vol, const char *path); +- +-int ml_chown(struct afp_volume * vol, const char * path, +- uid_t uid, gid_t gid); +- +-int ml_truncate(struct afp_volume * vol, const char * path, off_t offset); +- +-int ml_utime(struct afp_volume * vol, const char * path, +- struct utimbuf * timebuf); +- +-int ml_symlink(struct afp_volume *vol, const char * path1, const char * path2); +- +-int ml_rename(struct afp_volume * vol, +- const char * path_from, const char * path_to); +- +-int ml_statfs(struct afp_volume * vol, const char *path, struct statvfs *stat); +- +-void afp_ml_filebase_free(struct afp_file_info **filebase); +- +-int ml_passwd(struct afp_server *server, +- char * username, char * oldpasswd, char * newpasswd); +- +- +- +-#endif +diff -Naur afpfs-ng-0.8.1/include/uams_def.h afpfs-ng-0.8.1.patch/include/uams_def.h +--- afpfs-ng-0.8.1/include/uams_def.h 2007-09-07 15:10:51.000000000 +0200 ++++ afpfs-ng-0.8.1.patch/include/uams_def.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,16 +0,0 @@ +-#ifndef __UAM_DEFS_H_ +-#define __UAM_DEFS_H_ +- +-#define UAM_NOUSERAUTHENT 0x1 +-#define UAM_CLEARTXTPASSWRD 0x2 +-#define UAM_RANDNUMEXCHANGE 0x4 +-#define UAM_2WAYRANDNUM 0x8 +-#define UAM_DHCAST128 0x10 +-#define UAM_CLIENTKRB 0x20 +-#define UAM_DHX2 0x40 +-#define UAM_RECON1 0x80 +- +-int uam_string_to_bitmap(char * name); +-char * uam_bitmap_to_string(unsigned int bitmap); +- +-#endif +diff -Naur afpfs-ng-0.8.1/include/utils.h afpfs-ng-0.8.1.patch/include/utils.h +--- afpfs-ng-0.8.1/include/utils.h 2008-02-18 04:33:58.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/include/utils.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,43 +0,0 @@ +-#ifndef __UTILS_H_ +-#define __UTILS_H_ +-#include +- +-#include "afp.h" +- +-#if BYTE_ORDER == BIG_ENDIAN +-#define hton64(x) (x) +-#define ntoh64(x) (x) +-#else /* BYTE_ORDER == BIG_ENDIAN */ +-#define hton64(x) ((u_int64_t) (htonl(((x) >> 32) & 0xffffffffLL)) | \ +- (u_int64_t) ((htonl(x) & 0xffffffffLL) << 32)) +-#define ntoh64(x) (hton64(x)) +-#endif /* BYTE_ORDER == BIG_ENDIAN */ +- +-#define min(a,b) (((a)<(b)) ? (a) : (b)) +-#define max(a,b) (((a)>(b)) ? (a) : (b)) +- +- +- +-unsigned char unixpath_to_afppath( +- struct afp_server * server, +- char * buf); +- +-unsigned char sizeof_path_header(struct afp_server * server); +- +- +- +-unsigned char copy_from_pascal(char *dest, char *pascal,unsigned int max_len) ; +-unsigned short copy_from_pascal_two(char *dest, char *pascal,unsigned int max_len); +- +-unsigned char copy_to_pascal(char *dest, const char *src); +-unsigned short copy_to_pascal_two(char *dest, const char *src); +- +-void copy_path(struct afp_server * server, char * dest, const char * pathname, unsigned char len); +- +- +-char * create_path(struct afp_server * server, char * pathname, unsigned short * len); +- +- +-int invalid_filename(struct afp_server * server, const char * filename); +- +-#endif +diff -Naur afpfs-ng-0.8.1/lib/afp.c afpfs-ng-0.8.1.patch/lib/afp.c +--- afpfs-ng-0.8.1/lib/afp.c 2008-03-08 03:44:16.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/afp.c 2011-09-10 12:13:50.131124759 +0200 +@@ -9,7 +9,7 @@ + + + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + #include + + #include +@@ -21,17 +21,17 @@ + #include + #include + +-#include "afp_protocol.h" +-#include "libafpclient.h" ++#include "afpfs-ng/afp_protocol.h" ++#include "afpfs-ng/libafpclient.h" + #include "server.h" +-#include "dsi.h" ++#include "afpfs-ng/dsi.h" + #include "dsi_protocol.h" +-#include "utils.h" ++#include "afpfs-ng/utils.h" + #include "afp_replies.h" + #include "afp_internal.h" + #include "did.h" + #include "forklist.h" +-#include "codepage.h" ++#include "afpfs-ng/codepage.h" + + struct afp_versions afp_versions[] = { + { "AFPVersion 1.1", 11 }, +diff -Naur afpfs-ng-0.8.1/lib/afp_internal.h afpfs-ng-0.8.1.patch/lib/afp_internal.h +--- afpfs-ng-0.8.1/lib/afp_internal.h 2007-11-09 05:27:20.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/afp_internal.h 2011-09-10 12:13:50.132124772 +0200 +@@ -1,7 +1,7 @@ + #ifndef _AFP_INTERNAL_H_ + #define _AFP_INTERNAL_H_ + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + + extern struct afp_versions afp_versions[]; + +diff -Naur afpfs-ng-0.8.1/lib/afp_url.c afpfs-ng-0.8.1.patch/lib/afp_url.c +--- afpfs-ng-0.8.1/lib/afp_url.c 2008-03-04 21:16:49.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/afp_url.c 2011-09-10 12:13:50.132124772 +0200 +@@ -3,7 +3,7 @@ + #include + #include + #include +-#include "afp.h" ++#include "afpfs-ng/afp.h" + + void afp_default_url(struct afp_url *url) + { +diff -Naur afpfs-ng-0.8.1/lib/client.c afpfs-ng-0.8.1.patch/lib/client.c +--- afpfs-ng-0.8.1/lib/client.c 2008-02-18 04:36:30.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/client.c 2011-09-10 12:13:50.132124772 +0200 +@@ -1,5 +1,5 @@ +-#include +-#include ++#include ++#include + + + struct libafpclient * libafpclient = NULL; +diff -Naur afpfs-ng-0.8.1/lib/codepage.c afpfs-ng-0.8.1.patch/lib/codepage.c +--- afpfs-ng-0.8.1/lib/codepage.c 2008-02-18 04:36:54.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/codepage.c 2011-09-10 12:13:50.133124786 +0200 +@@ -14,8 +14,8 @@ + + #include + #include +-#include "afp_protocol.h" +-#include "utils.h" ++#include "afpfs-ng/afp_protocol.h" ++#include "afpfs-ng/utils.h" + #include "unicode.h" + + int convert_utf8dec_to_utf8pre(const char *src, int src_len, +diff -Naur afpfs-ng-0.8.1/lib/connect.c afpfs-ng-0.8.1.patch/lib/connect.c +--- afpfs-ng-0.8.1/lib/connect.c 2008-02-18 04:38:59.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/connect.c 2011-09-10 12:13:50.133124786 +0200 +@@ -10,13 +10,13 @@ + #include + #include + +-#include "afp.h" +-#include "dsi.h" +-#include "utils.h" +-#include "uams_def.h" +-#include "codepage.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/uams_def.h" ++#include "afpfs-ng/codepage.h" + #include "users.h" +-#include "libafpclient.h" ++#include "afpfs-ng/libafpclient.h" + #include "server.h" + + +diff -Naur afpfs-ng-0.8.1/lib/did.c afpfs-ng-0.8.1.patch/lib/did.c +--- afpfs-ng-0.8.1/lib/did.c 2008-02-18 04:39:17.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/did.c 2011-09-10 12:13:50.133124786 +0200 +@@ -9,8 +9,8 @@ + #include + #include + +-#include "afp.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/afp_protocol.h" + + #undef DID_CACHE_DISABLE + +diff -Naur afpfs-ng-0.8.1/lib/dsi.c afpfs-ng-0.8.1.patch/lib/dsi.c +--- afpfs-ng-0.8.1/lib/dsi.c 2008-02-18 04:53:03.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/dsi.c 2011-09-10 12:13:50.134124800 +0200 +@@ -19,12 +19,12 @@ + #include + #include + +-#include "utils.h" +-#include "dsi.h" +-#include "afp.h" +-#include "uams_def.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/uams_def.h" + #include "dsi_protocol.h" +-#include "libafpclient.h" ++#include "afpfs-ng/libafpclient.h" + #include "afp_internal.h" + #include "afp_replies.h" + +diff -Naur afpfs-ng-0.8.1/lib/forklist.c afpfs-ng-0.8.1.patch/lib/forklist.c +--- afpfs-ng-0.8.1/lib/forklist.c 2008-01-17 05:49:16.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/forklist.c 2011-09-10 12:13:50.135124814 +0200 +@@ -10,7 +10,7 @@ + */ + + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + + #include + #include +diff -Naur afpfs-ng-0.8.1/lib/log.c afpfs-ng-0.8.1.patch/lib/log.c +--- afpfs-ng-0.8.1/lib/log.c 2008-01-30 05:37:58.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/log.c 2011-09-10 12:13:50.135124814 +0200 +@@ -3,7 +3,7 @@ + #include + #include + #include +-#include "libafpclient.h" ++#include "afpfs-ng/libafpclient.h" + + void log_for_client(void * priv, + enum loglevels loglevel, int logtype, char *format, ...) { +diff -Naur afpfs-ng-0.8.1/lib/loop.c afpfs-ng-0.8.1.patch/lib/loop.c +--- afpfs-ng-0.8.1/lib/loop.c 2008-02-18 04:40:11.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/loop.c 2011-09-10 12:13:50.135124814 +0200 +@@ -16,9 +16,9 @@ + #include + #include + +-#include "afp.h" +-#include "dsi.h" +-#include "utils.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/utils.h" + + #define SIGNAL_TO_USE SIGUSR2 + +@@ -85,7 +85,7 @@ void signal_main_thread(void) + } + + static int ending=0; +-void * just_end_it_now(void * ignore) ++void just_end_it_now(void * ignore) + { + if (ending) return; + ending=1; + +diff -Naur afpfs-ng-0.8.1/lib/lowlevel.c afpfs-ng-0.8.1.patch/lib/lowlevel.c +--- afpfs-ng-0.8.1/lib/lowlevel.c 2008-02-20 02:33:17.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/lowlevel.c 2011-09-10 12:13:50.136124828 +0200 +@@ -19,10 +19,10 @@ + #else + #include + #endif +-#include "afp.h" +-#include "afp_protocol.h" +-#include "codepage.h" +-#include "utils.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/afp_protocol.h" ++#include "afpfs-ng/codepage.h" ++#include "afpfs-ng/utils.h" + #include "did.h" + #include "users.h" + +diff -Naur afpfs-ng-0.8.1/lib/map_def.c afpfs-ng-0.8.1.patch/lib/map_def.c +--- afpfs-ng-0.8.1/lib/map_def.c 2007-09-07 15:10:59.000000000 +0200 ++++ afpfs-ng-0.8.1.patch/lib/map_def.c 2011-09-10 12:13:50.136124828 +0200 +@@ -1,6 +1,6 @@ + #include +-#include "afp.h" +-#include "map_def.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/map_def.h" + + static char *afp_map_strings[] = { + "Unknown", +diff -Naur afpfs-ng-0.8.1/lib/meta.c afpfs-ng-0.8.1.patch/lib/meta.c +--- afpfs-ng-0.8.1/lib/meta.c 2008-01-04 04:52:44.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/meta.c 2011-09-10 12:13:50.137124841 +0200 +@@ -17,10 +17,10 @@ + #include + #include + +-#include "afp.h" +-#include "dsi.h" +-#include "afp_protocol.h" +-#include "utils.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp_protocol.h" ++#include "afpfs-ng/utils.h" + + + int afp_meta_getattr(const char *path, struct stat *stbuf) +diff -Naur afpfs-ng-0.8.1/lib/midlevel.c afpfs-ng-0.8.1.patch/lib/midlevel.c +--- afpfs-ng-0.8.1/lib/midlevel.c 2008-03-08 17:08:18.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/midlevel.c 2011-09-10 12:13:50.160125150 +0200 +@@ -10,7 +10,7 @@ + */ + + +-#include "afp.h" ++#include "afpfs-ng/afp.h" + + #include + #include +@@ -28,9 +28,9 @@ + #include "users.h" + #include "did.h" + #include "resource.h" +-#include "utils.h" +-#include "codepage.h" +-#include "midlevel.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/codepage.h" ++#include "afpfs-ng/midlevel.h" + #include "afp_internal.h" + #include "forklist.h" + #include "uams.h" +diff -Naur afpfs-ng-0.8.1/lib/proto_attr.c afpfs-ng-0.8.1.patch/lib/proto_attr.c +--- afpfs-ng-0.8.1/lib/proto_attr.c 2008-01-30 05:37:58.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_attr.c 2011-09-10 12:13:50.168125257 +0200 +@@ -7,10 +7,10 @@ + + #include + #include +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/afp_protocol.h" + #include "dsi_protocol.h" + + /* This is a new command, function 76. There are currently no docs, so this +diff -Naur afpfs-ng-0.8.1/lib/proto_desktop.c afpfs-ng-0.8.1.patch/lib/proto_desktop.c +--- afpfs-ng-0.8.1/lib/proto_desktop.c 2008-02-18 04:44:11.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_desktop.c 2011-09-10 12:13:50.168125257 +0200 +@@ -9,10 +9,10 @@ + #include + #include + +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/afp_protocol.h" + #include "dsi_protocol.h" + + /* closedt, addicon, geticoninfo, addappl, removeappl */ +diff -Naur afpfs-ng-0.8.1/lib/proto_directory.c afpfs-ng-0.8.1.patch/lib/proto_directory.c +--- afpfs-ng-0.8.1/lib/proto_directory.c 2008-02-19 03:39:29.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_directory.c 2011-09-10 12:13:50.168125257 +0200 +@@ -9,10 +9,10 @@ + #include + #include + +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/afp_protocol.h" + #include "dsi_protocol.h" + #include "afp_replies.h" + +diff -Naur afpfs-ng-0.8.1/lib/proto_files.c afpfs-ng-0.8.1.patch/lib/proto_files.c +--- afpfs-ng-0.8.1/lib/proto_files.c 2008-02-18 04:46:18.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_files.c 2011-09-10 12:13:50.169125270 +0200 +@@ -8,11 +8,11 @@ + + #include + #include +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "dsi_protocol.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/afp_protocol.h" + #include "afp_internal.h" + + /* afp_setfileparms, afp_setdirparms and afpsetfiledirparms are all remarkably +diff -Naur afpfs-ng-0.8.1/lib/proto_fork.c afpfs-ng-0.8.1.patch/lib/proto_fork.c +--- afpfs-ng-0.8.1/lib/proto_fork.c 2008-01-30 05:37:58.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_fork.c 2011-09-10 12:13:50.169125270 +0200 +@@ -9,11 +9,11 @@ + #include + #include + +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "dsi_protocol.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/afp_protocol.h" + + int afp_setforkparms(struct afp_volume * volume, + unsigned short forkid, unsigned short bitmap, unsigned long len) +diff -Naur afpfs-ng-0.8.1/lib/proto_login.c afpfs-ng-0.8.1.patch/lib/proto_login.c +--- afpfs-ng-0.8.1/lib/proto_login.c 2008-01-30 05:37:59.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_login.c 2011-09-10 12:13:50.169125270 +0200 +@@ -10,10 +10,10 @@ + + #include + #include +-#include "dsi.h" ++#include "afpfs-ng/dsi.h" + #include "dsi_protocol.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "afp_internal.h" + + +diff -Naur afpfs-ng-0.8.1/lib/proto_map.c afpfs-ng-0.8.1.patch/lib/proto_map.c +--- afpfs-ng-0.8.1/lib/proto_map.c 2008-01-30 05:37:59.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_map.c 2011-09-10 12:13:50.170125283 +0200 +@@ -9,11 +9,11 @@ + #include + #include + +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "dsi_protocol.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/afp_protocol.h" + + /* This is used to pass the return values back from afp_getuserinfo_reply() */ + struct uidgid { +diff -Naur afpfs-ng-0.8.1/lib/proto_replyblock.c afpfs-ng-0.8.1.patch/lib/proto_replyblock.c +--- afpfs-ng-0.8.1/lib/proto_replyblock.c 2008-02-18 04:46:19.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_replyblock.c 2011-09-10 12:13:50.170125283 +0200 +@@ -6,9 +6,9 @@ + */ + + #include +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "afp_internal.h" + + +diff -Naur afpfs-ng-0.8.1/lib/proto_server.c afpfs-ng-0.8.1.patch/lib/proto_server.c +--- afpfs-ng-0.8.1/lib/proto_server.c 2008-02-19 02:56:21.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_server.c 2011-09-10 12:13:50.170125283 +0200 +@@ -7,12 +7,12 @@ + */ + #include + #include +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "dsi_protocol.h" +-#include "afp_protocol.h" +-#include "codepage.h" ++#include "afpfs-ng/afp_protocol.h" ++#include "afpfs-ng/codepage.h" + #include "afp_internal.h" + + int afp_getsrvrparms(struct afp_server *server) +diff -Naur afpfs-ng-0.8.1/lib/proto_session.c afpfs-ng-0.8.1.patch/lib/proto_session.c +--- afpfs-ng-0.8.1/lib/proto_session.c 2008-02-18 04:46:19.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_session.c 2011-09-10 12:13:50.170125283 +0200 +@@ -8,10 +8,10 @@ + */ + #include + #include +-#include "dsi.h" ++#include "afpfs-ng/dsi.h" + #include "dsi_protocol.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + + int afp_getsessiontoken(struct afp_server * server, int type, + unsigned int timestamp, struct afp_token *outgoing_token, +diff -Naur afpfs-ng-0.8.1/lib/proto_volume.c afpfs-ng-0.8.1.patch/lib/proto_volume.c +--- afpfs-ng-0.8.1/lib/proto_volume.c 2008-02-18 04:47:48.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/proto_volume.c 2011-09-10 12:13:50.171125296 +0200 +@@ -8,13 +8,13 @@ + + #include + #include +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "dsi_protocol.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/afp_protocol.h" + #include "afp_internal.h" +-#include "codepage.h" ++#include "afpfs-ng/codepage.h" + + static int parse_volbitmap_reply(struct afp_server * server, + struct afp_volume * tmpvol, +diff -Naur afpfs-ng-0.8.1/lib/resource.c afpfs-ng-0.8.1.patch/lib/resource.c +--- afpfs-ng-0.8.1/lib/resource.c 2008-02-18 04:46:56.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/resource.c 2011-09-10 12:13:50.171125296 +0200 +@@ -3,11 +3,11 @@ + #include + #include + #include +-#include "afp.h" ++#include "afpfs-ng/afp.h" + #include "resource.h" + #include "lowlevel.h" + #include "did.h" +-#include "midlevel.h" ++#include "afpfs-ng/midlevel.h" + + #define appledouble ".AppleDouble" + #define finderinfo_string ".finderinfo" +diff -Naur afpfs-ng-0.8.1/lib/server.c afpfs-ng-0.8.1.patch/lib/server.c +--- afpfs-ng-0.8.1/lib/server.c 2008-02-19 02:56:21.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/server.c 2011-09-10 12:13:50.172125310 +0200 +@@ -8,15 +8,15 @@ + #include + #include + +-#include "afp.h" +-#include "dsi.h" +-#include "utils.h" +-#include "uams_def.h" +-#include "codepage.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/uams_def.h" ++#include "afpfs-ng/codepage.h" + #include "users.h" +-#include "libafpclient.h" ++#include "afpfs-ng/libafpclient.h" + #include "afp_internal.h" +-#include "dsi.h" ++#include "afpfs-ng/dsi.h" + + + struct afp_server * afp_server_complete_connection( +diff -Naur afpfs-ng-0.8.1/lib/status.c afpfs-ng-0.8.1.patch/lib/status.c +--- afpfs-ng-0.8.1/lib/status.c 2008-03-08 17:08:38.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/status.c 2011-09-10 12:13:50.172125310 +0200 +@@ -1,8 +1,8 @@ + #include + #include +-#include "map_def.h" +-#include "dsi.h" +-#include "afp.h" ++#include "afpfs-ng/map_def.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" + + int afp_status_header(char * text, int * len) + { +diff -Naur afpfs-ng-0.8.1/lib/uams.c afpfs-ng-0.8.1.patch/lib/uams.c +--- afpfs-ng-0.8.1/lib/uams.c 2008-01-04 04:52:44.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/uams.c 2011-09-10 12:13:50.173125324 +0200 +@@ -8,10 +8,10 @@ + + #include + #include +-#include "dsi.h" +-#include "afp.h" +-#include "utils.h" +-#include "uams_def.h" ++#include "afpfs-ng/dsi.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" ++#include "afpfs-ng/uams_def.h" + #include "config.h" + + #ifdef HAVE_LIBGCRYPT +diff -Naur afpfs-ng-0.8.1/lib/users.c afpfs-ng-0.8.1.patch/lib/users.c +--- afpfs-ng-0.8.1/lib/users.c 2008-02-18 04:48:56.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/users.c 2011-09-10 12:13:50.174125338 +0200 +@@ -3,8 +3,8 @@ + #include + #include + +-#include "afp.h" +-#include "map_def.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/map_def.h" + + /* How mapping works + * +diff -Naur afpfs-ng-0.8.1/lib/utils.c afpfs-ng-0.8.1.patch/lib/utils.c +--- afpfs-ng-0.8.1/lib/utils.c 2008-02-18 04:53:37.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/lib/utils.c 2011-09-10 12:13:50.174125338 +0200 +@@ -8,10 +8,10 @@ + #include + #include + #include +-#include "afp.h" +-#include "utils.h" ++#include "afpfs-ng/afp.h" ++#include "afpfs-ng/utils.h" + #include "afp_internal.h" +-#include "afp_protocol.h" ++#include "afpfs-ng/afp_protocol.h" + + struct afp_path_header_long { + unsigned char type; +diff -Naur afpfs-ng-0.8.1/Makefile.am afpfs-ng-0.8.1.patch/Makefile.am +--- afpfs-ng-0.8.1/Makefile.am 2008-02-18 04:24:14.000000000 +0100 ++++ afpfs-ng-0.8.1.patch/Makefile.am 2011-09-10 12:13:50.176125365 +0200 +@@ -1,5 +1,5 @@ + if HAVE_LIBFUSE +-SUBDIRS = lib fuse cmdline docs ++SUBDIRS = lib fuse cmdline include docs + else +-SUBDIRS = lib cmdline docs ++SUBDIRS = lib cmdline include docs + endif diff --git a/tools/depends/target/config-binaddons.site.in b/tools/depends/target/config-binaddons.site.in index 6d660a2..41d3d1d 100644 --- a/tools/depends/target/config-binaddons.site.in +++ b/tools/depends/target/config-binaddons.site.in @@ -34,7 +34,7 @@ LD_LIBRARY_PATH=@prefix@/@tool_dir@/lib:$LD_LIBRARY_PATH NATIVE_ROOT=@prefix@/@tool_dir@ -#libomxil-bellagio +#afps-ng and libomxil-bellagio ac_cv_func_malloc_0_nonnull=yes #curl diff --git a/tools/depends/target/config.site.in b/tools/depends/target/config.site.in index 36b3eab..26b5956 100644 --- a/tools/depends/target/config.site.in +++ b/tools/depends/target/config.site.in @@ -42,7 +42,7 @@ PYTHON_SITE_PKG=@prefix@/@deps_dir@/lib/python${PYTHON_VERSION}/site-packages PYTHON_NOVERSIONCHECK=no-check NATIVE_ROOT=@prefix@/@tool_dir@ -#libomxil-bellagio +#afps-ng and libomxil-bellagio ac_cv_func_malloc_0_nonnull=yes #curl diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 0fe02fa..3da4a6c 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -116,6 +116,9 @@ #ifdef HAS_FILESYSTEM_NFS #include "filesystem/NFSFile.h" #endif +#ifdef HAS_FILESYSTEM_AFP +#include "filesystem/AFPFile.h" +#endif #ifdef HAS_FILESYSTEM_SFTP #include "filesystem/SFTPFile.h" #endif @@ -4733,6 +4736,10 @@ void CApplication::ProcessSlow() gNfsConnection.CheckIfIdle(); #endif +#ifdef HAS_FILESYSTEM_AFP + gAfpConnection.CheckIfIdle(); +#endif + #ifdef HAS_FILESYSTEM_SFTP CSFTPSessionManager::ClearOutIdleSessions(); #endif @@ -5375,7 +5382,11 @@ void CApplication::CloseNetworkShares() #ifdef HAS_FILESYSTEM_NFS gNfsConnection.Deinit(); #endif - + +#ifdef HAS_FILESYSTEM_AFP + gAfpConnection.Deinit(); +#endif + #ifdef HAS_FILESYSTEM_SFTP CSFTPSessionManager::DisconnectAllSessions(); #endif diff --git a/xbmc/DllPaths_generated.h.in b/xbmc/DllPaths_generated.h.in index 5384a0b..b867a0f 100644 --- a/xbmc/DllPaths_generated.h.in +++ b/xbmc/DllPaths_generated.h.in @@ -33,6 +33,7 @@ #define DLL_PATH_LIBNFS "@NFS_SONAME@" #define DLL_PATH_LIBGIF "@GIF_SONAME@" +#define DLL_PATH_LIBAFP "@AFPCLIENT_SONAME@" #define DLL_PATH_LIBPLIST "@PLIST_SONAME@" #define DLL_PATH_LIBSHAIRPLAY "@SHAIRPLAY_SONAME@" #define DLL_PATH_LIBCEC "@LIBCEC_SONAME@" diff --git a/xbmc/DllPaths_generated_android.h.in b/xbmc/DllPaths_generated_android.h.in index edf6a04..15c5d2c 100644 --- a/xbmc/DllPaths_generated_android.h.in +++ b/xbmc/DllPaths_generated_android.h.in @@ -34,6 +34,7 @@ #define DLL_PATH_LIBRTMP "@RTMP_SONAME@" #define DLL_PATH_LIBNFS "@NFS_SONAME@" #define DLL_PATH_LIBGIF "@GIF_SONAME@" +#define DLL_PATH_LIBAFP "@AFPCLIENT_SONAME@" #define DLL_PATH_LIBPLIST "@PLIST_SONAME@" #define DLL_PATH_LIBSHAIRPLAY "@SHAIRPLAY_SONAME@" #define DLL_PATH_LIBCEC "@LIBCEC_SONAME@" diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp index 7c66e9e..190f5b1 100644 --- a/xbmc/FileItem.cpp +++ b/xbmc/FileItem.cpp @@ -1041,6 +1041,11 @@ bool CFileItem::IsNfs() const return URIUtils::IsNfs(m_strPath); } +bool CFileItem::IsAfp() const +{ + return URIUtils::IsAfp(m_strPath); +} + bool CFileItem::IsOnLAN() const { return URIUtils::IsOnLAN(m_strPath); @@ -2375,6 +2380,7 @@ void CFileItemList::StackFolders() if( !item->IsRemote() || item->IsSmb() || item->IsNfs() + || item->IsAfp() || URIUtils::IsInRAR(item->GetPath()) || URIUtils::IsInZIP(item->GetPath()) || URIUtils::IsOnLAN(item->GetPath()) diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h index 2cf3dcf..5cbeaf6 100644 --- a/xbmc/FileItem.h +++ b/xbmc/FileItem.h @@ -202,6 +202,7 @@ public: bool IsOnLAN() const; bool IsHD() const; bool IsNfs() const; + bool IsAfp() const; bool IsRemote() const; bool IsSmb() const; bool IsURL() const; diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp index 13a5f18..ae968cc 100644 --- a/xbmc/Util.cpp +++ b/xbmc/Util.cpp @@ -800,8 +800,8 @@ bool CUtil::CreateDirectoryEx(const std::string& strPath) // return true if directory already exist if (CDirectory::Exists(strPath)) return true; - // we currently only allow HD and smb and nfs paths - if (!URIUtils::IsHD(strPath) && !URIUtils::IsSmb(strPath) && !URIUtils::IsNfs(strPath)) + // we currently only allow HD and smb, nfs and afp paths + if (!URIUtils::IsHD(strPath) && !URIUtils::IsSmb(strPath) && !URIUtils::IsNfs(strPath) && !URIUtils::IsAfp(strPath)) { CLog::Log(LOGERROR,"%s called with an unsupported path: %s", __FUNCTION__, strPath.c_str()); return false; @@ -853,8 +853,8 @@ std::string CUtil::MakeLegalPath(const std::string &strPathAndFile, int LegalTyp return MakeLegalPath(CStackDirectory::GetFirstStackedFile(strPathAndFile)); if (URIUtils::IsMultiPath(strPathAndFile)) return MakeLegalPath(CMultiPathDirectory::GetFirstPath(strPathAndFile)); - if (!URIUtils::IsHD(strPathAndFile) && !URIUtils::IsSmb(strPathAndFile) && !URIUtils::IsNfs(strPathAndFile)) - return strPathAndFile; // we don't support writing anywhere except HD, SMB and NFS - no need to legalize path + if (!URIUtils::IsHD(strPathAndFile) && !URIUtils::IsSmb(strPathAndFile) && !URIUtils::IsNfs(strPathAndFile) && !URIUtils::IsAfp(strPathAndFile)) + return strPathAndFile; // we don't support writing anywhere except HD, SMB, NFS and AFP - no need to legalize path bool trailingSlash = URIUtils::HasSlashAtEnd(strPathAndFile); std::vector dirs = URIUtils::SplitPath(strPathAndFile); @@ -1385,7 +1385,7 @@ bool CUtil::MakeShortenPath(std::string StrInput, std::string& StrOutput, size_t bool CUtil::SupportsWriteFileOperations(const std::string& strPath) { - // currently only hd, smb, nfs and dav support delete and rename + // currently only hd, smb, nfs, afp and dav support delete and rename if (URIUtils::IsHD(strPath)) return true; if (URIUtils::IsSmb(strPath)) @@ -1394,6 +1394,8 @@ bool CUtil::SupportsWriteFileOperations(const std::string& strPath) return CPVRDirectory::SupportsWriteFileOperations(strPath); if (URIUtils::IsNfs(strPath)) return true; + if (URIUtils::IsAfp(strPath)) + return true; if (URIUtils::IsDAV(strPath)) return true; if (URIUtils::IsStack(strPath)) diff --git a/xbmc/cores/dvdplayer/Edl.cpp b/xbmc/cores/dvdplayer/Edl.cpp index 6d07bd6..4975209 100644 --- a/xbmc/cores/dvdplayer/Edl.cpp +++ b/xbmc/cores/dvdplayer/Edl.cpp @@ -103,7 +103,8 @@ bool CEdl::ReadEditDecisionLists(const std::string& strMovie, const float fFrame */ if ((URIUtils::IsHD(strMovie) || URIUtils::IsSmb(strMovie) || - URIUtils::IsNfs(strMovie)) && + URIUtils::IsNfs(strMovie) || + URIUtils::IsAfp(strMovie)) && !URIUtils::IsPVRRecording(strMovie) && !URIUtils::IsInternetStream(strMovie)) { diff --git a/xbmc/filesystem/AFPDirectory.cpp b/xbmc/filesystem/AFPDirectory.cpp new file mode 100644 index 0000000..df88ace --- /dev/null +++ b/xbmc/filesystem/AFPDirectory.cpp @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2011-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "system.h" + +#if defined(HAS_FILESYSTEM_AFP) +#include "AFPDirectory.h" +#include "AFPFile.h" +#include "Util.h" +#include "guilib/LocalizeStrings.h" +#include "Application.h" +#include "FileItem.h" +#include "settings/AdvancedSettings.h" +#include "utils/StringUtils.h" +#include "utils/log.h" +#include "utils/URIUtils.h" +#include "threads/SingleLock.h" +#include "PasswordManager.h" +#include "DllLibAfp.h" + +struct CachedDirEntry +{ + unsigned int type; + std::string name; +}; + +using namespace XFILE; +using namespace std; + +CAFPDirectory::CAFPDirectory(void) +{ + gAfpConnection.AddActiveConnection(); +} + +CAFPDirectory::~CAFPDirectory(void) +{ + gAfpConnection.AddIdleConnection(); +} + +bool CAFPDirectory::ResolveSymlink( const std::string &dirName, const std::string &fileName, + struct stat *stat, CURL &resolvedUrl) +{ + CSingleLock lock(gAfpConnection); + int ret = 0; + bool retVal = true; + char resolvedLink[MAX_PATH]; + std::string fullpath = dirName; + URIUtils::AddSlashAtEnd(fullpath); + fullpath += fileName; + + CPasswordManager::GetInstance().AuthenticateURL(resolvedUrl); + resolvedUrl.SetProtocol("afp"); + resolvedUrl.SetHostName(gAfpConnection.GetConnectedIp()); + + ret = gAfpConnection.GetImpl()->afp_wrap_readlink(gAfpConnection.GetVolume(), fullpath.c_str(), resolvedLink, MAX_PATH); + + if(ret == 0) + { + fullpath = dirName; + URIUtils::AddSlashAtEnd(fullpath); + fullpath.append(resolvedLink); + + if(resolvedLink[0] == '/') + { + //use the special stat function for using an extra context + //because we are inside of a dir traversation + //and just can't change the global nfs context here + //without destroying something... + fullpath = resolvedLink; + fullpath.erase(0, 1); + resolvedUrl.SetFileName(fullpath); + ret = gAfpConnection.stat(resolvedUrl, stat); + if(ret < 0) + { + URIUtils::AddSlashAtEnd(fullpath); + resolvedUrl.SetFileName(fullpath); + ret = gAfpConnection.stat(resolvedUrl, stat); + } + } + else + { + ret = gAfpConnection.GetImpl()->afp_wrap_getattr(gAfpConnection.GetVolume(), fullpath.c_str(), stat); + resolvedUrl.SetFileName(gAfpConnection.GetUrl()->volumename + fullpath); + } + + if (ret != 0) + { + CLog::Log(LOGERROR, "AFP: Failed to stat(%s) on link resolve %s\n", fullpath.c_str(), strerror(errno)); + retVal = false;; + } + } + else + { + CLog::Log(LOGERROR, "Failed to readlink(%s) %s\n", fullpath.c_str(), strerror(errno)); + retVal = false; + } + return retVal; +} + + +bool CAFPDirectory::GetDirectory(const CURL& url, CFileItemList &items) +{ + // We accept afp://[[user[:password@]]server[/share[/path[/file]]]] + // silence gdb breaking on signal SIGUSR2 with "handle SIGUSR2 nostop noprint" + bool bListVolumes = false; + FILETIME fileTime, localTime; + + CSingleLock lock(gAfpConnection); + CAfpConnection::afpConnnectError afpError = gAfpConnection.Connect(url); + + if (afpError != CAfpConnection::AfpOk || (!url.GetShareName().empty() && !gAfpConnection.GetVolume())) + { + if (afpError == CAfpConnection::AfpAuth) + { + if (m_flags & DIR_FLAG_ALLOW_PROMPT) + { + RequireAuthentication(url); + } + } + return false; + } + std::string strDirName = gAfpConnection.GetPath(url); + + vector vecEntries; + struct afp_file_info *dirEnt = NULL; + struct afp_file_info *curDirPtr = NULL; + + // if no share name in url - try to fetch the volumes on the server and treat them like folders + if (url.GetShareName().empty()) + { + bListVolumes = true; + struct afp_server *serv = gAfpConnection.GetServer(); + for (int i = 0; i < serv->num_volumes; i++) + { + CachedDirEntry aDir; + aDir.type = 1; + aDir.name = serv->volumes[i].volume_name; + vecEntries.push_back(aDir); + } + } + + // if we not only list volumes - read the dir + if (!bListVolumes) + { + if (gAfpConnection.GetImpl()->afp_wrap_readdir(gAfpConnection.GetVolume(), strDirName.c_str(), &dirEnt)) + return false; + lock.Leave(); + + for (curDirPtr = dirEnt; curDirPtr; curDirPtr = curDirPtr->next) + { + CachedDirEntry aDir; + aDir.type = curDirPtr->isdir; +#ifdef USE_CVS_AFPFS + aDir.name = curDirPtr->basic.name; +#else + aDir.name = curDirPtr->name; +#endif + vecEntries.push_back(aDir); + } + gAfpConnection.GetImpl()->afp_ml_filebase_free(&dirEnt); + } + + std::string myStrPath(url.Get()); + URIUtils::AddSlashAtEnd(myStrPath); //be sure the dir ends with a slash + for (size_t i = 0; i < vecEntries.size(); i++) + { + CachedDirEntry aDir = vecEntries[i]; + // We use UTF-8 internally, as does AFP + std::string strFile = aDir.name; + std::string path(myStrPath + strFile); + + if (strFile != "." && strFile != ".." && strFile != "lost+found") + { + int64_t iSize = 0; + bool bIsDir = aDir.type; + int64_t lTimeDate = 0; + + // if we not only list volumes - stat the files in folder + if (!bListVolumes) + { + struct stat info = {0}; + + if ((m_flags & DIR_FLAG_NO_FILE_INFO)==0 && g_advancedSettings.m_sambastatfiles) + { + // make sure we use the authenticated path wich contains any default username + std::string strFullName = strDirName + strFile; + + lock.Enter(); + + if (gAfpConnection.GetImpl()->afp_wrap_getattr(gAfpConnection.GetVolume(), strFullName.c_str(), &info) == 0) + { + //resolve symlinks + if(S_ISLNK(info.st_mode)) + { + CURL linkUrl(url); + if(!ResolveSymlink(strDirName, strFile, &info, linkUrl)) + { + lock.Leave(); + continue; + } + path = linkUrl.Get(); + bIsDir = S_ISDIR(info.st_mode); + } + lTimeDate = info.st_mtime; + if (lTimeDate == 0) // if modification date is missing, use create date + lTimeDate = info.st_ctime; + iSize = info.st_size; + } + else + { + CLog::Log(LOGERROR, "%s - Failed to stat file %s (%s)", __FUNCTION__, strFullName.c_str(),strerror(errno)); + } + + lock.Leave(); + } + LONGLONG ll = Int32x32To64(lTimeDate & 0xffffffff, 10000000) + 116444736000000000ll; + fileTime.dwLowDateTime = (DWORD)(ll & 0xffffffff); + fileTime.dwHighDateTime = (DWORD)(ll >> 32); + FileTimeToLocalFileTime(&fileTime, &localTime); + } + else + { + bIsDir = true; + localTime.dwHighDateTime = 0; + localTime.dwLowDateTime = 0; + } + + CFileItemPtr pItem(new CFileItem(strFile)); + pItem->m_dateTime = localTime; + pItem->m_dwSize = iSize; + + if (bIsDir) + { + URIUtils::AddSlashAtEnd(path); + pItem->m_bIsFolder = true; + } + else + { + pItem->m_bIsFolder = false; + } + + if (!aDir.name.empty() && aDir.name[0] == '.') + { + pItem->SetProperty("file:hidden", true); + } + + pItem->SetPath(path); + items.Add(pItem); + } + } + + return true; +} + +bool CAFPDirectory::Create(const CURL& url) +{ + CSingleLock lock(gAfpConnection); + + if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume()) + return false; + + std::string strFilename = gAfpConnection.GetPath(url); + + int result = gAfpConnection.GetImpl()->afp_wrap_mkdir(gAfpConnection.GetVolume(), strFilename.c_str(), 0); + + if (result != 0) + CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno)); + + return (result == 0 || EEXIST == result); +} + +bool CAFPDirectory::Remove(const CURL& url) +{ + CSingleLock lock(gAfpConnection); + + if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume()) + return false; + + std::string strFileName = gAfpConnection.GetPath(url); + + int result = gAfpConnection.GetImpl()->afp_wrap_rmdir(gAfpConnection.GetVolume(), strFileName.c_str()); + + if (result != 0 && errno != ENOENT) + { + CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno)); + return false; + } + + return true; +} + +bool CAFPDirectory::Exists(const CURL& url) +{ + CSingleLock lock(gAfpConnection); + + if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume()) + return false; + + std::string strFileName(gAfpConnection.GetPath(url)); + + struct stat info; + if (gAfpConnection.GetImpl()->afp_wrap_getattr(gAfpConnection.GetVolume(), strFileName.c_str(), &info) != 0) + return false; + + return S_ISDIR(info.st_mode); +} +#endif diff --git a/xbmc/filesystem/AFPDirectory.h b/xbmc/filesystem/AFPDirectory.h new file mode 100644 index 0000000..7fa3734 --- /dev/null +++ b/xbmc/filesystem/AFPDirectory.h @@ -0,0 +1,47 @@ +#pragma once +/* + * Copyright (C) 2011-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "IDirectory.h" +#include "MediaSource.h" +#include "URL.h" + +struct afp_file_info; + +namespace XFILE +{ +class CAFPDirectory : public IDirectory +{ +public: + CAFPDirectory(void); + virtual ~CAFPDirectory(void); + virtual bool GetDirectory(const CURL& url, CFileItemList &items); + virtual DIR_CACHE_TYPE GetCacheType(const CURL& url) const { return DIR_CACHE_ONCE; }; + virtual bool Create(const CURL& url); + virtual bool Exists(const CURL& url); + virtual bool Remove(const CURL& url); + + afp_file_info *Open(const CURL &url); +private: + afp_file_info *OpenDir(const CURL &url, std::string& strAuth); + bool ResolveSymlink( const std::string &dirName, const std::string &fileName, + struct stat *stat, CURL &resolvedUrl); +}; +} diff --git a/xbmc/filesystem/AFPFile.cpp b/xbmc/filesystem/AFPFile.cpp new file mode 100644 index 0000000..a4de580 --- /dev/null +++ b/xbmc/filesystem/AFPFile.cpp @@ -0,0 +1,728 @@ +/* + * Copyright (C) 2011-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +// FileAFP.cpp: implementation of the CAFPFile class. +// +////////////////////////////////////////////////////////////////////// +#ifdef TARGET_POSIX +#include "system.h" + +#if defined(HAS_FILESYSTEM_AFP) +#include "AFPFile.h" +#include "PasswordManager.h" +#include "AFPDirectory.h" +#include "Util.h" +#include "settings/AdvancedSettings.h" +#include "threads/SingleLock.h" +#include "utils/log.h" +#include "utils/StringUtils.h" +#include "utils/TimeUtils.h" + +using namespace XFILE; + +#define AFP_MAX_READ_SIZE 131072 + +void AfpConnectionLog(void *priv, enum loglevels loglevel, int logtype, const char *message) +{ + if (!message) return; + std::string msg = "LIBAFPCLIENT: " + std::string(message); + + switch(logtype) + { + case LOG_WARNING: + CLog::Log(LOGWARNING, "%s", msg.c_str()); + break; + case LOG_ERR: + CLog::Log(LOGERROR, "%s", msg.c_str()); + break; + default: + CLog::Log(LOGDEBUG, "%s", msg.c_str()); + break; + } +} + +CAfpConnection::CAfpConnection() + : m_OpenConnections(0) + , m_IdleTimeout(0) + , m_pAfpServer(NULL) + , m_pAfpVol(NULL) + , m_pAfpUrl((struct afp_url*)malloc(sizeof(struct afp_url))) + , m_pAfpClient((struct libafpclient*)malloc(sizeof(struct libafpclient))) + , m_pLibAfp(new DllLibAfp()) + , m_bDllInited(false) +{ +} + +CAfpConnection::~CAfpConnection() +{ + Disconnect(); + free(m_pAfpClient); + free(m_pAfpUrl); + if (m_pLibAfp->IsLoaded()) + m_pLibAfp->Unload(); + delete m_pLibAfp; +} + +bool CAfpConnection::initLib() +{ + if (!m_bDllInited) + { + if (m_pLibAfp->Load()) + { + m_pAfpClient->unmount_volume = NULL; + m_pAfpClient->log_for_client = AfpConnectionLog; + m_pAfpClient->forced_ending_hook = NULL; + m_pAfpClient->scan_extra_fds = NULL; + m_pAfpClient->loop_started = NULL; + + m_pLibAfp->libafpclient_register(m_pAfpClient); + m_pLibAfp->init_uams(); + m_pLibAfp->afp_main_quick_startup(NULL); + CLog::Log(LOGDEBUG, "AFP: Supported UAMs: %s", m_pLibAfp->get_uam_names_list()); + m_bDllInited = true; + } + else + { + CLog::Log(LOGERROR, "AFP: Error loading afpclient lib."); + } + } + + return m_bDllInited; +} + +//only unmount here - afpclient lib is not +//stoppable (no afp_main_quick_shutdown as counter part +//for afp_main_quick_startup) +void CAfpConnection::Deinit() +{ + if(m_pAfpVol && m_pLibAfp->IsLoaded()) + { + disconnectVolume(); + Disconnect(); + m_pAfpUrl->servername[0] = '\0'; + } +} + +void CAfpConnection::Disconnect() +{ + CSingleLock lock(*this); + m_pAfpServer = NULL; +} + +void CAfpConnection::disconnectVolume() +{ + if (m_pAfpVol) + { + // afp_unmount_volume(m_pAfpVol); + m_pLibAfp->afp_unmount_all_volumes(m_pAfpServer); + m_pAfpVol = NULL; + } +} + +// taken from cmdline tool +bool CAfpConnection::connectVolume(const char *volumename, struct afp_volume *&pVolume) +{ + bool ret = false; + if (strlen(volumename) != 0) + { + // Ah, we're not connected to a volume + unsigned int len = 0; + char mesg[1024]; + + if ((pVolume = m_pLibAfp->find_volume_by_name(m_pAfpServer, volumename)) == NULL) + { + CLog::Log(LOGDEBUG, "AFP: Could not find a volume called %s\n", volumename); + } + else + { + pVolume->mapping = AFP_MAPPING_LOGINIDS; + pVolume->extra_flags |= VOLUME_EXTRA_FLAGS_NO_LOCKING; + + if (m_pLibAfp->afp_connect_volume(pVolume, m_pAfpServer, mesg, &len, 1024 )) + { + CLog::Log(LOGDEBUG, "AFP: Could not access volume %s (error: %s)\n", pVolume->volume_name, mesg); + pVolume = NULL; + } + else + { + CLog::Log(LOGDEBUG, "AFP: Connected to volume %s\n", pVolume->volume_name_printable); + ret = true; + } + } + } + + return ret; +} + +CURL CAfpConnection::getAuthenticatedPath(const CURL &url) +{ + CURL authURL(url); + CPasswordManager::GetInstance().AuthenticateURL(authURL); + return authURL; +} + +CAfpConnection::afpConnnectError CAfpConnection::Connect(const CURL& url) +{ + CSingleLock lock(*this); + struct afp_connection_request *conn_req = NULL; + struct afp_url tmpurl; + CURL nonConstUrl(getAuthenticatedPath(url)); // we need a editable copy of the url + bool serverChanged=false; + + if (!initLib()) + return AfpFailed; + + m_pLibAfp->afp_default_url(&tmpurl); + + // if hostname has changed - assume server changed + if (nonConstUrl.GetHostName() != m_pAfpUrl->servername || (m_pAfpServer && m_pAfpServer->connect_state == 0)) + { + serverChanged = true; + Disconnect(); + } + + // if volume changed - also assume server changed (afpclient can't reuse old servobject it seems) + if (nonConstUrl.GetShareName() != m_pAfpUrl->volumename) + { + // no reusing of old server object possible with libafpclient it seems... + serverChanged = true; + Disconnect(); + } + + // first, try to parse the URL + if (m_pLibAfp->afp_parse_url(&tmpurl, nonConstUrl.Get().c_str(), 0) != 0) + { + // Okay, this isn't a real URL + CLog::Log(LOGDEBUG, "AFP: Could not parse url: %s!\n", nonConstUrl.Get().c_str()); + return AfpFailed; + } + else // parsed successfully + { + // this is our current url object whe are connected to (at least we try) + *m_pAfpUrl = tmpurl; + } + + // if no username and password is set - use no user authent uam + if (strlen(m_pAfpUrl->password) == 0 && strlen(m_pAfpUrl->username) == 0) + { + // try anonymous + strncpy(m_pAfpUrl->uamname, "No User Authent", sizeof(m_pAfpUrl->uamname)); + CLog::Log(LOGDEBUG, "AFP: Using anonymous authentication."); + } + else if ((nonConstUrl.GetPassWord().empty() || nonConstUrl.GetUserName().empty()) && serverChanged) + { + // this is our current url object whe are connected to (at least we try) + return AfpAuth; + } + + // we got a password in the url + if (!nonConstUrl.GetPassWord().empty()) + { + // copy password because afp_parse_url just puts garbage into the password field :( + strncpy(m_pAfpUrl->password, nonConstUrl.GetPassWord().c_str(), 127); + } + + // whe are not connected or we want to connect to another server + if (!m_pAfpServer || serverChanged) + { + // code from cmdline tool + conn_req = (struct afp_connection_request*)malloc(sizeof(struct afp_connection_request)); + memset(conn_req, 0, sizeof(struct afp_connection_request)); + + conn_req->url = *m_pAfpUrl; + conn_req->url.requested_version = 31; + + if (strlen(m_pAfpUrl->uamname)>0) + { + if ((conn_req->uam_mask = m_pLibAfp->find_uam_by_name(m_pAfpUrl->uamname)) == 0) + { + CLog::Log(LOGDEBUG, "AFP:I don't know about UAM %s\n", m_pAfpUrl->uamname); + m_pAfpUrl->volumename[0] = '\0'; + m_pAfpUrl->servername[0] = '\0'; + free(conn_req); + return AfpFailed; + } + } + else + { + conn_req->uam_mask = m_pLibAfp->default_uams_mask(); + } + + // try to connect +#ifdef USE_CVS_AFPFS + if ((m_pAfpServer = m_pLibAfp->afp_wrap_server_full_connect(NULL, conn_req, NULL)) == NULL) +#else + if ((m_pAfpServer = m_pLibAfp->afp_wrap_server_full_connect(NULL, conn_req)) == NULL) +#endif + { + m_pAfpUrl->volumename[0] = '\0'; + m_pAfpUrl->servername[0] = '\0'; + free(conn_req); + CLog::Log(LOGERROR, "AFP: Error connecting to %s", url.Get().c_str()); + return AfpFailed; + } + // success! + CLog::Log(LOGDEBUG, "AFP: Connected to server %s using UAM \"%s\"\n", + m_pAfpServer->server_name, m_pLibAfp->uam_bitmap_to_string(m_pAfpServer->using_uam)); + // we don't need it after here ... + free(conn_req); + } + + // if server changed reconnect volume + if (serverChanged) + { + connectVolume(m_pAfpUrl->volumename, m_pAfpVol); // connect new volume + } + return AfpOk; +} + +int CAfpConnection::stat(const CURL &url, struct stat *statbuff) +{ + CSingleLock lock(*this); + std::string strPath = gAfpConnection.GetPath(url); + struct afp_volume *pTmpVol = NULL; + struct afp_url tmpurl; + int iResult = -1; + CURL nonConstUrl(getAuthenticatedPath(url)); // we need a editable copy of the url + + if (!initLib() || !m_pAfpServer) + return -1; + + m_pLibAfp->afp_default_url(&tmpurl); + + // first, try to parse the URL + if (m_pLibAfp->afp_parse_url(&tmpurl, nonConstUrl.Get().c_str(), 0) != 0) + { + // Okay, this isn't a real URL + CLog::Log(LOGDEBUG, "AFP: Could not parse url: %s!\n", nonConstUrl.Get().c_str()); + return -1; + } + + // if no username and password is set - use no user authent uam + if (strlen(tmpurl.password) == 0 && strlen(tmpurl.username) == 0) + { + // try anonymous + strncpy(tmpurl.uamname, "No User Authent", sizeof(tmpurl.uamname)); + CLog::Log(LOGDEBUG, "AFP: Using anonymous authentication."); + } + else if ((nonConstUrl.GetPassWord().empty() || nonConstUrl.GetUserName().empty())) + { + // this is our current url object whe are connected to (at least we try) + return -1; + } + + // we got a password in the url + if (!nonConstUrl.GetPassWord().empty()) + { + // copy password because afp_parse_url just puts garbage into the password field :( + strncpy(tmpurl.password, nonConstUrl.GetPassWord().c_str(), 127); + } + + // connect new volume + if(connectVolume(tmpurl.volumename, pTmpVol) && pTmpVol) + { + iResult = m_pLibAfp->afp_wrap_getattr(pTmpVol, strPath.c_str(), statbuff); + //unmount single volume crashs + //we will get rid of the mounted volume + //once the context is changed in connect function + //ppppooooorrrr!! + //m_pLibAfp->afp_unmount_volume(pTmpVol); + } + return iResult; +} + + +/* This is called from CApplication::ProcessSlow() and is used to tell if afp have been idle for too long */ +void CAfpConnection::CheckIfIdle() +{ + /* We check if there are open connections. This is done without a lock to not halt the mainthread. It should be thread safe as + worst case scenario is that m_OpenConnections could read 0 and then changed to 1 if this happens it will enter the if wich will lead to another check, wich is locked. */ + if (m_OpenConnections == 0 && m_pAfpVol != NULL) + { /* I've set the the maxiumum IDLE time to be 1 min and 30 sec. */ + CSingleLock lock(*this); + if (m_OpenConnections == 0 /* check again - when locked */) + { + if (m_IdleTimeout > 0) + { + m_IdleTimeout--; + } + else + { + CLog::Log(LOGNOTICE, "AFP is idle. Closing the remaining connections."); + gAfpConnection.Deinit(); + } + } + } +} + +/* The following two function is used to keep track on how many Opened files/directories there are. +needed for unloading the dylib*/ +void CAfpConnection::AddActiveConnection() +{ + CSingleLock lock(*this); + m_OpenConnections++; +} + +void CAfpConnection::AddIdleConnection() +{ + CSingleLock lock(*this); + m_OpenConnections--; + /* If we close a file we reset the idle timer so that we don't have any wierd behaviours if a user + leaves the movie paused for a long while and then press stop */ + m_IdleTimeout = 180; +} + +std::string CAfpConnection::GetPath(const CURL &url) +{ + struct afp_url tmpurl; + std::string ret; + + m_pLibAfp->afp_default_url(&tmpurl); + + // First, try to parse the URL + if (m_pLibAfp->afp_parse_url(&tmpurl, url.Get().c_str(), 0) != 0 ) + { + // Okay, this isn't a real URL + CLog::Log(LOGDEBUG, "AFP: Could not parse url.\n"); + } + else + { + ret = tmpurl.path; + } + return ret; +} + +CAfpConnection gAfpConnection; + +CAFPFile::CAFPFile() + : m_fileSize(0) + , m_fileOffset(0) + , m_pFp(NULL) + , m_pAfpVol(NULL) +{ + gAfpConnection.AddActiveConnection(); +} + +CAFPFile::~CAFPFile() +{ + gAfpConnection.AddIdleConnection(); + Close(); +} + +int64_t CAFPFile::GetPosition() +{ + if (m_pFp == NULL) return 0; + return m_fileOffset; +} + +int64_t CAFPFile::GetLength() +{ + if (m_pFp == NULL) return 0; + return m_fileSize; +} + +bool CAFPFile::Open(const CURL& url) +{ + Close(); + // we can't open files like afp://file.f or afp://server/file.f + // if a file matches the if below return false, it can't exist on a afp share. + if (!IsValidFile(url.GetFileName())) + { + CLog::Log(LOGNOTICE, "FileAfp: Bad URL : '%s'", url.GetFileName().c_str()); + return false; + } + + CSingleLock lock(gAfpConnection); + if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume()) + return false; + m_pAfpVol = gAfpConnection.GetVolume(); + + std::string strPath = gAfpConnection.GetPath(url); + + if (gAfpConnection.GetImpl()->afp_wrap_open(m_pAfpVol, strPath.c_str(), O_RDONLY, &m_pFp)) + { + if (gAfpConnection.GetImpl()->afp_wrap_open(m_pAfpVol, CURL::Encode(strPath.c_str()).c_str(), O_RDONLY, &m_pFp)) + { + // write error to logfile + CLog::Log(LOGINFO, "CAFPFile::Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strPath.c_str(), errno, strerror(errno)); + return false; + } + } + + CLog::Log(LOGDEBUG,"CAFPFile::Open - opened %s, fd=%d",url.GetFileName().c_str(), m_pFp ? m_pFp->fileid:-1); + m_url = url; + +#ifdef TARGET_POSIX + struct __stat64 tmpBuffer; +#else + struct stat tmpBuffer; +#endif + if(Stat(&tmpBuffer)) + { + m_url.Reset(); + Close(); + return false; + } + + m_fileSize = tmpBuffer.st_size; + m_fileOffset = 0; + // We've successfully opened the file! + return true; +} + + +bool CAFPFile::Exists(const CURL& url) +{ + return Stat(url, NULL) == 0; +} + +int CAFPFile::Stat(struct __stat64* buffer) +{ + if (m_pFp == NULL) + return -1; + return Stat(m_url, buffer); +} + +// TODO - maybe check returncode! +int CAFPFile::Stat(const CURL& url, struct __stat64* buffer) +{ + CSingleLock lock(gAfpConnection); + if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume()) + return -1; + + std::string strPath = gAfpConnection.GetPath(url); + + struct stat tmpBuffer = {0}; + int iResult = gAfpConnection.GetImpl()->afp_wrap_getattr(gAfpConnection.GetVolume(), strPath.c_str(), &tmpBuffer); + + if (buffer) + { + memset(buffer, 0, sizeof(struct __stat64)); + buffer->st_dev = tmpBuffer.st_dev; + buffer->st_ino = tmpBuffer.st_ino; + buffer->st_mode = tmpBuffer.st_mode; + buffer->st_nlink = tmpBuffer.st_nlink; + buffer->st_uid = tmpBuffer.st_uid; + buffer->st_gid = tmpBuffer.st_gid; + buffer->st_rdev = tmpBuffer.st_rdev; + buffer->st_size = tmpBuffer.st_size; + buffer->st_atime = tmpBuffer.st_atime; + buffer->st_mtime = tmpBuffer.st_mtime; + buffer->st_ctime = tmpBuffer.st_ctime; + } + + return iResult; +} + +ssize_t CAFPFile::Read(void *lpBuf, size_t uiBufSize) +{ + CSingleLock lock(gAfpConnection); + if (m_pFp == NULL || !m_pAfpVol) + return -1; + + if (uiBufSize > AFP_MAX_READ_SIZE) + uiBufSize = AFP_MAX_READ_SIZE; + +#ifdef USE_CVS_AFPFS + char *name = m_pFp->basename; +#else + char *name = m_pFp->name; + if (strlen(name) == 0) + name = m_pFp->basename; + +#endif + int eof = 0; + ssize_t bytesRead = gAfpConnection.GetImpl()->afp_wrap_read(m_pAfpVol, + name, (char *)lpBuf,(size_t)uiBufSize, m_fileOffset, m_pFp, &eof); + if (bytesRead > 0) + m_fileOffset += bytesRead; + + if (bytesRead < 0) + { + CLog::Log(LOGERROR, "%s - Error( %d, %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno)); + return -1; + } + + return bytesRead; +} + +int64_t CAFPFile::Seek(int64_t iFilePosition, int iWhence) +{ + off_t newOffset = m_fileOffset; + if (m_pFp == NULL) return -1; + + switch(iWhence) + { + case SEEK_SET: + newOffset = iFilePosition; + break; + case SEEK_END: + newOffset = m_fileSize+iFilePosition; + break; + case SEEK_CUR: + newOffset += iFilePosition; + break; + } + + if ( newOffset < 0 || newOffset > m_fileSize) + { + CLog::Log(LOGERROR, "%s - Error( %" PRId64")", __FUNCTION__, newOffset); + return -1; + } + + m_fileOffset = newOffset; + return (int64_t)m_fileOffset; +} + +void CAFPFile::Close() +{ + CSingleLock lock(gAfpConnection); + if (m_pFp != NULL && m_pAfpVol) + { + CLog::Log(LOGDEBUG, "CAFPFile::Close closing fd %d", m_pFp->fileid); +#ifdef USE_CVS_AFPFS + char *name = m_pFp->basename; +#else + char *name = m_pFp->name; + if (strlen(name) == 0) + name = m_pFp->basename; +#endif + gAfpConnection.GetImpl()->afp_wrap_close(m_pAfpVol, name, m_pFp); + delete m_pFp; + m_pFp = NULL; + m_pAfpVol = NULL; + } +} + +ssize_t CAFPFile::Write(const void* lpBuf, size_t uiBufSize) +{ + CSingleLock lock(gAfpConnection); + if (m_pFp == NULL || !m_pAfpVol) + return -1; + + ssize_t numberOfBytesWritten = 0; + uid_t uid; + gid_t gid; + + // FIXME need a better way to get server's uid/gid + uid = getuid(); + gid = getgid(); +#ifdef USE_CVS_AFPFS + char *name = m_pFp->basename; +#else + char *name = m_pFp->name; + if (strlen(name) == 0) + name = m_pFp->basename; +#endif + numberOfBytesWritten = gAfpConnection.GetImpl()->afp_wrap_write(m_pAfpVol, + name, (const char *)lpBuf, uiBufSize, m_fileOffset, m_pFp, uid, gid); + + if (numberOfBytesWritten > 0) + m_fileOffset += numberOfBytesWritten; + + return numberOfBytesWritten; +} + +bool CAFPFile::Delete(const CURL& url) +{ + CSingleLock lock(gAfpConnection); + if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume()) + return false; + + std::string strPath = gAfpConnection.GetPath(url); + + int result = gAfpConnection.GetImpl()->afp_wrap_unlink(gAfpConnection.GetVolume(), strPath.c_str()); + + if (result != 0) + CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno)); + + return (result == 0); +} + +bool CAFPFile::Rename(const CURL& url, const CURL& urlnew) +{ + CSingleLock lock(gAfpConnection); + if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume()) + return false; + + std::string strFile = gAfpConnection.GetPath(url); + std::string strFileNew = gAfpConnection.GetPath(urlnew); + + int result = gAfpConnection.GetImpl()->afp_wrap_rename(gAfpConnection.GetVolume(), strFile.c_str(), strFileNew.c_str()); + + if (result != 0) + CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno)); + + return (result == 0); +} + +bool CAFPFile::OpenForWrite(const CURL& url, bool bOverWrite) +{ + + int ret = 0; + m_fileSize = 0; + m_fileOffset = 0; + + Close(); + CSingleLock lock(gAfpConnection); + if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume()) + return false; + + // we can't open files like afp://file.f or afp://server/file.f + // if a file matches the if below return false, it can't exist on a afp share. + if (!IsValidFile(url.GetFileName())) + return false; + + m_pAfpVol = gAfpConnection.GetVolume(); + + std::string strPath = gAfpConnection.GetPath(url); + + if (bOverWrite) + { + CLog::Log(LOGWARNING, "FileAFP::OpenForWrite() called with overwriting enabled! - %s", strPath.c_str()); + ret = gAfpConnection.GetImpl()->afp_wrap_creat(m_pAfpVol, strPath.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + } + + ret = gAfpConnection.GetImpl()->afp_wrap_open(m_pAfpVol, strPath.c_str(), O_RDWR, &m_pFp); + + if (ret || m_pFp == NULL) + { + // write error to logfile + CLog::Log(LOGERROR, "CAFPFile::Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strPath.c_str(), errno, strerror(errno)); + return false; + } + + // We've successfully opened the file! + return true; +} + +bool CAFPFile::IsValidFile(const std::string& strFileName) +{ + if (strFileName.find('/') == std::string::npos || // doesn't have sharename + StringUtils::EndsWith(strFileName, "/.") || // not current folder + StringUtils::EndsWith(strFileName, "/..")) // not parent folder + { + return false; + } + + return true; +} +#endif // HAS_FILESYSTEM_AFP +#endif // TARGET_POSIX diff --git a/xbmc/filesystem/AFPFile.h b/xbmc/filesystem/AFPFile.h new file mode 100644 index 0000000..9880b26 --- /dev/null +++ b/xbmc/filesystem/AFPFile.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2011-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +// FileAFP.h: interface for the CAFPFile class. +#ifndef FILEAFP_H_ +#define FILEAFP_H_ + + +#ifdef TARGET_POSIX + +#include "IFile.h" +#include "URL.h" +#include "threads/CriticalSection.h" +#include "DllLibAfp.h" + +// libafpclient includes +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + +class CAfpConnection : public CCriticalSection +{ +public: + enum eAfpConnectError + { + AfpOk = 0, + AfpFailed = 1, + AfpAuth = 2, + }; + typedef enum eAfpConnectError afpConnnectError; + + CAfpConnection(); + ~CAfpConnection(); + + afpConnnectError Connect(const CURL &url); + void Disconnect(void); + struct afp_server *GetServer() {return m_pAfpServer;} + struct afp_volume *GetVolume() {return m_pAfpVol;}; + struct afp_url *GetUrl() {return m_pAfpUrl;}; + std::string GetPath(const CURL &url); + DllLibAfp *GetImpl() {return m_pLibAfp;} + + const char *GetConnectedIp() const { if(m_pAfpUrl) return m_pAfpUrl->servername;else return "";} + + //special stat which uses its own context + //needed for getting intervolume symlinks to work + //it uses the same global server connection + //but its own volume + int stat(const CURL &url, struct stat *statbuff); + + void AddActiveConnection(); + void AddIdleConnection(); + void CheckIfIdle(); + void Deinit(); + +private: + bool initLib(void); + bool connectVolume(const char *volumename, struct afp_volume *&pVolume); + void disconnectVolume(void); + CURL getAuthenticatedPath(const CURL &url); + + int m_OpenConnections; + int m_IdleTimeout; + struct afp_server *m_pAfpServer; + struct afp_volume *m_pAfpVol; + struct afp_url *m_pAfpUrl; + struct libafpclient *m_pAfpClient; + DllLibAfp *m_pLibAfp; + bool m_bDllInited; +}; + +extern CAfpConnection gAfpConnection; + +namespace XFILE +{ +class CAFPFile : public IFile +{ +public: + CAFPFile(); + virtual ~CAFPFile(); + virtual void Close(); + virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET); + virtual ssize_t Read(void* lpBuf, size_t uiBufSize); + virtual bool Open(const CURL& url); + virtual bool Exists(const CURL& url); + virtual int Stat(const CURL& url, struct __stat64* buffer); + virtual int Stat(struct __stat64* buffer); + virtual int64_t GetLength(); + virtual int64_t GetPosition(); + virtual ssize_t Write(const void* lpBuf, size_t uiBufSize); + + virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false); + virtual bool Delete(const CURL& url); + virtual bool Rename(const CURL& url, const CURL& urlnew); + virtual int GetChunkSize() {return 1;} + // implement iocontrol for seek_possible for preventing the stat in File class for + // getting this info ... + virtual int IoControl(EIoControl request, void* param) + { if (request == IOCTRL_SEEK_POSSIBLE) return 1; + return -1; + }; + +protected: + bool IsValidFile(const std::string& strFileName); + + CURL m_url; + int64_t m_fileSize; + off_t m_fileOffset; // current SEEK pointer + struct afp_file_info *m_pFp; + struct afp_volume *m_pAfpVol; +}; +} +#endif // TARGET_POSIX +#endif // FILEAFP_H_ diff --git a/xbmc/filesystem/DirectoryFactory.cpp b/xbmc/filesystem/DirectoryFactory.cpp index 05ad2be..096627f 100644 --- a/xbmc/filesystem/DirectoryFactory.cpp +++ b/xbmc/filesystem/DirectoryFactory.cpp @@ -94,6 +94,9 @@ #ifdef HAS_FILESYSTEM_NFS #include "NFSDirectory.h" #endif +#ifdef HAS_FILESYSTEM_AFP +#include "AFPDirectory.h" +#endif #ifdef HAVE_LIBBLURAY #include "BlurayDirectory.h" #endif @@ -208,6 +211,9 @@ IDirectory* CDirectoryFactory::Create(const CURL& url) #ifdef HAS_FILESYSTEM_NFS if (url.IsProtocol("nfs")) return new CNFSDirectory(); #endif +#ifdef HAS_FILESYSTEM_AFP + if (url.IsProtocol("afp")) return new CAFPDirectory(); +#endif } CLog::Log(LOGWARNING, "%s - %sunsupported protocol(%s) in %s", __FUNCTION__, networkAvailable ? "" : "Network down or ", url.GetProtocol().c_str(), url.GetRedacted().c_str() ); diff --git a/xbmc/filesystem/DllLibAfp.h b/xbmc/filesystem/DllLibAfp.h new file mode 100644 index 0000000..c87d920 --- /dev/null +++ b/xbmc/filesystem/DllLibAfp.h @@ -0,0 +1,214 @@ +#pragma once + +/* + * Copyright (C) 2011-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "DynamicDll.h" + +//libafpclient includes +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include +#ifdef __cplusplus +} +#endif + + +//#define USE_CVS_AFPFS +#ifdef USE_CVS_AFPFS +#define afp_wrap_open afp_ml_open +#define afp_wrap_close afp_ml_close +#define afp_wrap_read afp_ml_read +#define afp_wrap_write afp_ml_write +#define afp_wrap_getattr afp_ml_getattr +#define afp_wrap_server_full_connect afp_server_full_connect +#define afp_wrap_unlink afp_ml_unlink +#define afp_wrap_rename afp_ml_rename +#define afp_wrap_creat afp_ml_creat +#define afp_wrap_readdir afp_ml_readdir +#define afp_wrap_readlink afp_ml_readlink +#define afp_wrap_mkdir afp_ml_mkdir +#define afp_wrap_rmdir afp_ml_rmdir +#else +#define afp_wrap_open ml_open +#define afp_wrap_close ml_close +#define afp_wrap_read ml_read +#define afp_wrap_write ml_write +#define afp_wrap_getattr ml_getattr +#define afp_wrap_server_full_connect afp_server_full_connect +#define afp_wrap_unlink ml_unlink +#define afp_wrap_rename ml_rename +#define afp_wrap_creat ml_creat +#define afp_wrap_readdir ml_readdir +#define afp_wrap_readlink ml_readlink +#define afp_wrap_mkdir ml_mkdir +#define afp_wrap_rmdir ml_rmdir +#endif + + +class DllLibAfpInterface +{ +public: + virtual ~DllLibAfpInterface() {} + + virtual void libafpclient_register(struct libafpclient * tmpclient)=0; + virtual int init_uams(void)=0; + virtual int afp_main_quick_startup(pthread_t * thread)=0; + virtual int afp_unmount_all_volumes(struct afp_server * server)=0; + virtual int afp_unmount_volume(struct afp_volume * volume)=0; + virtual struct afp_volume * find_volume_by_name(struct afp_server * server, const char * volname)=0; + virtual int afp_connect_volume(struct afp_volume * volume, struct afp_server * server, char * mesg, unsigned int * l, unsigned int max)=0; + virtual int afp_parse_url(struct afp_url * url, const char * toparse, int verbose)=0; + virtual unsigned int find_uam_by_name(const char * name)=0; + virtual unsigned int default_uams_mask(void)=0; + virtual char * uam_bitmap_to_string(unsigned int bitmap)=0; + virtual void afp_default_url(struct afp_url *url)=0; + virtual char * get_uam_names_list(void)=0; + virtual void afp_ml_filebase_free(struct afp_file_info **filebase)=0; + +#ifdef USE_CVS_AFPFS + virtual struct afp_server * afp_server_full_connect(void * priv, struct afp_connection_request * req, int * error)=0; + virtual int afp_ml_open(struct afp_volume * volume, const char *path, int flags, struct afp_file_info **newfp)=0; + virtual int afp_ml_close(struct afp_volume * volume, const char * path, struct afp_file_info * fp)=0; + virtual int afp_ml_read(struct afp_volume * volume, const char *path, char *buf, size_t size, off_t offset, struct afp_file_info *fp, int * eof)=0; + virtual int afp_ml_write(struct afp_volume * volume, const char * path, const char *data, size_t size, off_t offset, struct afp_file_info * fp, uid_t uid, gid_t gid)=0; + virtual int afp_ml_getattr(struct afp_volume * volume, const char *path, struct stat *stbuf)=0; + virtual int afp_ml_unlink(struct afp_volume * vol, const char *path)=0; + virtual int afp_ml_rename(struct afp_volume * vol, const char * path_from, const char * path_to)=0; + virtual int afp_ml_creat(struct afp_volume * volume, const char *path, mode_t mode)=0; + virtual int afp_ml_readdir(struct afp_volume * volume, const char *path, struct afp_file_info **base)=0; + virtual int afp_ml_readlink(struct afp_volume * vol, const char * path, char *buf, size_t size)=0; + virtual int afp_ml_mkdir(struct afp_volume * vol, const char * path, mode_t mode)=0; + virtual int afp_ml_rmdir(struct afp_volume * vol, const char *path)=0; + +#else + virtual struct afp_server * afp_server_full_connect(void * priv, struct afp_connection_request * req)=0; + virtual int ml_open(struct afp_volume * volume, const char *path, int flags, struct afp_file_info **newfp)=0; + virtual int ml_close(struct afp_volume * volume, const char * path, struct afp_file_info * fp)=0; + virtual int ml_read(struct afp_volume * volume, const char *path, char *buf, size_t size, off_t offset, struct afp_file_info *fp, int * eof)=0; + virtual int ml_write(struct afp_volume * volume, const char * path, const char *data, size_t size, off_t offset, struct afp_file_info * fp, uid_t uid, gid_t gid)=0; + virtual int ml_getattr(struct afp_volume * volume, const char *path, struct stat *stbuf)=0; + virtual int ml_unlink(struct afp_volume * vol, const char *path)=0; + virtual int ml_rename(struct afp_volume * vol, const char * path_from, const char * path_to)=0; + virtual int ml_creat(struct afp_volume * volume, const char *path, mode_t mode)=0; + virtual int ml_readdir(struct afp_volume * volume, const char *path, struct afp_file_info **base)=0; + virtual int ml_readlink(struct afp_volume * vol, const char * path, char *buf, size_t size)=0; + virtual int ml_mkdir(struct afp_volume * vol, const char * path, mode_t mode)=0; + virtual int ml_rmdir(struct afp_volume * vol, const char *path)=0; + +#endif + +}; + +class DllLibAfp : public DllDynamic, DllLibAfpInterface +{ + DECLARE_DLL_WRAPPER(DllLibAfp, DLL_PATH_LIBAFP) + DEFINE_METHOD0(int, init_uams) + DEFINE_METHOD0(unsigned int, default_uams_mask) + DEFINE_METHOD0(char *, get_uam_names_list) + + DEFINE_METHOD1(void, libafpclient_register, (struct libafpclient *p1)) + DEFINE_METHOD1(int, afp_main_quick_startup, (pthread_t *p1)) + DEFINE_METHOD1(int, afp_unmount_all_volumes, (struct afp_server *p1)) + DEFINE_METHOD1(int, afp_unmount_volume, (struct afp_volume *p1)) + DEFINE_METHOD1(unsigned int, find_uam_by_name, (const char *p1)) + DEFINE_METHOD1(char *, uam_bitmap_to_string, (unsigned int p1)) + DEFINE_METHOD1(void, afp_default_url, (struct afp_url *p1)) + DEFINE_METHOD1(void, afp_ml_filebase_free, (struct afp_file_info **p1)) + +#ifdef USE_CVS_AFPFS + DEFINE_METHOD3(struct afp_server *, afp_wrap_server_full_connect, (void *p1, struct afp_connection_request *p2, int *p3)) +#else + DEFINE_METHOD2(struct afp_server *, afp_wrap_server_full_connect, (void *p1, struct afp_connection_request *p2)) +#endif + + DEFINE_METHOD2(struct afp_volume *, find_volume_by_name, (struct afp_server *p1, const char *p2)) + DEFINE_METHOD2(int, afp_wrap_unlink, (struct afp_volume *p1, const char *p2)) + DEFINE_METHOD2(int, afp_wrap_rmdir, (struct afp_volume *p1, const char *p2)) + + DEFINE_METHOD3(int, afp_parse_url, (struct afp_url *p1, const char *p2, int p3)) + DEFINE_METHOD3(int, afp_wrap_close, (struct afp_volume *p1, const char *p2, struct afp_file_info *p3)) + DEFINE_METHOD3(int, afp_wrap_getattr, (struct afp_volume *p1, const char *p2, struct stat *p3)) + DEFINE_METHOD3(int, afp_wrap_rename, (struct afp_volume *p1, const char *p2, const char *p3)) + DEFINE_METHOD3(int, afp_wrap_creat, (struct afp_volume *p1, const char *p2, mode_t p3)) + DEFINE_METHOD3(int, afp_wrap_readdir, (struct afp_volume *p1, const char *p2, struct afp_file_info **p3)) + DEFINE_METHOD3(int, afp_wrap_mkdir, (struct afp_volume *p1, const char *p2, mode_t p3)) + + DEFINE_METHOD4(int, afp_wrap_open, (struct afp_volume *p1, const char *p2, int p3, struct afp_file_info **p4)) + DEFINE_METHOD4(int, afp_wrap_readlink, (struct afp_volume *p1, const char *p2, char *p3, size_t p4)) + + DEFINE_METHOD5(int, afp_connect_volume, (struct afp_volume *p1, struct afp_server *p2, char *p3, unsigned int *p4, unsigned int p5)) + + DEFINE_METHOD7(int, afp_wrap_read, (struct afp_volume *p1, const char *p2, char *p3, size_t p4, off_t p5, struct afp_file_info *p6, int *p7)) + + DEFINE_METHOD8(int, afp_wrap_write, (struct afp_volume *p1, const char *p2, const char *p3, size_t p4, off_t p5, struct afp_file_info *p6, uid_t p7, gid_t p8)) + + + + BEGIN_METHOD_RESOLVE() + RESOLVE_METHOD_RENAME(init_uams,init_uams) + RESOLVE_METHOD_RENAME(libafpclient_register, libafpclient_register) + RESOLVE_METHOD_RENAME(afp_main_quick_startup, afp_main_quick_startup) + RESOLVE_METHOD_RENAME(afp_unmount_all_volumes, afp_unmount_all_volumes) + RESOLVE_METHOD_RENAME(afp_unmount_all_volumes, afp_unmount_all_volumes) + RESOLVE_METHOD_RENAME(find_volume_by_name, find_volume_by_name) + RESOLVE_METHOD_RENAME(afp_connect_volume, afp_connect_volume) + RESOLVE_METHOD_RENAME(afp_parse_url, afp_parse_url) + RESOLVE_METHOD_RENAME(find_uam_by_name, find_uam_by_name) + RESOLVE_METHOD_RENAME(default_uams_mask, default_uams_mask) + RESOLVE_METHOD_RENAME(uam_bitmap_to_string, uam_bitmap_to_string) + RESOLVE_METHOD_RENAME(afp_default_url, afp_default_url) + RESOLVE_METHOD_RENAME(get_uam_names_list, get_uam_names_list) + RESOLVE_METHOD_RENAME(afp_ml_filebase_free, afp_ml_filebase_free) + +#ifdef USE_CVS_AFPFS + RESOLVE_METHOD_RENAME(afp_server_full_connect, afp_server_full_connect) + RESOLVE_METHOD_RENAME(afp_ml_open, afp_ml_open) + RESOLVE_METHOD_RENAME(afp_ml_close, afp_ml_close) + RESOLVE_METHOD_RENAME(afp_ml_read, afp_ml_read) + RESOLVE_METHOD_RENAME(afp_ml_write, afp_ml_write) + RESOLVE_METHOD_RENAME(afp_ml_getattr, afp_ml_getattr) + RESOLVE_METHOD_RENAME(afp_ml_unlink, afp_ml_unlink) + RESOLVE_METHOD_RENAME(afp_ml_rename, afp_ml_rename) + RESOLVE_METHOD_RENAME(afp_ml_creat, afp_ml_creat) + RESOLVE_METHOD_RENAME(afp_ml_readdir, afp_ml_readdir) + RESOLVE_METHOD_RENAME(afp_ml_readlink, afp_ml_readlink) + RESOLVE_METHOD_RENAME(afp_ml_mkdir, afp_ml_mkdir) + RESOLVE_METHOD_RENAME(afp_ml_rmdir, afp_ml_rmdir) +#else + RESOLVE_METHOD_RENAME(afp_server_full_connect, afp_server_full_connect) + RESOLVE_METHOD_RENAME(ml_open, ml_open) + RESOLVE_METHOD_RENAME(ml_close, ml_close) + RESOLVE_METHOD_RENAME(ml_read, ml_read) + RESOLVE_METHOD_RENAME(ml_write, ml_write) + RESOLVE_METHOD_RENAME(ml_getattr, ml_getattr) + RESOLVE_METHOD_RENAME(ml_unlink, ml_unlink) + RESOLVE_METHOD_RENAME(ml_rename, ml_rename) + RESOLVE_METHOD_RENAME(ml_creat, ml_creat) + RESOLVE_METHOD_RENAME(ml_readdir, ml_readdir) + RESOLVE_METHOD_RENAME(ml_readlink, ml_readlink) + RESOLVE_METHOD_RENAME(ml_mkdir, ml_mkdir) + RESOLVE_METHOD_RENAME(ml_rmdir, ml_rmdir) +#endif + END_METHOD_RESOLVE() +}; diff --git a/xbmc/filesystem/FileFactory.cpp b/xbmc/filesystem/FileFactory.cpp index 1cba8a2..08bec90 100644 --- a/xbmc/filesystem/FileFactory.cpp +++ b/xbmc/filesystem/FileFactory.cpp @@ -67,6 +67,9 @@ #ifdef HAS_FILESYSTEM_NFS #include "NFSFile.h" #endif +#ifdef HAS_FILESYSTEM_AFP +#include "AFPFile.h" +#endif #if defined(TARGET_ANDROID) #include "AndroidAppFile.h" #endif @@ -177,6 +180,9 @@ IFile* CFileFactory::CreateLoader(const CURL& url) #ifdef HAS_FILESYSTEM_NFS else if (url.IsProtocol("nfs")) return new CNFSFile(); #endif +#ifdef HAS_FILESYSTEM_AFP + else if (url.IsProtocol("afp")) return new CAFPFile(); +#endif #ifdef HAS_UPNP else if (url.IsProtocol("upnp")) return new CUPnPFile(); #endif diff --git a/xbmc/filesystem/Makefile.in b/xbmc/filesystem/Makefile.in index d7a9bed..128bc1d 100644 --- a/xbmc/filesystem/Makefile.in +++ b/xbmc/filesystem/Makefile.in @@ -100,6 +100,11 @@ SRCS += NFSFile.cpp SRCS += NFSDirectory.cpp endif +ifeq (@USE_LIBAFPCLIENT@,1) +SRCS += AFPFile.cpp +SRCS += AFPDirectory.cpp +endif + ifeq (@HAVE_LIBBLURAY@,1) SRCS += BlurayDirectory.cpp SRCS += BlurayFile.cpp diff --git a/xbmc/filesystem/ZeroconfDirectory.cpp b/xbmc/filesystem/ZeroconfDirectory.cpp index 666bb9e..e539b1a 100644 --- a/xbmc/filesystem/ZeroconfDirectory.cpp +++ b/xbmc/filesystem/ZeroconfDirectory.cpp @@ -52,6 +52,8 @@ namespace return "WebDAV"; else if(fcr_service_type == "_nfs._tcp.") return "NFS"; + else if(fcr_service_type == "_afpovertcp._tcp.") + return "AFP"; else if(fcr_service_type == "_sftp-ssh._tcp.") return "SFTP"; //fallback, just return the received type @@ -67,6 +69,8 @@ namespace fr_protocol = "dav"; else if(fcr_service_type == "_nfs._tcp.") fr_protocol = "nfs"; + else if(fcr_service_type == "_afpovertcp._tcp.") + fr_protocol = "afp"; else if(fcr_service_type == "_sftp-ssh._tcp.") fr_protocol = "sftp"; else diff --git a/xbmc/network/GUIDialogNetworkSetup.cpp b/xbmc/network/GUIDialogNetworkSetup.cpp index 206c597..85930ce 100644 --- a/xbmc/network/GUIDialogNetworkSetup.cpp +++ b/xbmc/network/GUIDialogNetworkSetup.cpp @@ -134,6 +134,9 @@ void CGUIDialogNetworkSetup::OnInitWindow() #ifdef HAS_FILESYSTEM_SFTP labels.push_back(make_pair(g_localizeStrings.Get(20260), NET_PROTOCOL_SFTP)); #endif +#ifdef HAS_FILESYSTEM_AFP + labels.push_back(make_pair(g_localizeStrings.Get(20261), NET_PROTOCOL_AFP)); +#endif SET_CONTROL_LABELS(CONTROL_PROTOCOL, m_protocol, &labels); UpdateButtons(); @@ -272,7 +275,8 @@ void CGUIDialogNetworkSetup::UpdateButtons() m_protocol == NET_PROTOCOL_DAV || m_protocol == NET_PROTOCOL_DAVS || m_protocol == NET_PROTOCOL_RSS || - m_protocol == NET_PROTOCOL_SFTP)); + m_protocol == NET_PROTOCOL_SFTP || + m_protocol == NET_PROTOCOL_AFP)); } std::string CGUIDialogNetworkSetup::ConstructPath() const @@ -298,6 +302,8 @@ std::string CGUIDialogNetworkSetup::ConstructPath() const url.SetProtocol("nfs"); else if (m_protocol == NET_PROTOCOL_SFTP) url.SetProtocol("sftp"); + else if (m_protocol == NET_PROTOCOL_AFP) + url.SetProtocol("afp"); if (!m_username.empty()) { @@ -347,6 +353,8 @@ void CGUIDialogNetworkSetup::SetPath(const std::string &path) m_protocol = NET_PROTOCOL_NFS; else if (url.IsProtocol("sftp") || url.IsProtocol("ssh")) m_protocol = NET_PROTOCOL_SFTP; + else if (url.IsProtocol("afp")) + m_protocol = NET_PROTOCOL_AFP; else m_protocol = NET_PROTOCOL_SMB; // default to smb m_username = url.GetUserName(); diff --git a/xbmc/network/GUIDialogNetworkSetup.h b/xbmc/network/GUIDialogNetworkSetup.h index e4bc8e3..c059447 100644 --- a/xbmc/network/GUIDialogNetworkSetup.h +++ b/xbmc/network/GUIDialogNetworkSetup.h @@ -36,7 +36,8 @@ public: NET_PROTOCOL_UPNP, NET_PROTOCOL_RSS, NET_PROTOCOL_SFTP, - NET_PROTOCOL_NFS}; + NET_PROTOCOL_NFS, + NET_PROTOCOL_AFP}; CGUIDialogNetworkSetup(void); virtual ~CGUIDialogNetworkSetup(void); virtual bool OnMessage(CGUIMessage& message); diff --git a/xbmc/network/ZeroconfBrowser.cpp b/xbmc/network/ZeroconfBrowser.cpp index 4b55bda..d96a135 100644 --- a/xbmc/network/ZeroconfBrowser.cpp +++ b/xbmc/network/ZeroconfBrowser.cpp @@ -61,6 +61,9 @@ CZeroconfBrowser::CZeroconfBrowser():mp_crit_sec(new CCriticalSection),m_started #ifdef HAS_FILESYSTEM_NFS AddServiceType("_nfs._tcp."); #endif// HAS_FILESYSTEM_NFS +#ifdef HAS_FILESYSTEM_AFP + AddServiceType("_afpovertcp._tcp."); +#endif AddServiceType("_sftp-ssh._tcp."); } diff --git a/xbmc/system.h b/xbmc/system.h index 5225518..a008730 100644 --- a/xbmc/system.h +++ b/xbmc/system.h @@ -61,6 +61,10 @@ #define HAS_FILESYSTEM_NFS #endif +#ifdef HAVE_LIBAFPCLIENT + #define HAS_FILESYSTEM_AFP +#endif + #ifdef HAVE_LIBPLIST #define HAS_AIRPLAY #endif diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp index 16a846a..b0f1b2b 100644 --- a/xbmc/utils/URIUtils.cpp +++ b/xbmc/utils/URIUtils.cpp @@ -1000,6 +1000,22 @@ bool URIUtils::IsNfs(const std::string& strFile) return IsProtocol(strFile, "nfs"); } +bool URIUtils::IsAfp(const std::string& strFile) +{ + if (IsStack(strFile)) + return IsAfp(CStackDirectory::GetFirstStackedFile(strFile)); + + if (IsSpecial(strFile)) + return IsAfp(CSpecialProtocol::TranslatePath(strFile)); + + CURL url(strFile); + if (HasParentInHostname(url)) + return IsAfp(url.GetHostName()); + + return IsProtocol(strFile, "afp"); +} + + bool URIUtils::IsVideoDb(const std::string& strFile) { return IsProtocol(strFile, "videodb"); diff --git a/xbmc/utils/URIUtils.h b/xbmc/utils/URIUtils.h index 257b8e2..96e2c8b 100644 --- a/xbmc/utils/URIUtils.h +++ b/xbmc/utils/URIUtils.h @@ -142,6 +142,7 @@ public: static bool IsMultiPath(const std::string& strPath); static bool IsMusicDb(const std::string& strFile); static bool IsNfs(const std::string& strFile); + static bool IsAfp(const std::string& strFile); static bool IsOnDVD(const std::string& strFile); static bool IsOnLAN(const std::string& strFile); static bool IsHostOnLAN(const std::string& hostName, bool offLineCheck = false); diff --git a/xbmc/utils/test/TestURIUtils.cpp b/xbmc/utils/test/TestURIUtils.cpp index 1eb49a5..be7c83d 100644 --- a/xbmc/utils/test/TestURIUtils.cpp +++ b/xbmc/utils/test/TestURIUtils.cpp @@ -333,6 +333,12 @@ TEST_F(TestURIUtils, IsNfs) EXPECT_TRUE(URIUtils::IsNfs("stack://nfs://path/to/file")); } +TEST_F(TestURIUtils, IsAfp) +{ + EXPECT_TRUE(URIUtils::IsAfp("afp://path/to/file")); + EXPECT_TRUE(URIUtils::IsAfp("stack://afp://path/to/file")); +} + TEST_F(TestURIUtils, IsOnDVD) { EXPECT_TRUE(URIUtils::IsOnDVD("dvd://path/to/file")); -- 2.7.1 From 09c822e60252174f4f04c7ad51ae6f21a40806c0 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 25 Aug 2015 05:02:33 +0200 Subject: [PATCH 094/250] DVDPlayer: also don't force ffmpeg as decoder for .iso when compiled for IMX Upstream-commit: d27c6dcdf4a79e443aabe57aaaf22b4d6f96a354 --- xbmc/cores/dvdplayer/DVDPlayer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp index 4ffe33a..2093f46 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -3501,7 +3501,9 @@ bool CDVDPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset) hint.aspect = aspect; hint.forced_aspect = true; } +#if !defined(TARGET_RASPBERRY_PI) && !defined(HAS_IMXVPU) hint.software = true; +#endif } else if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER)) { -- 2.7.1 From a48b7d7476854d0398e30b5807810e7334be7925 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 25 Aug 2015 06:44:16 +0200 Subject: [PATCH 095/250] DVDVideoCodecIMX: don't deinterlace if screen is configured with interlaced resolution Upstream-commit: 1f93c251effb0900f20dfc6984e32272cfbf468c --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index a8b1f8a..ac63da7 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1397,6 +1397,7 @@ bool CIMXContext::AdaptScreen() m_fbWidth = fbVar.xres; m_fbHeight = fbVar.yres; + m_fbInterlaced = fbVar.vmode & FB_VMODE_INTERLACED; if (!GetFBInfo(m_deviceName, &m_fbVar)) goto Err; @@ -1418,6 +1419,11 @@ bool CIMXContext::AdaptScreen() m_fbVar.xres = m_fbWidth; m_fbVar.yres = m_fbHeight; + if (m_fbInterlaced) + m_fbVar.vmode |= FB_VMODE_INTERLACED; + else + m_fbVar.vmode &= ~FB_VMODE_INTERLACED; + m_fbVar.yres_virtual = (m_fbVar.yres + 0) * m_fbPages; m_fbVar.xres_virtual = m_fbVar.xres; @@ -1561,6 +1567,8 @@ void CIMXContext::SetFieldData(uint8_t fieldFmt) if (m_bStop || !IsRunning()) return; + fieldFmt &= -!m_fbInterlaced; + // disable deinterlacing when not rendering fullscreen if (!g_graphicsContext.IsFullScreenVideo()) fieldFmt = 0; -- 2.7.1 From b8f7b48fb78426fb40cdb5183ec001d82798b3e1 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 30 Aug 2015 03:17:11 +0200 Subject: [PATCH 096/250] AESinkALSA: don't error on -EPIPE (buffer underrun) Upstream-commit: 91730ab5d6248950cd5ad7ce6d451f3d120312a6 --- xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp index e22db7a..21b4b6e 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp @@ -927,7 +927,7 @@ unsigned int CAESinkALSA::AddPackets(uint8_t **data, unsigned int frames, unsign int ret = snd_pcm_writei(m_pcm, buffer, amount); if (ret < 0) { - CLog::Log(LOGERROR, "CAESinkALSA - snd_pcm_writei(%d) %s - trying to recover", ret, snd_strerror(ret)); + CLog::Log(ret == -32 ? LOGDEBUG : LOGERROR, "CAESinkALSA - snd_pcm_writei(%d) %s - trying to recover", ret, snd_strerror(ret)); ret = snd_pcm_recover(m_pcm, ret, 1); if(ret < 0) { -- 2.7.1 From ce9586fc986e8fbfae746a5c1318499e2edef8a9 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 30 Aug 2015 05:19:46 +0200 Subject: [PATCH 097/250] Poweroff / on imx gpu when appropriate: - if screen output is made inactive (CEC source is no longer active source, or TV is powered off) - screensaver black is active Upstream-commit: 183b3a1ac6dad8a0eeefe0af3ef8c3bc3b5d3d63 --- .../resource.language.en_gb/resources/strings.po | 13 +++++++++++++ system/settings/imx6.xml | 3 +++ system/settings/settings.xml | 9 +++++++++ xbmc/Application.cpp | 22 ++++++++++++++++++++-- xbmc/Application.h | 1 + xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 2 ++ 6 files changed, 48 insertions(+), 2 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index a496be8..de793fa 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -18159,3 +18159,16 @@ msgstr "" msgctxt "#40002" msgid "Detect hotplug events" msgstr "" + +#. Label of setting "System -> Video output -> Blank framebuffer" +#: system/settings/settings.xml +msgctxt "#40003" +msgid "Intelligently power off/on GPU to save power" +msgstr "" + +#. Description of setting "System -> Video output -> Blank framebuffer" +#: system/settings/settings.xml +msgctxt "#40004" +msgid "Kodi will powerdown the GPU (when not in use), thus provide significant powersavings. TV being powered OFF, Kodi no longer active source (CEC) or start of BlackScreensaver will trigger this action (HDMI Audio will be powered down too)" +msgstr "" + diff --git a/system/settings/imx6.xml b/system/settings/imx6.xml index 979a00b..43337ce 100644 --- a/system/settings/imx6.xml +++ b/system/settings/imx6.xml @@ -18,6 +18,9 @@ false + + true + diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 41bafb3..85274d2 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -2411,6 +2411,15 @@ + + 1 + false + false + + + + + diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 3da4a6c..886aabe 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -295,6 +295,7 @@ CApplication::CApplication(void) m_skinReverting = false; m_cecStandby = false; m_ourVT = -1; + m_selfBlanked = false; #ifdef HAS_GLX XInitThreads(); @@ -769,7 +770,7 @@ bool CApplication::CreateGUI(bool showXBMCSplash) // Initialize core peripheral port support. Note: If these parameters // are 0 and NULL, respectively, then the default number and types of // controllers will be initialized. - CDisplaySettings::Get().SetCurrentResolution((RESOLUTION)CSettings::Get().GetInt("videoscreen.resolution")); + CDisplaySettings::GetInstance().SetCurrentResolution((RESOLUTION)CSettings::GetInstance().GetInt("videoscreen.resolution")); if (!g_Windowing.InitWindowSystem()) { CLog::Log(LOGFATAL, "CApplication::Create: Unable to init windowing system"); @@ -1915,10 +1916,22 @@ void CApplication::SetCecStandby(bool status) CLog::Log(LOGDEBUG, "%s is %x, se %d, sa %d", __FUNCTION__, (int)status, m_screenSaver ? 1:0, m_bScreenSave); m_cecStandby = status; - if (g_application.m_bStop) + if (g_application.m_bStop || !g_windowManager.Initialized()) return; SetRenderGUI(!status); +#ifdef HAS_IMXVPU + if (status && CSettings::GetInstance().GetBool("videoscreen.blankcurrent")) + { + m_selfBlanked = true; + g_Windowing.Hide(); + } + else if (!status && m_selfBlanked) + { + m_selfBlanked = false; + g_Windowing.Show(); + } +#endif } void CApplication::Render() @@ -4045,6 +4058,9 @@ bool CApplication::WakeUpScreenSaverAndDPMS(bool bPowerOffKeyPressed /* = false CVariant data(CVariant::VariantTypeObject); data["shuttingdown"] = bPowerOffKeyPressed; CAnnouncementManager::GetInstance().Announce(GUI, "xbmc", "OnScreensaverDeactivated", data); + + if (m_screenSaver->ID() == "screensaver.xbmc.builtin.black") + SetCecStandby(false); #ifdef TARGET_ANDROID // Screensaver deactivated -> acquire wake lock CXBMCApp::EnableWakeLock(true); @@ -4191,6 +4207,8 @@ void CApplication::ActivateScreenSaver(bool forceType /*= false */) m_screenSaver.reset(new CScreenSaver("")); } } + if (m_screenSaver->ID() == "screensaver.xbmc.builtin.black") + SetCecStandby(true); if (m_screenSaver->ID() == "screensaver.xbmc.builtin.dim" || m_screenSaver->ID() == "screensaver.xbmc.builtin.black") { diff --git a/xbmc/Application.h b/xbmc/Application.h index 26f2fde..b391dda 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h @@ -425,6 +425,7 @@ protected: bool m_autoExecScriptExecuted; bool m_cecStandby; + bool m_selfBlanked; int m_ourVT; void checkVTchange(); diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index 68b359b..a999bad 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -182,6 +182,8 @@ void CPeripheralCecAdapter::Announce(AnnouncementFlag flag, const char *sender, // Don't put devices to standby if application is currently playing if ((!g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused()) && m_configuration.bPowerOffScreensaver == 1) { + if (!(CEC_POWER_STATUS_ON == m_cecAdapter->GetDevicePowerStatus(CECDEVICE_TV) && m_cecAdapter->IsLibCECActiveSource())) + g_screen.SetOff(); // only power off when we're the active source if (m_cecAdapter->IsLibCECActiveSource()) StandbyDevices(); -- 2.7.1 From c66288c525f7521ce6bc9ae384af66dfa2519041 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 30 Aug 2015 10:43:28 +0200 Subject: [PATCH 098/250] WinSystem: Don't exclude RES_DESKTOP resolution from sort. (do not stay on top of list) Upstream-commit: b6042cd37f18af2b59f08a7215772327373ecc2e --- xbmc/windowing/WinSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/windowing/WinSystem.cpp b/xbmc/windowing/WinSystem.cpp index b8be750..5d67639 100644 --- a/xbmc/windowing/WinSystem.cpp +++ b/xbmc/windowing/WinSystem.cpp @@ -180,7 +180,7 @@ std::vector CWinSystemBase::ScreenResolutions(int screen, float // Can't assume a sort order // don't touch RES_DESKTOP which is index 0 - sort(resolutions.begin()+1, resolutions.end(), resSortPredicate); + sort(resolutions.begin()+0, resolutions.end(), resSortPredicate); return resolutions; } -- 2.7.1 From 4030f61676750d943358becb0ebff278203dc8bc Mon Sep 17 00:00:00 2001 From: fritsch Date: Fri, 8 May 2015 12:24:15 +0200 Subject: [PATCH 099/250] Use dcadec on IMX and RPI - move setting to audio output Upstream-commit: 3600cd9e2d08a769d1ed33e7217583af9a217b72 --- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 88d486b..cc62a1e 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -445,6 +445,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo, bool filein if (m_streaminfo) { for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) + if (CSettings::Get().GetBool("audiooutput.supportdtshdcpudecoding")) { AVStream *st = m_pFormatContext->streams[i]; if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == AV_CODEC_ID_DTS) -- 2.7.1 From e4df4ce591a524c011260ef781ab2ff4cd50680c Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 1 Sep 2015 15:14:53 +0200 Subject: [PATCH 100/250] keymaps: mouse: it looks wheelup/down is triggering horizontal movement in kodi. as most menus are vertical, wheel works at home screen only. Upstream-commit: af4a01e11e21d467739398912882ee1455b1f2bc this remaps wheelup/down to up/down everywhere but [HOME] --- system/keymaps/mouse.xml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/system/keymaps/mouse.xml b/system/keymaps/mouse.xml index c2b39f8..488de69 100644 --- a/system/keymaps/mouse.xml +++ b/system/keymaps/mouse.xml @@ -7,6 +7,12 @@ + + + wheeldown + wheelup + + leftclick @@ -15,8 +21,8 @@ doubleclick contextmenu - wheeldown - wheelup + down + up mousedrag mousemove -- 2.7.1 From 8b93343e252ea11878eebbc86f3990af33c20ef5 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 1 Sep 2015 19:20:46 +0200 Subject: [PATCH 101/250] ffmpeg: compile - specify pkg-config to don't fail configure on gnutls not found. ffmpeg autoconfigure.sh + Makefile adapt --- ...Signal-unsupported-GMC-with-more-than-one.patch | 48 +++++++++++++++++++ tools/depends/target/ffmpeg/Makefile | 19 ++++++-- tools/depends/target/ffmpeg/autobuild.sh | 6 ++- .../ffmpeg_Speed_up_wtv_index_creation.patch | 47 ++++++++++++++++++ tools/depends/target/ffmpeg/no_rpi.patch | 56 ---------------------- 5 files changed, 113 insertions(+), 63 deletions(-) create mode 100644 tools/depends/target/ffmpeg/0001-mpeg4video-Signal-unsupported-GMC-with-more-than-one.patch create mode 100644 tools/depends/target/ffmpeg/ffmpeg_Speed_up_wtv_index_creation.patch delete mode 100644 tools/depends/target/ffmpeg/no_rpi.patch diff --git a/tools/depends/target/ffmpeg/0001-mpeg4video-Signal-unsupported-GMC-with-more-than-one.patch b/tools/depends/target/ffmpeg/0001-mpeg4video-Signal-unsupported-GMC-with-more-than-one.patch new file mode 100644 index 0000000..4cb8dd8 --- /dev/null +++ b/tools/depends/target/ffmpeg/0001-mpeg4video-Signal-unsupported-GMC-with-more-than-one.patch @@ -0,0 +1,48 @@ +From 84e9a1784bbd3182b68cefa5e5feae8da8b9e184 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 5 Jun 2015 22:48:33 +0100 +Subject: [PATCH] mpeg4video: Signal unsupported GMC with more than one warp + point + +--- + libavcodec/avcodec.h | 1 + + libavcodec/mpeg4videodec.c | 4 ++++ + 2 files changed, 5 insertions(+) + +diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h +index 8c7c420..e63dc2d 100644 +--- a/libavcodec/avcodec.h ++++ b/libavcodec/avcodec.h +@@ -2527,6 +2527,7 @@ typedef struct AVCodecContext { + #define FF_BUG_DC_CLIP 4096 + #define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders. + #define FF_BUG_TRUNCATED 16384 ++#define FF_BUG_GMC_UNSUPPORTED 32768 + + /** + * strictly follow the standard (MPEG4, ...). +diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c +index 9bf33dd..0b5d3b9 100644 +--- a/libavcodec/mpeg4videodec.c ++++ b/libavcodec/mpeg4videodec.c +@@ -2179,6 +2179,9 @@ int ff_mpeg4_workaround_bugs(AVCodecContext *avctx) + + if (ctx->divx_version >= 0) + s->workaround_bugs |= FF_BUG_HPEL_CHROMA; ++ ++ if (ctx->num_sprite_warping_points > 1) ++ s->workaround_bugs |= FF_BUG_GMC_UNSUPPORTED; + } + + if (s->workaround_bugs & FF_BUG_STD_QPEL) { +@@ -2203,6 +2206,7 @@ int ff_mpeg4_workaround_bugs(AVCodecContext *avctx) + s->workaround_bugs, ctx->lavc_build, ctx->xvid_build, + ctx->divx_version, ctx->divx_build, s->divx_packed ? "p" : ""); + ++ avctx->workaround_bugs = s->workaround_bugs; + if (CONFIG_MPEG4_DECODER && ctx->xvid_build >= 0 && + s->codec_id == AV_CODEC_ID_MPEG4 && + avctx->idct_algo == FF_IDCT_AUTO) { +-- +1.9.1 + diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile index 127ee9c..823f9c5 100644 --- a/tools/depends/target/ffmpeg/Makefile +++ b/tools/depends/target/ffmpeg/Makefile @@ -1,6 +1,12 @@ include FFMPEG-VERSION + +PLATFORM = ffmpeg-$(VERSION) +RETRIEVE_TOOL = curl +TARBALLS_LOCATION = $(shell pwd) +ARCHIVE_TOOL = tar +ARCHIVE_TOOL_FLAGS = --strip-components=1 -xf + DEPS= ../../Makefile.include FFMPEG-VERSION Makefile ffmpeg_Speed_up_wtv_index_creation.patch \ - 0001-avcodec-add-libdcadec-decoder.patch 0002-avcodec-Fix-libdcadec-include-dir.patch 0003-avcodec-add-profile-define-for-DTS-Express.patch \ 0001-mpeg4video-Signal-unsupported-GMC-with-more-than-one.patch # set to "yes" to enable patching @@ -19,8 +25,8 @@ ffmpg_config += --enable-muxer=spdif --enable-muxer=adts ffmpg_config += --enable-muxer=asf --enable-muxer=ipod ffmpg_config += --enable-encoder=ac3 --enable-encoder=aac ffmpg_config += --enable-encoder=wmav2 --enable-protocol=http +ffmpg_config += --pkg-config=/usr/bin/pkg-config ffmpg_config += --enable-gnutls -ffmpg_config += --enable-libdcadec ifeq ($(CROSS_COMPILING), yes) ffmpg_config += --arch=$(CPU) --enable-cross-compile @@ -45,9 +51,8 @@ ifeq ($(OS), ios) endif ifeq ($(OS), osx) ffmpg_config += --disable-outdev=sdl - ffmpg_config += --disable-decoder=mpeg_xvmc --enable-vda --disable-crystalhd --disable-videotoolbox + ffmpg_config += --disable-decoder=mpeg_xvmc --enable-vda --disable-crystalhd ffmpg_config += --target-os=darwin - ffmpg_config += --disable-securetransport endif ifeq ($(findstring arm, $(CPU)), arm) ffmpg_config += --enable-pic --disable-armv5te --disable-armv6t2 @@ -58,7 +63,7 @@ endif ifeq ($(Configuration), Release) ffmpg_config += --disable-debug endif - +ffmpg_config += --enable-libdcadec ffmpg_config += $(CONFFLAGS) @@ -73,6 +78,10 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS) rm -rf $(PLATFORM); mkdir -p $(PLATFORM) cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) cd $(PLATFORM); sed -i".bak" -e "s%pkg_config_default=pkg-config%export PKG_CONFIG_LIBDIR=$(PREFIX)/lib/pkgconfig \&\& pkg_config_default=$(NATIVEPREFIX)/bin/pkg-config%" configure + cd $(PLATFORM); patch -p1 < ../ffmpeg_Speed_up_wtv_index_creation.patch + cd $(PLATFORM); patch -p1 < ../0001-mpeg4video-Signal-unsupported-GMC-with-more-than-one.patch + ##cd $(PLATFORM); patch -p1 < ../0001-libavformat-add-mvcC-handling-in-.mov-.mp4.patch + ##cd $(PLATFORM); patch -p1 < ../0001-Discard-data-before-VO-VOL-in-mpeg-4-over-mpegts.patch cd $(PLATFORM);\ CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" \ ./configure $(ffmpg_config) diff --git a/tools/depends/target/ffmpeg/autobuild.sh b/tools/depends/target/ffmpeg/autobuild.sh index e0161b5..255d3ce 100755 --- a/tools/depends/target/ffmpeg/autobuild.sh +++ b/tools/depends/target/ffmpeg/autobuild.sh @@ -72,6 +72,7 @@ do ;; --arch=*) FLAGS="$FLAGS --arch=${1#*=}" + ARCH=${1#*=} shift ;; --extra-cflags=*) @@ -100,7 +101,8 @@ do esac done -FLAGS="$FLAGS --target-os=linux" +[ -n ${ARCH} ] || ARCH=$(dpkg-architecture -qDEB_BUILD_GNU_CPU) +[ ${ARCH} = $(dpkg-architecture -qDEB_BUILD_GNU_CPU) ] || FLAGS="$FLAGS --enable-cross-compile" BUILDTHREADS=${BUILDTHREADS:-$(grep -c "^processor" /proc/cpuinfo)} [ ${BUILDTHREADS} -eq 0 ] && BUILDTHREADS=1 @@ -112,7 +114,7 @@ then [ "$VERSION" == "$CURVER" ] && exit 0 fi -CFLAG="$CFLAGS" CXXFLAGS="$CXXFLAGS" LDFLAGS="$LDFLAGS" PLATFORM=ffmpeg-${VERSION} CONFFLAGS=${FLAGS} PREFIX=${FFMPEG_PREFIX} make -j ${BUILDTHREADS} +CFLAG="$CFLAGS" CPPFLAGS="$CFLAGS" ARCH=$ARCH CXXFLAGS="$CXXFLAGS" LDFLAGS="$LDFLAGS" PLATFORM=ffmpeg-${VERSION} CONFFLAGS=${FLAGS} PREFIX=${FFMPEG_PREFIX} make -j ${BUILDTHREADS} exit $? [ -f ${ARCHIVE} ] || curl -Ls --create-dirs -f -o ${ARCHIVE} ${BASE_URL}/${VERSION}.tar.gz diff --git a/tools/depends/target/ffmpeg/ffmpeg_Speed_up_wtv_index_creation.patch b/tools/depends/target/ffmpeg/ffmpeg_Speed_up_wtv_index_creation.patch new file mode 100644 index 0000000..d829898 --- /dev/null +++ b/tools/depends/target/ffmpeg/ffmpeg_Speed_up_wtv_index_creation.patch @@ -0,0 +1,47 @@ +commit 0e7427498cb1131671f6fe9d054245ae7e5a36f5 +Author: popcornmix +Date: Tue Mar 25 19:43:07 2014 +0000 + + [ffmpeg] Speed up wtv index creation + + The index creation is O(N^2) with number of entries (typically thousands). + On a Pi this can take more than 60 seconds to execute for a recording of a few hours. + + By replacing with an O(N) loop, this takes virtually zero time + +diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c +index e423370..70898bd 100644 +--- a/libavformat/wtvdec.c ++++ b/libavformat/wtvdec.c +@@ -980,21 +980,23 @@ static int read_header(AVFormatContext *s) + pb = wtvfile_open(s, root, root_size, ff_timeline_table_0_entries_Events_le16); + if (pb) { + int i; ++ AVIndexEntry *e = wtv->index_entries; ++ AVIndexEntry *e_end = wtv->index_entries + wtv->nb_index_entries - 1; ++ uint64_t last_position = 0; + while (1) { + uint64_t frame_nb = avio_rl64(pb); + uint64_t position = avio_rl64(pb); ++ while (frame_nb > e->size && e <= e_end) { ++ e->pos = last_position; ++ e++; ++ } + if (avio_feof(pb)) + break; +- for (i = wtv->nb_index_entries - 1; i >= 0; i--) { +- AVIndexEntry *e = wtv->index_entries + i; +- if (frame_nb > e->size) +- break; +- if (position > e->pos) +- e->pos = position; +- } ++ last_position = position; + } ++ e_end->pos = last_position; + wtvfile_close(pb); +- st->duration = wtv->index_entries[wtv->nb_index_entries - 1].timestamp; ++ st->duration = e_end->timestamp; + } + } + } diff --git a/tools/depends/target/ffmpeg/no_rpi.patch b/tools/depends/target/ffmpeg/no_rpi.patch deleted file mode 100644 index 845695d..0000000 --- a/tools/depends/target/ffmpeg/no_rpi.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- a/libavcodec/Makefile 2015-05-31 10:55:01.494795804 +0200 -+++ b/libavcodec/Makefile 2015-05-31 10:55:16.462530460 +0200 -@@ -4,10 +4,6 @@ - - HEADERS = avcodec.h \ - avfft.h \ -- rpi_qpu.h \ -- rpi_shader.h \ -- rpi_mailbox.h \ -- rpi_hevc_transform.h \ - dv_profile.h \ - dxva2.h \ - old_codec_ids.h \ -@@ -37,9 +33,6 @@ - resample.o \ - resample2.o \ - utils.o \ -- rpi_qpu.o \ -- rpi_shader.o \ -- rpi_mailbox.o \ - vorbis_parser.o \ - xiph.o \ - ---- a/libavcodec/hevc.h 2015-05-31 10:29:34.000000000 +0200 -+++ b/libavcodec/hevc.h 2015-05-31 11:04:26.486341721 +0200 -@@ -37,7 +37,7 @@ - #include "videodsp.h" - - // define RPI to split the CABAC/prediction/transform into separate stages --#define RPI -+//#define RPI - - #ifdef RPI - ---- a/libavcodec/utils.c 2015-05-31 10:29:34.000000000 +0200 -+++ b/libavcodec/utils.c 2015-05-31 11:13:05.543108709 +0200 -@@ -26,7 +26,7 @@ - */ - - // Move video buffers to GPU memory --#define RPI_GPU_BUFFERS -+//#define RPI_GPU_BUFFERS - - #include "config.h" - #include "libavutil/atomic.h" ---- a/libavcodec/rpi_qpu.c 2015-06-14 00:13:13.000000000 +0200 -+++ b/libavcodec/rpi_qpu.c 2015-06-14 00:44:50.203459910 +0200 -@@ -4,7 +4,7 @@ - // define RPI_TIME_TOTAL_VPU to print out how much time is spent in the VPI code - //#define RPI_TIME_TOTAL_VPU - // define RPI_ASYNC to run the VPU in a separate thread, need to make a separate call to check for completion --#define RPI_ASYNC -+//#define RPI_ASYNC - - #include - #include -- 2.7.1 From ea39c471214976e9d39e9f7d6aa9ac0a6e9efb81 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 2 Sep 2015 01:59:38 +0200 Subject: [PATCH 102/250] SetCecStandby: take care of stopping/restarting reference clock thread. in case we keep it running it will 'accumulate' errors and tick misses and after wakeup (while trying to put things into order) it produces just unnecessary chaos (skips, pitch changes ...) Upstream-commit: 1bf160e0845c2024883cdd45308760b1a8787beb TODO: ReferenceClock should manage this on it's own (perhaps even on pause/play events). Try to fix that from this perspective. --- xbmc/Application.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 886aabe..5630d59 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -1913,6 +1913,8 @@ void CApplication::SetCecStandby(bool status) if (status == m_cecStandby) return; + static bool m_restartClock; + CLog::Log(LOGDEBUG, "%s is %x, se %d, sa %d", __FUNCTION__, (int)status, m_screenSaver ? 1:0, m_bScreenSave); m_cecStandby = status; @@ -1924,12 +1926,22 @@ void CApplication::SetCecStandby(bool status) if (status && CSettings::GetInstance().GetBool("videoscreen.blankcurrent")) { m_selfBlanked = true; + if (g_VideoReferenceClock.IsRunning()) + { + m_restartClock = true; + g_VideoReferenceClock.Stop(); + } g_Windowing.Hide(); } else if (!status && m_selfBlanked) { m_selfBlanked = false; g_Windowing.Show(); + if (m_restartClock) + { + m_restartClock = false; + g_VideoReferenceClock.Start(); + } } #endif } -- 2.7.1 From 29c624cd800968e308053f37f39ce9d618a57dea Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 2 Sep 2015 02:11:29 +0200 Subject: [PATCH 103/250] IMXCodec: don't update internal state itself in reconf() function. Unblank() is doing it already. Upstream-commit: d3b1567370735494b9ea9efb60f0a8940c31fde0 --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index ac63da7..792361e 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1449,7 +1449,6 @@ bool CIMXContext::AdaptScreen() Unblank(); - m_bFbIsConfigured = true; return true; Err: -- 2.7.1 From 09671fb151030bccf43702e6916796d35174f2f2 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 2 Sep 2015 02:13:13 +0200 Subject: [PATCH 104/250] IMXCodec lock moving Upstream-commit: 5734ef1d65af86021016c8f121187b6711deae67 --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 7 +++++-- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 6 ------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 792361e..8d6f7e5 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -41,7 +41,7 @@ #define IMX_VDI_MAX_WIDTH 968 #define FRAME_ALIGN 16 #define MEDIAINFO 1 -#define RENDER_QUEUE_SIZE 3 +#define RENDER_QUEUE_SIZE 5 #define _4CC(c1,c2,c3,c4) (((uint32_t)(c4)<<24)|((uint32_t)(c3)<<16)|((uint32_t)(c2)<<8)|(uint32_t)(c1)) #define Align(ptr,align) (((unsigned int)ptr + (align) - 1)/(align)*(align)) #define Align2(ptr,align) (((unsigned int)ptr)/(align)*(align)) @@ -1377,7 +1377,6 @@ void CIMXContext::MemMap(struct fb_fix_screeninfo *fb_fix) bool CIMXContext::AdaptScreen() { - CSingleLock lk(m_pageSwapLock); if(m_ipuHandle) { close(m_ipuHandle); @@ -1458,6 +1457,8 @@ Err: void CIMXContext::OnResetDevice() { + CSingleLock lk(m_pageSwapLock); + CLog::Log(LOGDEBUG, "iMX : %s - going to change screen parameters\n", __FUNCTION__); m_bFbIsConfigured = false; AdaptScreen(); @@ -1578,6 +1579,8 @@ void CIMXContext::SetFieldData(uint8_t fieldFmt) return; CLog::Log(LOGDEBUG, "iMX : Deinterlacing parameters changed (%s)\n", !!fieldFmt ? "active" : "not active"); + + CSingleLock lk(m_pageSwapLock); m_bFbIsConfigured = false; AdaptScreen(); } diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 426f774..e6e117c 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -390,12 +390,6 @@ bool CEGLNativeTypeIMX::ShowWindow(bool show) return true; CLog::Log(LOGDEBUG, ": %s %s", __FUNCTION__, show?"show":"hide"); - int fd; - if (m_show && (fd = open("/dev/fb0", O_RDWR))) - { - ioctl(fd, FBIO_WAITFORVSYNC, 0); - close(fd); - } SysfsUtils::SetInt("/sys/class/graphics/fb0/blank", show ? 0 : 1 ); m_show = show; -- 2.7.1 From 559a5c812c5c5e7635c8fde5a7c5fc60a488c152 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 3 Sep 2015 22:56:25 +0200 Subject: [PATCH 105/250] Fix wrong reading of cable states. Upstream-commit: 216c6eab00076537bfdb5c5cfd5f3309b2543281 --- xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp b/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp index b7eaab8..7687e5e 100644 --- a/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp +++ b/xbmc/peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.cpp @@ -110,9 +110,9 @@ int CPeripheralBusPLATFORM::GetCableState(const std::string &strLocation) if (udev_device_get_sysattr_value(dev, f->c_str())) t = udev_device_get_sysattr_value(dev, f->c_str()); - if (!t.empty() && (t.find("connected") != std::string::npos || t.find("plugout") != std::string::npos)) + if (!t.empty() && (t.find("disconnected") != std::string::npos || t.find("plugout") != std::string::npos)) state = CABLE_DISCONNECTED; - if (!t.empty() && (t.find("disconnected") != std::string::npos || t.find("plugin") != std::string::npos)) + if (!t.empty() && (t.find("connected") != std::string::npos || t.find("plugin") != std::string::npos)) state = CABLE_CONNECTED; if (state) -- 2.7.1 From 5f981271a5ca86f8caf21ee6293231d6f98c3222 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 3 Sep 2015 23:12:09 +0200 Subject: [PATCH 106/250] CecStandby: move all relevant code into single class. Upstream-commit: 217400a98cb1dd2d95e5247de9dca3b4b35a0103 --- xbmc/Application.cpp | 54 ++------- xbmc/Application.h | 5 - xbmc/messaging/ApplicationMessenger.h | 1 + xbmc/peripherals/Peripherals.cpp | 1 + xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 8 +- xbmc/peripherals/devices/PeripheralVideo.cpp | 15 ++- xbmc/utils/Makefile.in | 1 + xbmc/utils/Screen.cpp | 131 ++++++++++++++++++++++ xbmc/utils/Screen.h | 54 +++++++++ 9 files changed, 210 insertions(+), 60 deletions(-) create mode 100644 xbmc/utils/Screen.cpp create mode 100644 xbmc/utils/Screen.h diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 5630d59..f425a7d 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -234,6 +234,7 @@ #include "utils/CharsetConverter.h" #include "pictures/GUIWindowSlideShow.h" #include "windows/GUIWindowLoginScreen.h" +#include "utils/Screen.h" using namespace ADDON; using namespace XFILE; @@ -293,9 +294,7 @@ CApplication::CApplication(void) m_bPlaybackStarting = false; m_ePlayState = PLAY_STATE_NONE; m_skinReverting = false; - m_cecStandby = false; m_ourVT = -1; - m_selfBlanked = false; #ifdef HAS_GLX XInitThreads(); @@ -352,7 +351,7 @@ bool CApplication::OnEvent(XBMC_Event& newEvent) if (!g_application.m_bStop) { CApplicationMessenger::GetInstance().PostMsg(TMSG_QUIT); - g_application.SetCecStandby(false); + g_screen.SetOn(); } break; case XBMC_VIDEORESIZE: @@ -1908,44 +1907,6 @@ float CApplication::GetDimScreenSaverLevel() const return 100.0f; } -void CApplication::SetCecStandby(bool status) -{ - if (status == m_cecStandby) - return; - - static bool m_restartClock; - - CLog::Log(LOGDEBUG, "%s is %x, se %d, sa %d", __FUNCTION__, (int)status, m_screenSaver ? 1:0, m_bScreenSave); - - m_cecStandby = status; - if (g_application.m_bStop || !g_windowManager.Initialized()) - return; - - SetRenderGUI(!status); -#ifdef HAS_IMXVPU - if (status && CSettings::GetInstance().GetBool("videoscreen.blankcurrent")) - { - m_selfBlanked = true; - if (g_VideoReferenceClock.IsRunning()) - { - m_restartClock = true; - g_VideoReferenceClock.Stop(); - } - g_Windowing.Hide(); - } - else if (!status && m_selfBlanked) - { - m_selfBlanked = false; - g_Windowing.Show(); - if (m_restartClock) - { - m_restartClock = false; - g_VideoReferenceClock.Start(); - } - } -#endif -} - void CApplication::Render() { // do not render if we are stopped or in background @@ -2078,7 +2039,7 @@ void CApplication::Render() else flip = true; - flip &= !m_cecStandby; + flip &= !g_screen.GetScreenState(); //fps limiter, make sure each frame lasts at least singleFrameTime milliseconds if (limitFrames || !(flip || m_bPresentFrame)) @@ -2629,6 +2590,11 @@ void CApplication::OnApplicationMessage(ThreadMessage* pMsg) break; #endif + case TMSG_DISPLAY_RECONFIGURE: + g_Windowing.UpdateResolutions(); + g_graphicsContext.SetFullScreenVideo(g_graphicsContext.IsFullScreenVideo()); + break; + case TMSG_SETPVRMANAGERSTATE: if (pMsg->param1 != 0) StartPVRManager(); @@ -4072,7 +4038,7 @@ bool CApplication::WakeUpScreenSaverAndDPMS(bool bPowerOffKeyPressed /* = false CAnnouncementManager::GetInstance().Announce(GUI, "xbmc", "OnScreensaverDeactivated", data); if (m_screenSaver->ID() == "screensaver.xbmc.builtin.black") - SetCecStandby(false); + g_screen.SetOn(); #ifdef TARGET_ANDROID // Screensaver deactivated -> acquire wake lock CXBMCApp::EnableWakeLock(true); @@ -4219,8 +4185,6 @@ void CApplication::ActivateScreenSaver(bool forceType /*= false */) m_screenSaver.reset(new CScreenSaver("")); } } - if (m_screenSaver->ID() == "screensaver.xbmc.builtin.black") - SetCecStandby(true); if (m_screenSaver->ID() == "screensaver.xbmc.builtin.dim" || m_screenSaver->ID() == "screensaver.xbmc.builtin.black") { diff --git a/xbmc/Application.h b/xbmc/Application.h index b391dda..0b04927 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h @@ -394,8 +394,6 @@ public: void UnregisterActionListener(IActionListener *listener); bool ScreenSaverDisablesAutoScrolling(); - void SetCecStandby(bool status); - bool GetCecStandby() { return m_cecStandby; } void ChangeVT(int newVT); protected: @@ -424,9 +422,6 @@ protected: bool m_saveSkinOnUnloading; bool m_autoExecScriptExecuted; - bool m_cecStandby; - bool m_selfBlanked; - int m_ourVT; void checkVTchange(); diff --git a/xbmc/messaging/ApplicationMessenger.h b/xbmc/messaging/ApplicationMessenger.h index 8fcb70d..67cda36 100644 --- a/xbmc/messaging/ApplicationMessenger.h +++ b/xbmc/messaging/ApplicationMessenger.h @@ -91,6 +91,7 @@ #define TMSG_VIDEORESIZE TMSG_MASK_APPLICATION + 28 #define TMSG_SETAUDIODSPSTATE TMSG_MASK_APPLICATION + 29 #define TMSG_CHANGEVT TMSG_MASK_APPLICATION + 30 +#define TMSG_DISPLAY_RECONFIGURE TMSG_MASK_APPLICATION + 31 #define TMSG_GUI_INFOLABEL TMSG_MASK_GUIINFOMANAGER + 0 diff --git a/xbmc/peripherals/Peripherals.cpp b/xbmc/peripherals/Peripherals.cpp index f736c5b..4653308 100644 --- a/xbmc/peripherals/Peripherals.cpp +++ b/xbmc/peripherals/Peripherals.cpp @@ -32,6 +32,7 @@ #include "devices/PeripheralNIC.h" #include "devices/PeripheralNyxboard.h" #include "devices/PeripheralTuner.h" +#include "devices/PeripheralVideo.h" #include "dialogs/GUIDialogKaiToast.h" #include "dialogs/GUIDialogPeripheralSettings.h" #include "dialogs/GUIDialogSelect.h" diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index a999bad..dfd9bef 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -34,6 +34,7 @@ #include "settings/AdvancedSettings.h" #include "utils/log.h" #include "utils/Variant.h" +#include "utils/Screen.h" #include @@ -173,9 +174,6 @@ void CPeripheralCecAdapter::Announce(AnnouncementFlag flag, const char *sender, GetAudioSystemConnected()) m_cecAdapter->PowerOnDevices(CECDEVICE_AUDIOSYSTEM); } - // if we disable render on TV power on/off events, we have to enable it again screensaver off - // to get screen updates for VNC sessions - g_application.SetCecStandby(false); } else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && m_bIsReady) { @@ -646,7 +644,7 @@ int CPeripheralCecAdapter::CecCommand(void *cbParam, const cec_command command) g_application.ExecuteXBMCAction("Shutdown"); } if (command.initiator == CECDEVICE_TV) - g_application.SetCecStandby(true); + g_screen.SetOff(); break; case CEC_OPCODE_SET_MENU_LANGUAGE: if (adapter->m_configuration.bUseTVMenuLanguage == 1 && command.initiator == CECDEVICE_TV && command.parameters.size == 3) @@ -1201,7 +1199,7 @@ void CPeripheralCecAdapter::CecSourceActivated(void *cbParam, const CEC::cec_log } if (activated != 1) - g_application.SetCecStandby(true); + g_screen.SetOff(); } int CPeripheralCecAdapter::CecLogMessage(void *cbParam, const cec_log_message message) diff --git a/xbmc/peripherals/devices/PeripheralVideo.cpp b/xbmc/peripherals/devices/PeripheralVideo.cpp index e2fac22..f6c89a6 100644 --- a/xbmc/peripherals/devices/PeripheralVideo.cpp +++ b/xbmc/peripherals/devices/PeripheralVideo.cpp @@ -20,14 +20,18 @@ #include "PeripheralVideo.h" #include "utils/log.h" +#include "utils/Screen.h" #include "guilib/GraphicContext.h" #include "dialogs/GUIDialogKaiToast.h" #include "guilib/LocalizeStrings.h" -#include "ApplicationMessenger.h" -#include "Application.h" #include "settings/Settings.h" +#include "xbmc/utils/SysfsUtils.h" +#include "messaging/ApplicationMessenger.h" +#include "Application.h" +#include using namespace PERIPHERALS; +using namespace KODI::MESSAGING; CPeripheralVideo::CPeripheralVideo(const PeripheralScanResult& scanResult) : CPeripheral(scanResult) @@ -68,9 +72,10 @@ bool CPeripheralVideo::InitialiseFeature(const PeripheralFeature feature) void CPeripheralVideo::OnTimeout() { - switch (m_cableState) { + switch (m_cableState) + { case CABLE_CONNECTED: - g_application.SetCecStandby(false); + g_screen.SetOn(); if (CSettings::Get().GetBool("videoscreen.updateresolutions")) { @@ -80,7 +85,7 @@ void CPeripheralVideo::OnTimeout() break; case CABLE_DISCONNECTED: - g_application.SetCecStandby(true); + g_screen.SetOff(); default: ; diff --git a/xbmc/utils/Makefile.in b/xbmc/utils/Makefile.in index 7501a7c..85596be 100644 --- a/xbmc/utils/Makefile.in +++ b/xbmc/utils/Makefile.in @@ -52,6 +52,7 @@ SRCS += RssReader.cpp SRCS += SaveFileStateJob.cpp SRCS += ScraperParser.cpp SRCS += ScraperUrl.cpp +SRCS += Screen.cpp SRCS += Screenshot.cpp SRCS += SeekHandler.cpp SRCS += SortUtils.cpp diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp new file mode 100644 index 0000000..43287ce --- /dev/null +++ b/xbmc/utils/Screen.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "Application.h" +#include "utils/log.h" +#include "settings/Settings.h" +#include "video/VideoReferenceClock.h" +#include "guilib/GUIWindowManager.h" +#include "utils/Screen.h" +#include "windowing/WindowingFactory.h" +#include "threads/SingleLock.h" + +using namespace ANNOUNCEMENT; + +CScreen g_screen; + +CScreen::CScreen() + : m_state(false) + , m_changedBlank(false) + , m_timer(this) +{ + CAnnouncementManager::Get().AddAnnouncer(this); +} + +CScreen::~CScreen() +{ + CAnnouncementManager::Get().RemoveAnnouncer(this); +} + +void CScreen::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) +{ + if (flag == System && !strcmp(sender, "xbmc") && !strcmp(message, "OnQuit")) + g_application.SetRenderGUI(true); + else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverDeactivated")) + g_screen.SetOn(); + else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && CSettings::Get().GetString("screensaver.mode") == "screensaver.xbmc.builtin.black") + g_screen.SetOff(); +#ifdef HAS_IMXVPU + else if (flag == Player && !strcmp(sender, "xbmc") && !strcmp(message, "OnPlay")) + g_VideoReferenceClock.Start(); + else if (flag == Player && !strcmp(sender, "xbmc") && !strcmp(message, "OnPause")) + g_VideoReferenceClock.Stop(); +#endif +} + +void CScreen::ScreenPowerOff(bool doBlank) +{ + if (!doBlank || !CSettings::Get().GetBool("videoscreen.blankcurrent")) + return; + +#ifdef HAS_IMXVPU + m_changedBlank = true; + g_Windowing.Hide(); +#endif +} + +void CScreen::ScreenPowerOn(bool doBlank) +{ + if (!doBlank || !m_changedBlank) + return; + +#ifdef HAS_IMXVPU + m_changedBlank = false; + g_Windowing.Show(); +#endif +} + +void CScreen::SetState(bool state, bool doBlank) +{ + CSingleLock lock(m_critSection); + if (g_application.m_bStop) + { + g_application.SetRenderGUI(true); + return; + } + else if (state == m_state) + return; + + CLog::Log(LOGDEBUG, "%s - set standby %d, screensaver is %s", __FUNCTION__, (int)state, g_application.IsInScreenSaver() ? "active" : "inactive"); + + m_state = state; + + switch (state) + { + case true: + + g_VideoReferenceClock.Stop(); + if (!g_application.IsInScreenSaver()) + g_application.ActivateScreenSaver(); + ScreenPowerOff(doBlank); + + break; + case false: + g_application.WakeUpScreenSaverAndDPMS(); + ScreenPowerOn(doBlank); + if (g_application.m_pPlayer->IsPlayingVideo()) + g_VideoReferenceClock.Start(); + + default: + ; + } + + if (!state) + OnTimeout(); + else if (m_timer.IsRunning()) + m_timer.Restart(); + else + m_timer.Start(2500); +} + +void CScreen::OnTimeout() +{ + g_application.SetRenderGUI(!m_state); +} diff --git a/xbmc/utils/Screen.h b/xbmc/utils/Screen.h new file mode 100644 index 0000000..22b4f12 --- /dev/null +++ b/xbmc/utils/Screen.h @@ -0,0 +1,54 @@ +#pragma once +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +#include "interfaces/AnnouncementManager.h" +#include "threads/CriticalSection.h" +#include "threads/Timer.h" + +class CScreen : public ANNOUNCEMENT::IAnnouncer, protected ITimerCallback +{ +public: + CScreen(); + ~CScreen(); + + void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data); + + void SetOff(bool doBlank = true) { SetState(true, doBlank); }; + void SetOn() { SetState(false); }; + void SwitchState() { SetState(!m_state, m_changedBlank); }; + + bool GetScreenState() { return m_state; } + +protected: + void OnTimeout(); + +private: + void SetState(bool status, bool doBlank = true); + void ScreenPowerOn(bool doBlank); + void ScreenPowerOff(bool doBlank); + + bool m_state; + bool m_changedBlank; + CCriticalSection m_critSection; + CTimer m_timer; +}; + +extern CScreen g_screen; -- 2.7.1 From c62edddaf32ddf0c3beeacf62401c10bd2646baf Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 3 Sep 2015 23:18:37 +0200 Subject: [PATCH 107/250] PeripheralVideo: read 'limitedrange' setting from video hw Upstream-commit: bdcbd342b34b0fccc3e5d0ce8c10ffe58545925f --- xbmc/peripherals/devices/PeripheralVideo.cpp | 21 +++++++++++++++++++++ xbmc/peripherals/devices/PeripheralVideo.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/xbmc/peripherals/devices/PeripheralVideo.cpp b/xbmc/peripherals/devices/PeripheralVideo.cpp index f6c89a6..ca7d0f3 100644 --- a/xbmc/peripherals/devices/PeripheralVideo.cpp +++ b/xbmc/peripherals/devices/PeripheralVideo.cpp @@ -58,6 +58,26 @@ void CPeripheralVideo::OnDeviceChanged(int state) m_timer.Start(5000); } +bool CPeripheralVideo::IsQuantRangeLimited() +{ +#ifdef HAS_IMXVPU + std::string value; + std::string from = "/sys/devices/soc0/soc/20e0000.hdmi_video/rgb_quant_range"; + + std::ifstream file(from); + if (!file.is_open()) + { + from = "/sys/devices/soc0/soc.1/20e0000.hdmi_video/rgb_quant_range"; + } + file.close(); + + SysfsUtils::GetString(from, value); + if (value.find("limited") != std::string::npos) + return true; +#endif + return false; +} + void CPeripheralVideo::OnSettingChanged(const std::string &strChangedSetting) { bool configSet = false; @@ -77,6 +97,7 @@ void CPeripheralVideo::OnTimeout() case CABLE_CONNECTED: g_screen.SetOn(); + CSettings::Get().SetBool("videoscreen.limitedrange", IsQuantRangeLimited()); if (CSettings::Get().GetBool("videoscreen.updateresolutions")) { CApplicationMessenger::Get().SetupDisplayReconfigure(); diff --git a/xbmc/peripherals/devices/PeripheralVideo.h b/xbmc/peripherals/devices/PeripheralVideo.h index de1cc67..e6f363f 100644 --- a/xbmc/peripherals/devices/PeripheralVideo.h +++ b/xbmc/peripherals/devices/PeripheralVideo.h @@ -37,6 +37,8 @@ namespace PERIPHERALS void OnSettingChanged(const std::string &strChangedSetting); bool InitialiseFeature(const PeripheralFeature feature); + bool IsQuantRangeLimited(); + protected: int m_cableState; CTimer m_timer; -- 2.7.1 From c576f496169dacce4571284f9ce94269f9dde57c Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 3 Sep 2015 23:19:40 +0200 Subject: [PATCH 108/250] PeripheralVideo: add extra logging Upstream-commit: 6ecd44dea9773c78d576acf9c518ff2594e83342 --- xbmc/peripherals/devices/PeripheralVideo.cpp | 2 ++ xbmc/peripherals/devices/PeripheralVideo.h | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/xbmc/peripherals/devices/PeripheralVideo.cpp b/xbmc/peripherals/devices/PeripheralVideo.cpp index ca7d0f3..987c6bd 100644 --- a/xbmc/peripherals/devices/PeripheralVideo.cpp +++ b/xbmc/peripherals/devices/PeripheralVideo.cpp @@ -50,6 +50,8 @@ void CPeripheralVideo::OnDeviceChanged(int state) if (!GetSettingBool("pass_events")) return; + CLog::Log(LOGDEBUG, "%s - state %s over %s, timer %s", __FUNCTION__, stateToStr(state), stateToStr(m_cableState), !m_timer.IsRunning() ? "will be started" : "is already running"); + m_cableState = state; if (m_timer.IsRunning()) diff --git a/xbmc/peripherals/devices/PeripheralVideo.h b/xbmc/peripherals/devices/PeripheralVideo.h index e6f363f..2339bb1 100644 --- a/xbmc/peripherals/devices/PeripheralVideo.h +++ b/xbmc/peripherals/devices/PeripheralVideo.h @@ -39,6 +39,19 @@ namespace PERIPHERALS bool IsQuantRangeLimited(); + static const char *stateToStr(const int state) + { + switch (state) + { + case CABLE_CONNECTED: + return "connected"; + case CABLE_DISCONNECTED: + return "disconnected"; + default: + return "unknown"; + } + } + protected: int m_cableState; CTimer m_timer; -- 2.7.1 From 79d5a1e2403dc57bd8aab25b97236b6345f347c2 Mon Sep 17 00:00:00 2001 From: macrule Date: Thu, 11 Apr 2013 19:54:59 +0200 Subject: [PATCH 109/250] Added methods SuspendVideoOutput() and ResumeVideoOutput() to CRBP class, which can be used to power down the Raspberry PI's video interface, and restore it at a later point. Upstream-commit: cdaa66e2c2928d19aaf3b2949ddb64415f9c1c16 (cherry picked from commit b3dade1dc214c15ed48e96f6b5fedf41b644c662) Signed-off-by: Matus Kral --- xbmc/linux/RBP.cpp | 15 +++++++++++++++ xbmc/linux/RBP.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/xbmc/linux/RBP.cpp b/xbmc/linux/RBP.cpp index 2a9a93a..776687b 100644 --- a/xbmc/linux/RBP.cpp +++ b/xbmc/linux/RBP.cpp @@ -215,4 +215,19 @@ void CRBP::Deinitialize() m_initialized = false; m_omx_initialized = false; } + +void CRBP::SuspendVideoOutput() +{ + CLog::Log(LOGDEBUG, "Raspberry PI suspending video output\n"); + char response[80]; + m_DllBcmHost->vc_gencmd(response, sizeof response, "display_power 0"); +} + +void CRBP::ResumeVideoOutput() +{ + char response[80]; + m_DllBcmHost->vc_gencmd(response, sizeof response, "display_power 1"); + CLog::Log(LOGDEBUG, "Raspberry PI resuming video output\n"); +} + #endif diff --git a/xbmc/linux/RBP.h b/xbmc/linux/RBP.h index 9559914..3b1df8b 100644 --- a/xbmc/linux/RBP.h +++ b/xbmc/linux/RBP.h @@ -64,6 +64,9 @@ public: DllOMX *GetDllOMX() { return m_OMX ? m_OMX->GetDll() : NULL; } void WaitVsync(); + void SuspendVideoOutput(); + void ResumeVideoOutput(); + private: DllBcmHost *m_DllBcmHost; bool m_initialized; -- 2.7.1 From 52fb7d53f73f9daa2a3f6118b5ea7db6bb033725 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 5 Sep 2015 04:37:28 +0200 Subject: [PATCH 110/250] WinSystemEGL: put RPI relevant code under #ifdef Upstream-commit: d21c5b2d165d3022a3feea0aad2d68cff7bd802e --- xbmc/windowing/egl/WinSystemEGL.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xbmc/windowing/egl/WinSystemEGL.cpp b/xbmc/windowing/egl/WinSystemEGL.cpp index 35b7de6..b6f550b 100644 --- a/xbmc/windowing/egl/WinSystemEGL.cpp +++ b/xbmc/windowing/egl/WinSystemEGL.cpp @@ -289,7 +289,9 @@ bool CWinSystemEGL::CreateNewWindow(const std::string& name, bool fullScreen, RE (current_resolution.dwFlags & D3DPRESENTFLAG_MODEMASK) == (res.dwFlags & D3DPRESENTFLAG_MODEMASK)) { CLog::Log(LOGDEBUG, "CWinSystemEGL::CreateNewWindow: No need to create a new window"); +#if !defined(TARGET_RASPBERRY_PI) return true; +#endif } m_bFullScreen = fullScreen; -- 2.7.1 From e70fb3dec7a4c925ad697a199ab9cc3bd2845fd8 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 9 Sep 2015 12:23:36 +0200 Subject: [PATCH 111/250] EGLNativeTypeIMX: call ShowWindow(true) on ::Destroy() Upstream-commit: 7b942bfbfc7d317446a3b2185226f1ba8a655867 --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index e6e117c..a629fc3 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -179,6 +179,7 @@ void CEGLNativeTypeIMX::Destroy() close(fd); SetNativeResolution(m_init); + ShowWindow(true); system("/usr/bin/splash --force -i -m 'stopping kodi...'"); #endif -- 2.7.1 From c8a2c855351a515471dc16c4470564508fc932ae Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 9 Sep 2015 12:25:59 +0200 Subject: [PATCH 112/250] CScreen: test for g_application.m_bStop outside the lock() Upstream-commit: 273b31fd782533a817dd074760669c5d28b4ff9c --- xbmc/utils/Screen.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp index 43287ce..dcfd886 100644 --- a/xbmc/utils/Screen.cpp +++ b/xbmc/utils/Screen.cpp @@ -84,13 +84,14 @@ void CScreen::ScreenPowerOn(bool doBlank) void CScreen::SetState(bool state, bool doBlank) { - CSingleLock lock(m_critSection); if (g_application.m_bStop) { g_application.SetRenderGUI(true); return; } - else if (state == m_state) + + CSingleLock lock(m_critSection); + if (state == m_state) return; CLog::Log(LOGDEBUG, "%s - set standby %d, screensaver is %s", __FUNCTION__, (int)state, g_application.IsInScreenSaver() ? "active" : "inactive"); -- 2.7.1 From d943e59b2240576710989114fb0ea9d58924a637 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 9 Sep 2015 16:06:57 +0200 Subject: [PATCH 113/250] CScreen: call CIMXContext::Blank/Unblank to inform that FB rendering/flipping/* is disabled Upstream-commit: b63d82fc4cdd718e61686a0fc6ef59a103f41eae --- xbmc/utils/Screen.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp index dcfd886..8680600 100644 --- a/xbmc/utils/Screen.cpp +++ b/xbmc/utils/Screen.cpp @@ -26,6 +26,9 @@ #include "utils/Screen.h" #include "windowing/WindowingFactory.h" #include "threads/SingleLock.h" +#ifdef HAS_IMXVPU +#include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h" +#endif using namespace ANNOUNCEMENT; @@ -67,6 +70,9 @@ void CScreen::ScreenPowerOff(bool doBlank) #ifdef HAS_IMXVPU m_changedBlank = true; + // calling CIMXContext::Blank() tells CodecIMX + // fb1 is not ready + g_IMXContext.Blank(); g_Windowing.Hide(); #endif } @@ -79,6 +85,7 @@ void CScreen::ScreenPowerOn(bool doBlank) #ifdef HAS_IMXVPU m_changedBlank = false; g_Windowing.Show(); + g_IMXContext.Unblank(); #endif } -- 2.7.1 From c0867e6271bbea069f1336239d2c264f159c6d1e Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 9 Sep 2015 20:13:36 +0200 Subject: [PATCH 114/250] Revert "[peripherals] Move initialisation after language init to fix notifications" Upstream-commit: 51c2030e7fc2f6e28d16ef7a4ef61eaae57d89a1 This reverts commit c2238cb4f7136b57c3a8a620db4ae80dd5579231. --- xbmc/Application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index f425a7d..b215ee4 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -691,6 +691,8 @@ bool CApplication::Create() return false; } + g_peripherals.Initialise(); + // Create the Mouse, Keyboard, Remote, and Joystick devices // Initialize after loading settings to get joystick deadzone setting CInputManager::GetInstance().InitializeInputs(); @@ -1129,8 +1131,6 @@ bool CApplication::Initialize() StringUtils::Format(g_localizeStrings.Get(178).c_str(), g_sysinfo.GetAppName().c_str()), "special://xbmc/media/icon256x256.png", EventLevelBasic))); - g_peripherals.Initialise(); - // Load curl so curl_global_init gets called before any service threads // are started. Unloading will have no effect as curl is never fully unloaded. // To quote man curl_global_init: -- 2.7.1 From 969d577e6db5bd2cb28831da6714b799c994d4d9 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 9 Sep 2015 20:18:58 +0200 Subject: [PATCH 115/250] CScreen: Suspend/Resume audio when powering off display Upstream-commit: d4826bfa21736eb849d73041cdfdf8e72400ea33 --- xbmc/utils/Screen.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp index 8680600..721e35a 100644 --- a/xbmc/utils/Screen.cpp +++ b/xbmc/utils/Screen.cpp @@ -29,6 +29,7 @@ #ifdef HAS_IMXVPU #include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h" #endif +#include "cores/AudioEngine/AEFactory.h" using namespace ANNOUNCEMENT; @@ -70,6 +71,7 @@ void CScreen::ScreenPowerOff(bool doBlank) #ifdef HAS_IMXVPU m_changedBlank = true; + CAEFactory::Suspend(); // calling CIMXContext::Blank() tells CodecIMX // fb1 is not ready g_IMXContext.Blank(); @@ -86,6 +88,7 @@ void CScreen::ScreenPowerOn(bool doBlank) m_changedBlank = false; g_Windowing.Show(); g_IMXContext.Unblank(); + CAEFactory::Resume(); #endif } -- 2.7.1 From dd267b0182f7f9f0582757c9a5f516d374dd929f Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 11 Sep 2015 11:26:07 +0200 Subject: [PATCH 116/250] CSceen: add RPI to the display savings workflow Upstream-commit: a80ad44d822ebda4fc4358a5e02bb1bc7d2c6655 --- xbmc/utils/Screen.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp index 721e35a..50d9773 100644 --- a/xbmc/utils/Screen.cpp +++ b/xbmc/utils/Screen.cpp @@ -28,6 +28,8 @@ #include "threads/SingleLock.h" #ifdef HAS_IMXVPU #include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h" +#elif defined(TARGET_RASPBERRY_PI) +#include "linux/RBP.h" #endif #include "cores/AudioEngine/AEFactory.h" @@ -56,12 +58,10 @@ void CScreen::Announce(AnnouncementFlag flag, const char *sender, const char *me g_screen.SetOn(); else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && CSettings::Get().GetString("screensaver.mode") == "screensaver.xbmc.builtin.black") g_screen.SetOff(); -#ifdef HAS_IMXVPU else if (flag == Player && !strcmp(sender, "xbmc") && !strcmp(message, "OnPlay")) g_VideoReferenceClock.Start(); else if (flag == Player && !strcmp(sender, "xbmc") && !strcmp(message, "OnPause")) g_VideoReferenceClock.Stop(); -#endif } void CScreen::ScreenPowerOff(bool doBlank) @@ -69,8 +69,10 @@ void CScreen::ScreenPowerOff(bool doBlank) if (!doBlank || !CSettings::Get().GetBool("videoscreen.blankcurrent")) return; -#ifdef HAS_IMXVPU m_changedBlank = true; +#if defined(TARGET_RASPBERRY_PI) + g_RBP.SuspendVideoOutput(); +#elif HAS_IMXVPU CAEFactory::Suspend(); // calling CIMXContext::Blank() tells CodecIMX // fb1 is not ready @@ -84,8 +86,10 @@ void CScreen::ScreenPowerOn(bool doBlank) if (!doBlank || !m_changedBlank) return; -#ifdef HAS_IMXVPU m_changedBlank = false; +#if defined(TARGET_RASPBERRY_PI) + g_RBP.ResumeVideoOutput(); +#elif HAS_IMXVPU g_Windowing.Show(); g_IMXContext.Unblank(); CAEFactory::Resume(); @@ -128,6 +132,10 @@ void CScreen::SetState(bool state, bool doBlank) ; } + // SetRenderGui(false) doesn't need to be timed (delayed) + // It was just try to let ScreenSaver kick in (rewrite screen - black for instance) + // before we stop render. But somehow has not the expected effect (perhaps the actual + // delay between event <> saver launch is longer. if (!state) OnTimeout(); else if (m_timer.IsRunning()) -- 2.7.1 From 30eef5e1d20af08162dac703519dbd8ee87da841 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 12 Sep 2015 11:43:01 +0200 Subject: [PATCH 117/250] configure: remove FFMPEG_EXTRACFLAGS as it is no more used and move arch/cpu relevant flags into CFLAGS Upstream-commit: f7fd7875c90157538d394b545c2c263259c10602 --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4414d8d..562b435 100644 --- a/configure.ac +++ b/configure.ac @@ -737,7 +737,6 @@ case $use_platform in use_hardcoded_tables="yes" CFLAGS="$CFLAGS -pipe -O3 -march=armv7-a -mtune=cortex-a9 -mcpu=cortex-a9 -mfloat-abi=hard -mfpu=neon -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " CXXFLAGS="$CXXFLAGS -pipe -O3 -march=armv7-a -mtune=cortex-a9 -mcpu=cortex-a9 -mfloat-abi=hard -mfpu=neon -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " - FFMPEG_EXTRACFLAGS="$FFMPEG_EXTRACFLAGS -pipe -O3 -march=armv7-a -mtune=cortex-a9 -mcpu=cortex-a9 -mfloat-abi=hard -mfpu=neon -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " use_cpu=cortex-a9 use_x11=no use_neon=yes -- 2.7.1 From a253493f2c28c39ed4585c7c20ec247a60bbf781 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 12 Sep 2015 16:49:38 +0200 Subject: [PATCH 118/250] EGLEdid: change class to work as a global object, with public access to raw edid Upstream-commit: 149496e6b135a5a49633dcdd0c45b5f8802adf23 --- xbmc/windowing/egl/EGLEdid.cpp | 9 +++++++++ xbmc/windowing/egl/EGLEdid.h | 19 ++++++++++++++++--- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 12 ++++++++---- xbmc/windowing/egl/EGLNativeTypeIMX.h | 5 +---- xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 16 ++++++++++------ xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h | 5 +---- 6 files changed, 45 insertions(+), 21 deletions(-) diff --git a/xbmc/windowing/egl/EGLEdid.cpp b/xbmc/windowing/egl/EGLEdid.cpp index babc506..75e56d2 100644 --- a/xbmc/windowing/egl/EGLEdid.cpp +++ b/xbmc/windowing/egl/EGLEdid.cpp @@ -21,9 +21,13 @@ #include "system.h" #include "EGLEdid.h" #include "utils/log.h" +#include "threads/SingleLock.h" + +CEGLEdid g_EGLEdid; CEGLEdid::CEGLEdid() : m_fSar(0.0f) + , m_edidEmpty(true) { } @@ -50,7 +54,10 @@ float CEGLEdid::ValidateSAR(struct dt_dim *dtm, bool mb) void CEGLEdid::CalcSAR() { + CSingleLock lk(m_lock); + m_fSar = .0f; + m_edidEmpty = true; ReadEdidData(); // enumerate through (max four) detailed timing info blocks @@ -72,4 +79,6 @@ void CEGLEdid::CalcSAR() CLog::Log(LOGWARNING, "%s: Screen SAR - not usable info",__FUNCTION__); m_fSar = 1.0f; } + + m_edidEmpty = false; } diff --git a/xbmc/windowing/egl/EGLEdid.h b/xbmc/windowing/egl/EGLEdid.h index 5c10e44..71241b7 100644 --- a/xbmc/windowing/egl/EGLEdid.h +++ b/xbmc/windowing/egl/EGLEdid.h @@ -20,11 +20,14 @@ * */ +#include "threads/CriticalSection.h" +#include "threads/SingleLock.h" #include #define EDID_STRUCT_DISPLAY 0x14 #define EDID_DTM_START 0x36 #define EDID_DTM_OFFSET_DIMENSION 0x0c +#define EDID_EXTENSION_BLOCK_START 0x7e #define EDID_MAXSIZE 512 class CEGLEdid @@ -39,14 +42,24 @@ public: CEGLEdid(); virtual ~CEGLEdid(); - virtual void ReadEdidData() = 0; + bool ReadEdidData(); + const uint8_t *GetRawEdid() { Lock(); if (m_edidEmpty) CalcSAR(); return m_edidEmpty ? NULL : &m_edid[0]; } - float GetSAR() const { return m_fSar; } + float GetSAR() const { CSingleLock lk(m_lock); return m_fSar; } void CalcSAR(); + void Lock() { m_lock.lock(); } + void Unlock() { m_lock.unlock(); } + + uint8_t m_edid[EDID_MAXSIZE]; + protected: float ValidateSAR(struct dt_dim *dtm, bool mb = false); float m_fSar; - uint8_t m_edid[EDID_MAXSIZE]; + bool m_edidEmpty; + + CCriticalSection m_lock; }; + +extern CEGLEdid g_EGLEdid; diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index a629fc3..370a8f7 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -43,6 +43,8 @@ #include "peripherals/Peripherals.h" #include "peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h" +#include "EGLEdid.h" + using namespace PERIPHERALS; CEGLNativeTypeIMX::CEGLNativeTypeIMX() @@ -341,7 +343,7 @@ bool CEGLNativeTypeIMX::FindMatchingResolution(const RESOLUTION_INFO &res, const bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutions) { #ifdef HAS_IMXVPU - CalcSAR(); + g_EGLEdid.CalcSAR(); if (m_readonly) return false; @@ -401,7 +403,7 @@ bool CEGLNativeTypeIMX::ShowWindow(bool show) } #ifdef HAS_IMXVPU -void CEGLNativeTypeIMX::ReadEdidData() +bool CEGLEdid::ReadEdidData() { FILE *f_edid; char *str = NULL; @@ -416,7 +418,7 @@ void CEGLNativeTypeIMX::ReadEdidData() f_edid = fopen("/sys/devices/soc0/soc.1/20e0000.hdmi_video/edid", "r"); if(!f_edid) - return; + return false; // we need to convert mxc_hdmi output format to binary array // mxc_hdmi provides the EDID as space delimited 1bytes blocks @@ -446,6 +448,8 @@ void CEGLNativeTypeIMX::ReadEdidData() str = NULL; } fclose(f_edid); + + return true; } bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) const @@ -499,7 +503,7 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->bFullScreen = true; res->iSubtitles = (int)(0.965 * res->iHeight); - res->fPixelRatio *= (float)GetSAR() / res->iScreenWidth * res->iScreenHeight; + res->fPixelRatio *= (float)g_EGLEdid.GetSAR() / res->iScreenWidth * res->iScreenHeight; res->strMode = StringUtils::Format("%4sx%4s @ %.3f%s - Full Screen (%.3f) %s", StringUtils::Format("%d", res->iScreenWidth).c_str(), StringUtils::Format("%d", res->iScreenHeight).c_str(), res->fRefreshRate, res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : " ", res->fPixelRatio, diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.h b/xbmc/windowing/egl/EGLNativeTypeIMX.h index d7976f4..7769e79 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.h +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.h @@ -24,9 +24,7 @@ #include #include "EGLNativeType.h" -#include "EGLEdid.h" - -class CEGLNativeTypeIMX : public CEGLNativeType, private CEGLEdid +class CEGLNativeTypeIMX : public CEGLNativeType { public: CEGLNativeTypeIMX(); @@ -51,7 +49,6 @@ public: virtual bool GetPreferredResolution(RESOLUTION_INFO *res) const; virtual bool ShowWindow(bool show = true); - virtual void ReadEdidData(); #ifdef HAS_IMXVPU protected: diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp index 7c4b1a3..39875e1 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp @@ -33,6 +33,8 @@ #include "peripherals/bus/PeripheralBus.h" #include "peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h" +#include "EGLEdid.h" + using namespace PERIPHERALS; #ifndef __VIDEOCORE4__ @@ -220,7 +222,7 @@ bool CEGLNativeTypeRaspberryPI::GetNativeResolution(RESOLUTION_INFO *res) const res->iScreenWidth = tv_state.display.hdmi.width; res->iScreenHeight= tv_state.display.hdmi.height; res->dwFlags = MAKEFLAGS(tv_state.display.hdmi.group, tv_state.display.hdmi.mode, tv_state.display.hdmi.scan_mode); - res->fPixelRatio = (float)GetSAR() / ((float)res->iScreenWidth / (float)res->iScreenHeight); + res->fPixelRatio = (float)g_EGLEdid.GetSAR() / ((float)res->iScreenWidth / (float)res->iScreenHeight); // Also add 3D flags if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_SBS_HALF) { @@ -247,7 +249,7 @@ bool CEGLNativeTypeRaspberryPI::GetNativeResolution(RESOLUTION_INFO *res) const res->iScreenHeight= tv_state.display.sdtv.height; res->dwFlags = MAKEFLAGS(HDMI_RES_GROUP_INVALID, tv_state.display.sdtv.mode, 1); res->fRefreshRate = (float)tv_state.display.sdtv.frame_rate; - res->fPixelRatio = (float)GetSAR() / ((float)res->iScreenWidth / (float)res->iScreenHeight); + res->fPixelRatio = (float)g_EGLEdid.GetSAR() / ((float)res->iScreenWidth / (float)res->iScreenHeight); } else if ((tv_state.state & VC_LCD_ATTACHED_DEFAULT) != 0) // lcd { @@ -259,7 +261,7 @@ bool CEGLNativeTypeRaspberryPI::GetNativeResolution(RESOLUTION_INFO *res) const res->iScreenHeight= tv_state.display.sdtv.height; res->dwFlags = MAKEFLAGS(HDMI_RES_GROUP_INVALID, 0, 0); res->fRefreshRate = (float)tv_state.display.sdtv.frame_rate; - res->fPixelRatio = (float)GetSAR() / ((float)res->iScreenWidth / (float)res->iScreenHeight); + res->fPixelRatio = (float)g_EGLEdid.GetSAR() / ((float)res->iScreenWidth / (float)res->iScreenHeight); } DLOG("CEGLNativeTypeRaspberryPI::GetNativeResolution %s\n", res->strMode.c_str()); @@ -545,7 +547,7 @@ bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &r if(!m_DllBcmHost) return false; - CalcSAR(); + g_EGLEdid.CalcSAR(); /* read initial desktop resolution before probe resolutions. * probing will replace the desktop resolution when it finds the same one. @@ -651,7 +653,7 @@ void CEGLNativeTypeRaspberryPI::GetSupportedModes(HDMI_RES_GROUP_T group, std::v res.iHeight = tv->height; res.iScreenWidth = tv->width; res.iScreenHeight = tv->height; - res.fPixelRatio = (float)GetSAR() / ((float)res.iScreenWidth / (float)res.iScreenHeight); + res.fPixelRatio = (float)g_EGLEdid.GetSAR() / ((float)res.iScreenWidth / (float)res.iScreenHeight); res.iSubtitles = (int)(0.965 * res.iHeight); if (!m_desktopRes.dwFlags && prefer_group == group && prefer_mode == tv->code) @@ -742,7 +744,7 @@ void CEGLNativeTypeRaspberryPI::CallbackTvServiceCallback(void *userdata, uint32 callback->TvServiceCallback(reason, param1, param2); } -void CEGLNativeTypeRaspberryPI::ReadEdidData() +bool CEGLEdid::ReadEdidData() { uint8_t buffer[128]; size_t offset = 0; @@ -767,6 +769,8 @@ void CEGLNativeTypeRaspberryPI::ReadEdidData() memcpy((uint8_t *)(&m_edid + offset), &buffer, sizeof(buffer)); } } + + return true; } #endif diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h index e72ba4e..93b54b3 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.h @@ -28,12 +28,10 @@ #include "peripherals/Peripherals.h" #include "threads/Thread.h" -#include "EGLEdid.h" - using namespace PERIPHERALS; class DllBcmHost; -class CEGLNativeTypeRaspberryPI : public CEGLNativeType, private CEGLEdid +class CEGLNativeTypeRaspberryPI : public CEGLNativeType { public: CEGLNativeTypeRaspberryPI(); @@ -58,7 +56,6 @@ public: virtual bool GetPreferredResolution(RESOLUTION_INFO *res) const; virtual bool ShowWindow(bool show); - virtual void ReadEdidData(); #if defined(TARGET_RASPBERRY_PI) private: -- 2.7.1 From 3275dca56e1664268081374e5c22ec5a849a1505 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 17 Sep 2015 11:59:49 +0200 Subject: [PATCH 119/250] CNetwork: make restart of services on network change user setting dependent Upstream-commit: 3fc33181ee149c12b9efe193fc76c9855431be45 --- addons/resource.language.en_gb/resources/strings.po | 12 ++++++++++++ system/settings/settings.xml | 7 +++++++ xbmc/network/Network.cpp | 10 +++++++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index de793fa..dcd533e 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -18172,3 +18172,15 @@ msgctxt "#40004" msgid "Kodi will powerdown the GPU (when not in use), thus provide significant powersavings. TV being powered OFF, Kodi no longer active source (CEC) or start of BlackScreensaver will trigger this action (HDMI Audio will be powered down too)" msgstr "" +#. Label of setting "System -> Network -> Restart services" +#: system/settings/settings.xml +msgctxt "#40005" +msgid "Restart services on network change" +msgstr "" + +#. Description of setting "System -> Network -> Restart services" +#: system/settings/settings.xml +msgctxt "#40006" +msgid "If physical network parameters change (add/remove of network card or interface), automatically restart all Kodi services (sevices will re-read network settings and use new network parameters)" +msgstr "" + diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 85274d2..04bc977 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -2881,6 +2881,13 @@ + + + 3 + false + + + diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index 79a9037..56e0b86 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -24,6 +24,7 @@ #include #include +#include "settings/Settings.h" #include "Network.h" #include "messaging/ApplicationMessenger.h" #include "network/NetworkServices.h" @@ -417,10 +418,13 @@ void CNetwork::NetworkMessage(EMESSAGE message, int param) case NETWORK_CHANGED: m_signalNetworkChange.Set(); - CLog::Log(LOGDEBUG, "%s - Network setup changed. Will restart network services",__FUNCTION__); ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::Network, "network", "OnInterfacesChange"); - NetworkMessage(SERVICES_DOWN, 0); - NetworkMessage(SERVICES_UP, 0); + if (CSettings::GetInstance().GetBool("network.restartservices")) + { + CLog::Log(LOGDEBUG, "%s - Network setup changed. Will restart network services",__FUNCTION__); + NetworkMessage(SERVICES_DOWN, 0); + NetworkMessage(SERVICES_UP, 0); + } break; } } -- 2.7.1 From 4910aa35d25582e9b0432b4cea8a941db4047f55 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 18 Sep 2015 07:31:00 +0200 Subject: [PATCH 120/250] Log: #undef DEBUG to not force DEBUG logging if compiling with debug info Upstream-commit: a49de0e644793d8d8d4ebb86d9b7f3e89c786818 --- xbmc/utils/log.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/xbmc/utils/log.cpp b/xbmc/utils/log.cpp index 3443f12..b719ccd 100644 --- a/xbmc/utils/log.cpp +++ b/xbmc/utils/log.cpp @@ -17,6 +17,7 @@ * . * */ +#undef _DEBUG #include "log.h" #include "system.h" -- 2.7.1 From fa55ba394c3de2a1a69303de114156fabf54826f Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 18 Sep 2015 17:41:51 +0200 Subject: [PATCH 121/250] DVDVideoCodecIMX: dispose dropped frame Upstream-commit: be5547bc970559efa6767fe7a6204da93f3334a3 --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 8d6f7e5..f609145 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1099,11 +1099,6 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) pDvdVideoPicture->iFlags = 0; pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED; - if (m_dropState) - { - pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED; - m_dropState = false; - } if (m_initInfo.nInterlace) { @@ -1129,6 +1124,14 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) pDvdVideoPicture->pts = m_currentBuffer->GetPts(); pDvdVideoPicture->dts = m_currentBuffer->GetDts(); + if (m_dropState) + { + pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED; + SAFE_RELEASE(m_currentBuffer); + m_dropState = false; + return true; + } + pDvdVideoPicture->IMXBuffer = m_currentBuffer; m_currentBuffer = NULL; -- 2.7.1 From 02effbea2a47d1b089f480ec29db3e011a95215b Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 21 Sep 2015 06:35:33 +0200 Subject: [PATCH 122/250] EGLNativeTypeRaspberryPI: more cleanup Upstream-commit: 7f777fd856e5e239c28b79f6eecf7c6b032e6b05 --- xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 39 +++++++------------------ 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp index 39875e1..da4fb78 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp @@ -204,6 +204,10 @@ bool CEGLNativeTypeRaspberryPI::DestroyNativeWindow() #endif } +#if defined(TARGET_RASPBERRY_PI) +static float get_display_aspect_ratio(SDTV_ASPECT_T aspect); +#endif + bool CEGLNativeTypeRaspberryPI::GetNativeResolution(RESOLUTION_INFO *res) const { #if defined(TARGET_RASPBERRY_PI) @@ -291,14 +295,9 @@ int CEGLNativeTypeRaspberryPI::AddUniqueResolution(RESOLUTION_INFO &res, std::ve { SetResolutionString(res); int i = FindMatchingResolution(res, resolutions); - if (i>=0) - { // don't replace a progressive resolution with an interlaced one of same resolution - resolutions[i] = res; - } - else - { - resolutions.push_back(res); - } + if (i == -1) + resolutions.push_back(res); + return i; } #endif @@ -549,25 +548,10 @@ bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &r g_EGLEdid.CalcSAR(); - /* read initial desktop resolution before probe resolutions. - * probing will replace the desktop resolution when it finds the same one. - * we raplace it because probing will generate more detailed - * resolution flags we don't get with vc_tv_get_state. - */ - - if(m_initDesktopRes) + if(GETFLAGS_GROUP(m_desktopRes.dwFlags) && GETFLAGS_MODE(m_desktopRes.dwFlags)) { - m_initDesktopRes = !GetNativeResolution(&m_desktopRes); - SetResolutionString(m_desktopRes); - CLog::Log(LOGDEBUG, "EGL initial desktop resolution %s (%.2f)\n", m_desktopRes.strMode.c_str(), m_desktopRes.fPixelRatio); - } - - GetSupportedModes(HDMI_RES_GROUP_CEA, resolutions); - GetSupportedModes(HDMI_RES_GROUP_DMT, resolutions); - - { - AddUniqueResolution(m_desktopRes, resolutions); - CLog::Log(LOGDEBUG, "EGL probe resolution %s:%x\n", m_desktopRes.strMode.c_str(), m_desktopRes.dwFlags); + GetSupportedModes(HDMI_RES_GROUP_CEA, resolutions); + GetSupportedModes(HDMI_RES_GROUP_DMT, resolutions); } DLOG("CEGLNativeTypeRaspberryPI::ProbeResolutions\n"); @@ -659,9 +643,6 @@ void CEGLNativeTypeRaspberryPI::GetSupportedModes(HDMI_RES_GROUP_T group, std::v if (!m_desktopRes.dwFlags && prefer_group == group && prefer_mode == tv->code) m_desktopRes = res; - if (res.dwFlags & D3DPRESENTFLAG_INTERLACED) - continue; - AddUniqueResolution(res, resolutions); CLog::Log(LOGDEBUG, "EGL mode %d: %s (%.2f) %s%s:%x\n", i, res.strMode.c_str(), res.fPixelRatio, tv->native ? "N" : "", tv->scan_mode ? "I" : "", tv->code); -- 2.7.1 From d49db970268fa40c7e3dd2a052813fc8002af35e Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 22 Sep 2015 00:35:52 +0200 Subject: [PATCH 123/250] add vc_hdmi.h - to share some #define with RPB Upstream-commit: 20c24fa377acc62766be2536a519bac7232af765 --- xbmc/windowing/egl/vc_hdmi.h | 561 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 561 insertions(+) create mode 100644 xbmc/windowing/egl/vc_hdmi.h diff --git a/xbmc/windowing/egl/vc_hdmi.h b/xbmc/windowing/egl/vc_hdmi.h new file mode 100644 index 0000000..8f07c00 --- /dev/null +++ b/xbmc/windowing/egl/vc_hdmi.h @@ -0,0 +1,561 @@ +/* +Copyright (c) 2012, Broadcom Europe Ltd +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + * HDMI common host header for TV service, defines resolution code which host applications should + * use for power up command for HDMI + */ + +#ifndef _VC_HDMI_H_ +#define _VC_HDMI_H_ + +typedef int VC_HDMI_BOOL_T; + +/** + * HDMI resolution groups. There are two main groups: + * CEA - the conventional HDMI ones like 720p + * DMT - computer monitor resolutions like XGA + */ +typedef enum { + HDMI_RES_GROUP_INVALID = 0, /**< Initialised value */ + HDMI_RES_GROUP_CEA = 1, /**< CEA - HDMI device */ + HDMI_RES_GROUP_DMT = 2, /**< DMT - computer monitors */ + HDMI_RES_GROUP_CEA_3D = 3, /* deprecated */ + +} HDMI_RES_GROUP_T; + + +/** + * CEA 861 defined video code and aspect ratios for various HDMI modes + * Not all values are valid for AVI infoframe + */ +typedef enum { + HDMI_ASPECT_UNKNOWN = 0, /**< Unknown aspect ratio, or not one of the values below */ + HDMI_ASPECT_4_3 = 1, /**< 4:3 */ + HDMI_ASPECT_14_9 = 2, /**< 14:9 */ + HDMI_ASPECT_16_9 = 3, /**< 16:9 */ + HDMI_ASPECT_5_4 = 4, /**< 5:4 */ + HDMI_ASPECT_16_10 = 5, /**< 16:10*/ + HDMI_ASPECT_15_9 = 6, /**< 15:9 */ + HDMI_ASPECT_64_27 = 7, /**< 64:27 */ + HDMI_ASPECT_21_9 = HDMI_ASPECT_64_27 /**< 21:9 is jargon, 64:27 is the actual aspect ratio */ + /* More aspect ratio values may be added here if defined by CEA in future */ +} HDMI_ASPECT_T; + +/** + * Display options set the bounding box (only used in CEA mode) + */ +typedef struct { + uint16_t aspect; /**> 16) & 0xff )) +#define GETFLAGS_MODE(f) ( ( (f) >>24 ) & 0xff ) + +#endif /*HDMI_RES_GROUP_NAME*/ -- 2.7.1 From f5d95e1ace9815de8be3b0c2cfe76cbf22fbad15 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 22 Sep 2015 00:27:40 +0200 Subject: [PATCH 124/250] Add new setting in Settings->Videos - Allow only CEA modes when changing resolutions Upstream-commit: 6f85985c4f01f6742abf9a225e137a371f582924 --- addons/resource.language.en_gb/resources/strings.po | 5 +++++ system/settings/settings.xml | 9 +++++++++ xbmc/cores/VideoRenderers/BaseRenderer.cpp | 6 +++++- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 4 +++- xbmc/windowing/egl/EGLNativeTypeIMX.h | 1 + 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index dcd533e..59f7ba2 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -18184,3 +18184,8 @@ msgctxt "#40006" msgid "If physical network parameters change (add/remove of network card or interface), automatically restart all Kodi services (sevices will re-read network settings and use new network parameters)" msgstr "" +#. Label of setting "Settings -> Videos -> Allow non-CEA" +#: system/settings/settings.xml +msgctxt "#40013" +msgid "Allow changing to non-CEA modes" +msgstr "" diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 04bc977..3cfd0cf 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -594,6 +594,15 @@ + + 2 + false + true + + true + + + 2 false diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp index 07f7e37..cac81d6 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp @@ -41,6 +41,8 @@ #endif #include "Application.h" +#include "windowing/egl/vc_hdmi.h" + CBaseRenderer::CBaseRenderer() { m_sourceFrameRatio = 1.0f; @@ -253,6 +255,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES { const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); if (!(info.dwFlags & D3DPRESENTFLAG_INTERLACED) + || (!CSettings::GetInstance().GetBool("videoplayer.adjustallownoncea") && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) || info.iScreenHeight != m_sourceHeight || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.11) continue; @@ -270,6 +273,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.11 || (info.dwFlags & D3DPRESENTFLAG_INTERLACED && !(m_iFlags & CONF_FLAGS_INTERLACED)) || (!CSettings::GetInstance().GetBool("videoplayer.adjustresolutioninterlaced") && (info.dwFlags & D3DPRESENTFLAG_INTERLACED)) + || (!CSettings::GetInstance().GetBool("videoplayer.adjustallownoncea") && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) || m_sourceWidth > info.iScreenWidth || m_sourceHeight > info.iScreenHeight || pow(info.iScreenWidth*info.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) > last_diff) continue; @@ -291,6 +295,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES if (m_sourceWidth > info.iScreenWidth || m_sourceHeight > info.iScreenHeight || pow(info.iScreenWidth*info.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) > last_diff || info.iScreen != curr.iScreen + || (!CSettings::GetInstance().GetBool("videoplayer.adjustallownoncea") && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK)) { /* CLog::Log(LOGDEBUG, "curr %.2f, trying %.2f, mode nr. %d, %dx%d msk %d, m_msk %d", info.fPixelRatio, curr.fPixelRatio, i, @@ -304,7 +309,6 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES last_diff = pow(curr.iScreenWidth*curr.iScreenHeight - m_sourceWidth*m_sourceHeight, 2); } } ->>>>>>> adjust resolution on play. last_diff = fRefreshRate; diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 370a8f7..1a08305 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -466,7 +466,7 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) std::string fromMode = StringUtils::Mid(mode, 2); StringUtils::Trim(fromMode); - res->dwFlags = 0; + res->dwFlags = MAKEFLAGS(HDMI_RES_GROUP_CEA, 0, 0); res->fPixelRatio = 1.0f; if (StringUtils::StartsWith(mode, "H:")) { @@ -475,6 +475,8 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) } else if (StringUtils::StartsWith(mode, "T:")) { res->dwFlags |= D3DPRESENTFLAG_MODE3DTB; res->fPixelRatio = 0.5f; + } else if (StringUtils::StartsWith(mode, "U:") || StringUtils::StartsWith(mode, "V:")) { + res->dwFlags &= ~(MAKEFLAGS(HDMI_RES_GROUP_CEA, 0, 0)); } else if (StringUtils::StartsWith(mode, "F:")) { return false; } diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.h b/xbmc/windowing/egl/EGLNativeTypeIMX.h index 7769e79..694ef16 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.h +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.h @@ -23,6 +23,7 @@ #include #include "EGLNativeType.h" +#include "windowing/egl/vc_hdmi.h" class CEGLNativeTypeIMX : public CEGLNativeType { -- 2.7.1 From 7237b5b3af449eabba14dfe0dcb79f43d057d444 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 22 Sep 2015 00:29:17 +0200 Subject: [PATCH 125/250] Add new setting in Settings->Videos - Allow only modes with higher horizontal resolution than X Upstream-commit: 7bfd21bd0d5363e26a4ac0b3f4ee93659bb277fc --- .../resource.language.en_gb/resources/strings.po | 26 ++++++++++++++++++++++ system/settings/settings.xml | 18 +++++++++++++++ xbmc/cores/VideoRenderers/BaseRenderer.cpp | 3 +++ 3 files changed, 47 insertions(+) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 59f7ba2..62a02c3 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -18184,6 +18184,32 @@ msgctxt "#40006" msgid "If physical network parameters change (add/remove of network card or interface), automatically restart all Kodi services (sevices will re-read network settings and use new network parameters)" msgstr "" +msgctxt "#40007" +msgid "480p" +msgstr "" + +msgctxt "#40008" +msgid "576p" +msgstr "" + +msgctxt "#40009" +msgid "720p" +msgstr "" + +msgctxt "#40010" +msgid "900" +msgstr "" + +msgctxt "#40011" +msgid "1080p" +msgstr "" + +#. Label of setting "Settings -> Videos -> Minimum horizontal resolution" +#: system/settings/settings.xml +msgctxt "#40012" +msgid "Only modes having higher horizontal resolution" +msgstr "" + #. Label of setting "Settings -> Videos -> Allow non-CEA" #: system/settings/settings.xml msgctxt "#40013" diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 3cfd0cf..104bf30 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -612,6 +612,24 @@ + + 2 + 720 + true + + true + + + + + + + + + + + + 2 false diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp index cac81d6..114a05b 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp @@ -255,6 +255,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES { const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); if (!(info.dwFlags & D3DPRESENTFLAG_INTERLACED) + || CSettings::GetInstance().GetInt("videoplayer.minimumhorizontal") > info.iScreenHeight || (!CSettings::GetInstance().GetBool("videoplayer.adjustallownoncea") && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) || info.iScreenHeight != m_sourceHeight || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.11) @@ -271,6 +272,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); if ((fabs(info.fRefreshRate - fRefreshRate) > 0.001 && fabs(info.fRefreshRate - 2*fRefreshRate) > 0.001) || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.11 + || CSettings::GetInstance().GetInt("videoplayer.minimumhorizontal") > info.iScreenHeight || (info.dwFlags & D3DPRESENTFLAG_INTERLACED && !(m_iFlags & CONF_FLAGS_INTERLACED)) || (!CSettings::GetInstance().GetBool("videoplayer.adjustresolutioninterlaced") && (info.dwFlags & D3DPRESENTFLAG_INTERLACED)) || (!CSettings::GetInstance().GetBool("videoplayer.adjustallownoncea") && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) @@ -293,6 +295,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); if (m_sourceWidth > info.iScreenWidth || m_sourceHeight > info.iScreenHeight + || CSettings::GetInstance().GetInt("videoplayer.minimumhorizontal") > info.iScreenHeight || pow(info.iScreenWidth*info.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) > last_diff || info.iScreen != curr.iScreen || (!CSettings::GetInstance().GetBool("videoplayer.adjustallownoncea") && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) -- 2.7.1 From fb14cab6d478a5f36d1c26afb3c0dae19024f86e Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 27 Sep 2015 21:08:22 +0200 Subject: [PATCH 126/250] DVDVideoCodecIMX: merge SetFieldData() call into BlitAsync/BlitSync parameter. Inline whole function. (+small optimisations) Upstream-commit: f1aeb2c83c16ae6ec8e94d891b2b89b54ad1ed75 --- xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 3 +-- .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 17 +++++++---------- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 9 +++++---- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp index 7fd5b4c..ecce6d1 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp @@ -667,8 +667,7 @@ void CLinuxRendererGLES::RenderUpdateVideo(bool clear, DWORD flags, DWORD alpha) fieldFmt |= IPU_DEINTERLACE_RATE_FRAME1; } - g_IMXContext.SetFieldData(fieldFmt); - g_IMXContext.BlitAsync(NULL, buffer); + g_IMXContext.BlitAsync(NULL, buffer, fieldFmt); } #if 0 diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index f609145..4c07507 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1096,8 +1096,6 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) #endif m_frameCounter++; - pDvdVideoPicture->iFlags = 0; - pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED; if (m_initInfo.nInterlace) @@ -1554,17 +1552,13 @@ bool CIMXContext::SetVSync(bool enable) return true; } -bool CIMXContext::DoubleRate() const -{ - return m_currentFieldFmt & IPU_DEINTERLACE_RATE_EN; -} - void CIMXContext::SetBlitRects(const CRect &srcRect, const CRect &dstRect) { m_srcRect = srcRect; m_dstRect = dstRect; } +inline void CIMXContext::SetFieldData(uint8_t fieldFmt) { if (m_bStop || !IsRunning()) @@ -1588,20 +1582,23 @@ void CIMXContext::SetFieldData(uint8_t fieldFmt) AdaptScreen(); } -bool CIMXContext::Blit(int page, CIMXBuffer *source_p, CIMXBuffer *source) +bool CIMXContext::Blit(int page, CIMXBuffer *source_p, CIMXBuffer *source, uint8_t fieldFmt) { if (page < 0 || page >= m_fbPages) return false; IPUTask ipu; + + SetFieldData(fieldFmt); PrepareTask(ipu, source_p, source); return DoTask(ipu, page); } -bool CIMXContext::BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, CRect *dest) +bool CIMXContext::BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, uint8_t fieldFmt, CRect *dest) { IPUTask ipu; + SetFieldData(fieldFmt); PrepareTask(ipu, source_p, source, dest); return PushTask(ipu); } @@ -1980,7 +1977,7 @@ bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) { //We really use IPU only if we have to deinterlace (using VDIC) int ret = IPU_CHECK_ERR_INPUT_CROP; - while (ret != IPU_CHECK_OK && ret > IPU_CHECK_ERR_MIN) + while (ret > IPU_CHECK_ERR_MIN) { ret = ioctl(m_ipuHandle, IPU_CHECK_TASK, &ipu.task); switch (ret) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h index 2bb5f65..7266b25 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h @@ -110,8 +110,7 @@ public: bool GetPageInfo(CIMXBuffer *info, int page); // Blitter configuration - void SetFieldData(uint8_t fieldFmt); - bool DoubleRate() const; + bool IsDoubleRate() const { return m_currentFieldFmt & IPU_DEINTERLACE_RATE_EN; } void SetBlitRects(const CRect &srcRect, const CRect &dstRect); @@ -119,13 +118,13 @@ public: // source_p (previous buffer) is required for de-interlacing // modes LOW_MOTION and MED_MOTION. bool Blit(int targetPage, CIMXBuffer *source_p, - CIMXBuffer *source); + CIMXBuffer *source, uint8_t fieldFmt = 0); // Same as blit but runs in another thread and returns after the task has // been queued. BlitAsync renders always to the current backbuffer and // swaps the pages. bool BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, - CRect *dest = NULL); + uint8_t fieldFmt = 0, CRect *dest = NULL); // Shows a page vsynced bool ShowPage(int page); @@ -175,6 +174,8 @@ private: CRect *dest = NULL); bool DoTask(IPUTask &ipu, int targetPage); + void SetFieldData(uint8_t fieldFmt); + void Dispose(); void MemMap(struct fb_fix_screeninfo *fb_fix = NULL); -- 2.7.1 From 30c330c3a91a9b06c14c0a53139c745cbde73ae6 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 29 Sep 2015 04:39:31 +0200 Subject: [PATCH 127/250] Fix initialisation of variable Upstream-commit: d71c252f0c6385afad0600f48ed8541a88cd153c --- xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp index da4fb78..4c779fe 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp @@ -548,6 +548,7 @@ bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &r g_EGLEdid.CalcSAR(); + GetNativeResolution(&m_desktopRes); if(GETFLAGS_GROUP(m_desktopRes.dwFlags) && GETFLAGS_MODE(m_desktopRes.dwFlags)) { GetSupportedModes(HDMI_RES_GROUP_CEA, resolutions); -- 2.7.1 From a9cd6e68c060af238459d18a602aca390a80f4b6 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 29 Sep 2015 19:37:29 +0200 Subject: [PATCH 128/250] IMX: Use case insensitive matching for resolution type matching Upstream-commit: 37835706e8964eb7f13dbf9b93d7ccd3170096a7 --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 1a08305..24198ed 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -469,15 +469,15 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->dwFlags = MAKEFLAGS(HDMI_RES_GROUP_CEA, 0, 0); res->fPixelRatio = 1.0f; - if (StringUtils::StartsWith(mode, "H:")) { + if (StringUtils::StartsWithNoCase(mode, "H:")) { res->dwFlags |= D3DPRESENTFLAG_MODE3DSBS; res->fPixelRatio = 2.0f; - } else if (StringUtils::StartsWith(mode, "T:")) { + } else if (StringUtils::StartsWithNoCase(mode, "T:")) { res->dwFlags |= D3DPRESENTFLAG_MODE3DTB; res->fPixelRatio = 0.5f; - } else if (StringUtils::StartsWith(mode, "U:") || StringUtils::StartsWith(mode, "V:")) { + } else if (StringUtils::StartsWithNoCase(mode, "U:") || StringUtils::StartsWithNoCase(mode, "V:")) { res->dwFlags &= ~(MAKEFLAGS(HDMI_RES_GROUP_CEA, 0, 0)); - } else if (StringUtils::StartsWith(mode, "F:")) { + } else if (StringUtils::StartsWithNoCase(mode, "F:")) { return false; } -- 2.7.1 From 59c15e52c04a371784802b90fdef5a16e2780c32 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 30 Sep 2015 21:03:25 +0200 Subject: [PATCH 129/250] Fix edid - case of no EDID. SAR was provided correctly (1.0f), but was incorrectly used when setting PixelRatio resolution parameter Upstream-commit: 5980d9933ba0f153215bd1100e05329b70529076 --- xbmc/windowing/egl/EGLEdid.cpp | 9 ++++++++- xbmc/windowing/egl/EGLEdid.h | 1 + xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 2 +- xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 4 ++-- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/xbmc/windowing/egl/EGLEdid.cpp b/xbmc/windowing/egl/EGLEdid.cpp index 75e56d2..a740d30 100644 --- a/xbmc/windowing/egl/EGLEdid.cpp +++ b/xbmc/windowing/egl/EGLEdid.cpp @@ -22,6 +22,7 @@ #include "EGLEdid.h" #include "utils/log.h" #include "threads/SingleLock.h" +#include "settings/DisplaySettings.h" CEGLEdid g_EGLEdid; @@ -76,8 +77,14 @@ void CEGLEdid::CalcSAR() // SAR value wasn't sane if (m_fSar == 0) { + RESOLUTION_INFO res = CDisplaySettings::Get().GetCurrentResolutionInfo(); + CLog::Log(LOGWARNING, "%s: Screen SAR - not usable info",__FUNCTION__); - m_fSar = 1.0f; + + if (res.iScreenWidth != 0) + m_fSar = res.iScreenHeight / res.iScreenWidth; + else + m_fSar = .0f; } m_edidEmpty = false; diff --git a/xbmc/windowing/egl/EGLEdid.h b/xbmc/windowing/egl/EGLEdid.h index 71241b7..0483fb8 100644 --- a/xbmc/windowing/egl/EGLEdid.h +++ b/xbmc/windowing/egl/EGLEdid.h @@ -23,6 +23,7 @@ #include "threads/CriticalSection.h" #include "threads/SingleLock.h" #include +#include "guilib/GraphicContext.h" #define EDID_STRUCT_DISPLAY 0x14 #define EDID_DTM_START 0x36 diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 24198ed..f590aa8 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -505,7 +505,7 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->bFullScreen = true; res->iSubtitles = (int)(0.965 * res->iHeight); - res->fPixelRatio *= (float)g_EGLEdid.GetSAR() / res->iScreenWidth * res->iScreenHeight; + res->fPixelRatio *= (g_EGLEdid.GetSAR() ? (float)g_EGLEdid.GetSAR() / res->iScreenWidth * res->iScreenHeight : (float)1.0f); res->strMode = StringUtils::Format("%4sx%4s @ %.3f%s - Full Screen (%.3f) %s", StringUtils::Format("%d", res->iScreenWidth).c_str(), StringUtils::Format("%d", res->iScreenHeight).c_str(), res->fRefreshRate, res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : " ", res->fPixelRatio, diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp index 4c779fe..f003337 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp @@ -226,7 +226,7 @@ bool CEGLNativeTypeRaspberryPI::GetNativeResolution(RESOLUTION_INFO *res) const res->iScreenWidth = tv_state.display.hdmi.width; res->iScreenHeight= tv_state.display.hdmi.height; res->dwFlags = MAKEFLAGS(tv_state.display.hdmi.group, tv_state.display.hdmi.mode, tv_state.display.hdmi.scan_mode); - res->fPixelRatio = (float)g_EGLEdid.GetSAR() / ((float)res->iScreenWidth / (float)res->iScreenHeight); + res->fPixelRatio = g_EGLEdid.GetSAR() ? (float)g_EGLEdid.GetSAR() / ((float)res->iScreenWidth / (float)res->iScreenHeight) : 1.0f; // Also add 3D flags if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_SBS_HALF) { @@ -638,7 +638,7 @@ void CEGLNativeTypeRaspberryPI::GetSupportedModes(HDMI_RES_GROUP_T group, std::v res.iHeight = tv->height; res.iScreenWidth = tv->width; res.iScreenHeight = tv->height; - res.fPixelRatio = (float)g_EGLEdid.GetSAR() / ((float)res.iScreenWidth / (float)res.iScreenHeight); + res.fPixelRatio = g_EGLEdid.GetSAR() ? (float)g_EGLEdid.GetSAR() / ((float)res.iScreenWidth / (float)res.iScreenHeight) : 1.0f; res.iSubtitles = (int)(0.965 * res.iHeight); if (!m_desktopRes.dwFlags && prefer_group == group && prefer_mode == tv->code) -- 2.7.1 From d221fde75997f95f25fd98a3a4ef146a74c32c1a Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 10 Oct 2015 06:41:51 +0200 Subject: [PATCH 130/250] Screen: don't stop/start refclock on pause/unpause. Still stop/start it for all other actions. Upstream-commit: 2785772aecd9d7dbef6ad708ad5feef19cd2f86a --- xbmc/utils/Screen.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp index 50d9773..695fcfe 100644 --- a/xbmc/utils/Screen.cpp +++ b/xbmc/utils/Screen.cpp @@ -58,10 +58,12 @@ void CScreen::Announce(AnnouncementFlag flag, const char *sender, const char *me g_screen.SetOn(); else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && CSettings::Get().GetString("screensaver.mode") == "screensaver.xbmc.builtin.black") g_screen.SetOff(); +/* else if (flag == Player && !strcmp(sender, "xbmc") && !strcmp(message, "OnPlay")) g_VideoReferenceClock.Start(); else if (flag == Player && !strcmp(sender, "xbmc") && !strcmp(message, "OnPause")) g_VideoReferenceClock.Stop(); +*/ } void CScreen::ScreenPowerOff(bool doBlank) -- 2.7.1 From 19631dfa7cf8de33cb23399d0661a8897ef50c5c Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 11 Oct 2015 21:01:23 +0200 Subject: [PATCH 131/250] Application: simplify VT change operations Upstream-commit: 8f102ff6f3bb7c178d5442b345a02f728b97c45e --- xbmc/Application.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index b215ee4..259576b 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -4562,25 +4562,16 @@ void CApplication::checkVTchange() #endif SetRenderGUI(true); g_graphicsContext.SetFullScreenVideo(g_graphicsContext.IsFullScreenVideo()); - if (bRestartClock) - { - bRestartClock = false; - g_VideoReferenceClock.Start(); - } + g_VideoReferenceClock.Start(); } else { CLog::Log(LOGDEBUG,"%s : our VT being deactivated", __func__); SetRenderGUI(false); + g_VideoReferenceClock.Stop(); #ifdef HAS_IMXVPU g_IMXContext.Blank(); #endif - if (g_VideoReferenceClock.IsRunning()) - { - bRestartClock = true; - g_VideoReferenceClock.Stop(); - } - { CSingleLock lock(g_graphicsContext); g_graphicsContext.Clear(0); -- 2.7.1 From 912eadd6e1f967e608991df3f1d1887af72d46c4 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 18 Oct 2015 04:50:28 +0200 Subject: [PATCH 132/250] DVDVideoCodecIMX: readd original DoubleRate deint handling Upstream-commit: f42601dbf254972edb743b5c976726fb1f54d59b --- xbmc/cores/VideoRenderers/RenderManager.cpp | 4 ++++ xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp index 7a99ac4..21d60a8 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp @@ -715,7 +715,11 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L /* default to odd field if we want to deinterlace and don't know better */ if (deinterlacemode == VS_DEINTERLACEMODE_FORCE && sync == FS_NONE) +#ifdef HAS_IMXVPU + sync = FS_BOT; +#else sync = FS_TOP; +#endif /* invert present field */ if(invert) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 4c07507..42b3331 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1405,7 +1405,7 @@ bool CIMXContext::AdaptScreen() m_fbVar.xoffset = 0; m_fbVar.yoffset = 0; - if (0 && m_currentFieldFmt) + if (m_currentFieldFmt) { m_fbVar.nonstd = _4CC('U', 'Y', 'V', 'Y'); m_fbVar.bits_per_pixel = 16; @@ -1424,7 +1424,7 @@ bool CIMXContext::AdaptScreen() else m_fbVar.vmode &= ~FB_VMODE_INTERLACED; - m_fbVar.yres_virtual = (m_fbVar.yres + 0) * m_fbPages; + m_fbVar.yres_virtual = (m_fbVar.yres + 1) * m_fbPages; m_fbVar.xres_virtual = m_fbVar.xres; Blank(); @@ -1575,7 +1575,7 @@ void CIMXContext::SetFieldData(uint8_t fieldFmt) if (!!fieldFmt == deint) return; - CLog::Log(LOGDEBUG, "iMX : Deinterlacing parameters changed (%s)\n", !!fieldFmt ? "active" : "not active"); + CLog::Log(LOGDEBUG, "iMX : Deinterlacing parameters changed (%s) %s\n", !!fieldFmt ? "active" : "not active", IsDoubleRate() ? "DR" : ""); CSingleLock lk(m_pageSwapLock); m_bFbIsConfigured = false; @@ -1625,7 +1625,7 @@ bool CIMXContext::ShowPage(int page) m_fbVar.activate = FB_ACTIVATE_VBL; - m_fbVar.yoffset = (m_fbVar.yres + 0) * page; + m_fbVar.yoffset = (m_fbVar.yres + 1) * page; if (ioctl(m_fbHandle, FBIOPAN_DISPLAY, &m_fbVar) < 0) { CLog::Log(LOGWARNING, "Panning failed: %s\n", strerror(errno)); @@ -2022,7 +2022,7 @@ bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) } // Duplicate 2nd scandline if double rate is active - if (ipu.task.input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN) + if (IsDoubleRate()) { uint8_t *pageAddr = m_fbVirtAddr + targetPage*m_fbPageSize; memcpy(pageAddr, pageAddr+m_fbLineLength, m_fbLineLength); -- 2.7.1 From cd4d9a51aeb37509a03cfbb052df9a1366fac28d Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 19 Oct 2015 03:33:08 +0200 Subject: [PATCH 133/250] PeripheralVideo: make cablestatus variable static Upstream-commit: de81c2c9ef821f1f500a01362372390fd989d18d --- xbmc/peripherals/devices/PeripheralVideo.cpp | 3 ++- xbmc/peripherals/devices/PeripheralVideo.h | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/xbmc/peripherals/devices/PeripheralVideo.cpp b/xbmc/peripherals/devices/PeripheralVideo.cpp index 987c6bd..ea0d61d 100644 --- a/xbmc/peripherals/devices/PeripheralVideo.cpp +++ b/xbmc/peripherals/devices/PeripheralVideo.cpp @@ -33,9 +33,10 @@ using namespace PERIPHERALS; using namespace KODI::MESSAGING; +int CPeripheralVideo::m_cableState = 0; + CPeripheralVideo::CPeripheralVideo(const PeripheralScanResult& scanResult) : CPeripheral(scanResult) - , m_cableState(0) , m_timer(this) { m_features.push_back(FEATURE_CABLESTATE); diff --git a/xbmc/peripherals/devices/PeripheralVideo.h b/xbmc/peripherals/devices/PeripheralVideo.h index 2339bb1..e3a228f 100644 --- a/xbmc/peripherals/devices/PeripheralVideo.h +++ b/xbmc/peripherals/devices/PeripheralVideo.h @@ -37,7 +37,7 @@ namespace PERIPHERALS void OnSettingChanged(const std::string &strChangedSetting); bool InitialiseFeature(const PeripheralFeature feature); - bool IsQuantRangeLimited(); + static bool IsQuantRangeLimited(); static const char *stateToStr(const int state) { @@ -52,8 +52,9 @@ namespace PERIPHERALS } } + public: + static int m_cableState; protected: - int m_cableState; CTimer m_timer; }; -- 2.7.1 From 43dcdafec676f86decb7454de34c587899181b4b Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 26 Oct 2015 08:11:15 +0100 Subject: [PATCH 134/250] DisplaySettings: remove DESKTOP resolution from list, it is duplicity. Upstream-commit: 5d15ba0515dde39048853da2881178f9d6c60bc6 --- xbmc/settings/DisplaySettings.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp index 7993a73..dd7f6fb 100644 --- a/xbmc/settings/DisplaySettings.cpp +++ b/xbmc/settings/DisplaySettings.cpp @@ -683,7 +683,9 @@ void CDisplaySettings::SettingOptionsResolutionsFiller(const CSetting *setting, std::vector resolutions = g_Windowing.ScreenResolutions(info.iScreen, info.fRefreshRate); for (std::vector::const_iterator resolution = resolutions.begin(); resolution != resolutions.end(); ++resolution) { - list.push_back(std::make_pair( + if (resolution->ResInfo_Index == RES_DESKTOP) + continue; + list.push_back(make_pair( StringUtils::Format("%dx%d%s", resolution->width, resolution->height, ModeFlagsToString(resolution->flags, false).c_str()), resolution->ResInfo_Index)); -- 2.7.1 From d338edb3ee8dff31a11c25f80a8017aa607d75c0 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 26 Oct 2015 08:32:50 +0100 Subject: [PATCH 135/250] EGLNativeTypeIMX: on destroy() blank fb1, don't set previous mode as Splash is doing that. Upstream-commit: f0df4a5087015aaf93fab96ae64e777dd404e375 --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index f590aa8..7a136c2 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -180,8 +180,7 @@ void CEGLNativeTypeIMX::Destroy() } close(fd); - SetNativeResolution(m_init); - ShowWindow(true); + SysfsUtils::SetInt("/sys/class/graphics/fb1/blank", 1); system("/usr/bin/splash --force -i -m 'stopping kodi...'"); #endif -- 2.7.1 From a353d739c328f88b7ed130b5d95e6d5e98486d80 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 26 Oct 2015 08:33:42 +0100 Subject: [PATCH 136/250] EGLNativeTypeIMX: Upstream-commit: a75c77307a957c556a6be50a64245128f3dd4a48 - as per Kernel optimalisation on mode changes (when under Blank), blank FB sooner for quicker mode change --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 7a136c2..a7f34ef 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -306,10 +306,11 @@ bool CEGLNativeTypeIMX::SetNativeResolution(const RESOLUTION_INFO &res) return true; } + ShowWindow(false); + DestroyNativeWindow(); DestroyNativeDisplay(); - ShowWindow(false); CLog::Log(LOGDEBUG,": %s - changing resolution to %s", __FUNCTION__, res.strId.c_str()); SysfsUtils::SetString("/sys/class/graphics/fb0/mode", res.strId + "\n"); -- 2.7.1 From cc40388c6ae3bad8d9d1e44ee85ce979d33203aa Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 27 Oct 2015 21:57:48 +0100 Subject: [PATCH 137/250] OMX+MMAL: disable DEBUG VERBOSE logging (even when when we compile with DEBUG) Upstream-commit: b8129c6a00b5e99f7d7d1d5b54a8eb4528e8184d --- xbmc/cores/VideoRenderers/MMALRenderer.cpp | 1 + xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/xbmc/cores/VideoRenderers/MMALRenderer.cpp b/xbmc/cores/VideoRenderers/MMALRenderer.cpp index 2941d34..e428719 100644 --- a/xbmc/cores/VideoRenderers/MMALRenderer.cpp +++ b/xbmc/cores/VideoRenderers/MMALRenderer.cpp @@ -40,6 +40,7 @@ #define MMAL_DEBUG_VERBOSE #endif +#undef MMAL_DEBUG_VERBOSE CYUVVideoBuffer::CYUVVideoBuffer() { diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp index 87d97af..8a49483 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp @@ -92,6 +92,8 @@ do \ (a).nVersion.s.nRevision = OMX_VERSION_REVISION; \ (a).nVersion.s.nStep = OMX_VERSION_STEP +#undef OMX_DEBUG_VERBOSE + pthread_mutex_t m_omx_queue_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; COpenMaxVideo::COpenMaxVideo() -- 2.7.1 From d566f4b3ab9a61e145673142c06c1d77f18b8281 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 4 Nov 2015 06:14:23 +0100 Subject: [PATCH 138/250] EGLEdid: recognise if DTM block is not a DTM block and skip parsing it Upstream-commit: e8f1d1653394ab765ff4db1884741380241c721b --- xbmc/windowing/egl/EGLEdid.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xbmc/windowing/egl/EGLEdid.cpp b/xbmc/windowing/egl/EGLEdid.cpp index a740d30..89fffce 100644 --- a/xbmc/windowing/egl/EGLEdid.cpp +++ b/xbmc/windowing/egl/EGLEdid.cpp @@ -64,7 +64,9 @@ void CEGLEdid::CalcSAR() // enumerate through (max four) detailed timing info blocks // specs and lookup WxH [mm / in]. W and H are in 3 bytes, // where 1st = W, 2nd = H, 3rd byte is 4bit/4bit. - for (int i = EDID_DTM_START; i < 126 && m_fSar == 0; i += 18) + // + // if DTM block starts with 0 - it is not DTM, skip + for (int i = EDID_DTM_START; i < 126 && m_fSar == 0 && *(m_edid +i); i += 18) m_fSar = ValidateSAR((struct dt_dim *)(m_edid +i +EDID_DTM_OFFSET_DIMENSION), true); // fallback - info related to 'Basic display parameters.' is at offset 0x14-0x18. -- 2.7.1 From 0471b0c04e21ea783c702d45a84cf08dfa9f7beb Mon Sep 17 00:00:00 2001 From: Alex Deryskyba Date: Sun, 21 Sep 2014 17:20:25 +0300 Subject: [PATCH 139/250] Fix incorrect frame rate detection of some videos with variable frame rate. Upstream-commit: 2b8daf00159ccd08cb227ea9869a3f21f47e8d61 Use FFMPEG's r_frame_rate, if it as valid, as a video stream frame rate, otherwise use avg_frame_rate. Also remove CDVDStreamInfo.rfpsscale, CDVDStreamInfo.rfpsrate, CDemuxStreamVideo.irFpsScale and CDemuxStreamVideo.irFpsRate, they are not needed anymore. --- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h | 4 --- .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 29 ++++++++-------------- xbmc/cores/dvdplayer/DVDStreamInfo.cpp | 8 ------ xbmc/cores/dvdplayer/DVDStreamInfo.h | 2 -- 4 files changed, 10 insertions(+), 33 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h index e380056..d93b1dc 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h @@ -149,8 +149,6 @@ public: { iFpsScale = 0; iFpsRate = 0; - irFpsScale = 0; - irFpsRate = 0; iHeight = 0; iWidth = 0; fAspect = 0.0; @@ -165,8 +163,6 @@ public: virtual ~CDemuxStreamVideo() {} int iFpsScale; // scale of 1000 and a rate of 29970 will result in 29.97 fps int iFpsRate; - int irFpsScale; - int irFpsRate; int iHeight; // height of the stream reported by the demuxer int iWidth; // width of the stream reported by the demuxer float fAspect; // display aspect of stream diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index cc62a1e..75e6f79 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -1152,34 +1152,25 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) #else AVRational r_frame_rate = pStream->r_frame_rate; #endif + int rFrameRate = 0; + if (r_frame_rate.den && r_frame_rate.num) + rFrameRate = r_frame_rate.num / r_frame_rate.den; + bool rFrameRateValid = rFrameRate >= 5 && rFrameRate <= 100; - //average fps is more accurate for mkv files - if (m_bMatroska && pStream->avg_frame_rate.den && pStream->avg_frame_rate.num) - { - st->iFpsRate = pStream->avg_frame_rate.num; - st->iFpsScale = pStream->avg_frame_rate.den; - } - else if(r_frame_rate.den && r_frame_rate.num) + if (rFrameRateValid) { st->iFpsRate = r_frame_rate.num; st->iFpsScale = r_frame_rate.den; } - else - { - st->iFpsRate = 0; - st->iFpsScale = 0; - } - - // added for aml hw decoder, mkv frame-rate can be wrong. - if (r_frame_rate.den && r_frame_rate.num) + else if(pStream->avg_frame_rate.den && pStream->avg_frame_rate.num) { - st->irFpsRate = r_frame_rate.num; - st->irFpsScale = r_frame_rate.den; + st->iFpsRate = pStream->avg_frame_rate.num; + st->iFpsScale = pStream->avg_frame_rate.den; } else { - st->irFpsRate = 0; - st->irFpsScale = 0; + st->iFpsRate = 0; + st->iFpsScale = 0; } if (pStream->codec_info_nb_frames > 0 diff --git a/xbmc/cores/dvdplayer/DVDStreamInfo.cpp b/xbmc/cores/dvdplayer/DVDStreamInfo.cpp index fa0defa..b48cd61 100644 --- a/xbmc/cores/dvdplayer/DVDStreamInfo.cpp +++ b/xbmc/cores/dvdplayer/DVDStreamInfo.cpp @@ -51,8 +51,6 @@ void CDVDStreamInfo::Clear() fpsscale = 0; fpsrate = 0; - rfpsscale= 0; - rfpsrate = 0; height = 0; width = 0; aspect = 0.0; @@ -96,8 +94,6 @@ bool CDVDStreamInfo::Equal(const CDVDStreamInfo& right, bool withextradata) // VIDEO if( fpsscale != right.fpsscale || fpsrate != right.fpsrate - || rfpsscale!= right.rfpsscale - || rfpsrate != right.rfpsrate || height != right.height || width != right.width || stills != right.stills @@ -158,8 +154,6 @@ void CDVDStreamInfo::Assign(const CDVDStreamInfo& right, bool withextradata) // VIDEO fpsscale = right.fpsscale; fpsrate = right.fpsrate; - rfpsscale= right.rfpsscale; - rfpsrate = right.rfpsrate; height = right.height; width = right.width; aspect = right.aspect; @@ -219,8 +213,6 @@ void CDVDStreamInfo::Assign(const CDemuxStream& right, bool withextradata) const CDemuxStreamVideo *stream = static_cast(&right); fpsscale = stream->iFpsScale; fpsrate = stream->iFpsRate; - rfpsscale = stream->irFpsScale; - rfpsrate = stream->irFpsRate; height = stream->iHeight; width = stream->iWidth; aspect = stream->fAspect; diff --git a/xbmc/cores/dvdplayer/DVDStreamInfo.h b/xbmc/cores/dvdplayer/DVDStreamInfo.h index c0e22a2..8953ff3 100644 --- a/xbmc/cores/dvdplayer/DVDStreamInfo.h +++ b/xbmc/cores/dvdplayer/DVDStreamInfo.h @@ -58,8 +58,6 @@ public: // VIDEO int fpsscale; // scale of 1001 and a rate of 60000 will result in 59.94 fps int fpsrate; - int rfpsscale; - int rfpsrate; int height; // height of the stream reported by the demuxer int width; // width of the stream reported by the demuxer float aspect; // display aspect as reported by demuxer -- 2.7.1 From da1f0a7a9059ac08d235cfb53816d751a940745c Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 18 Nov 2015 22:28:37 +0100 Subject: [PATCH 140/250] Jarvis adapt ::Get() -> ::GetInstance() --- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 2 +- xbmc/peripherals/devices/PeripheralVideo.cpp | 6 +++--- xbmc/utils/Screen.cpp | 8 ++++---- xbmc/windowing/egl/EGLEdid.cpp | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 75e6f79..4422fed 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -445,7 +445,7 @@ bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo, bool filein if (m_streaminfo) { for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) - if (CSettings::Get().GetBool("audiooutput.supportdtshdcpudecoding")) + if (CSettings::GetInstance().GetBool("audiooutput.supportdtshdcpudecoding")) { AVStream *st = m_pFormatContext->streams[i]; if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == AV_CODEC_ID_DTS) diff --git a/xbmc/peripherals/devices/PeripheralVideo.cpp b/xbmc/peripherals/devices/PeripheralVideo.cpp index ea0d61d..9737129 100644 --- a/xbmc/peripherals/devices/PeripheralVideo.cpp +++ b/xbmc/peripherals/devices/PeripheralVideo.cpp @@ -100,10 +100,10 @@ void CPeripheralVideo::OnTimeout() case CABLE_CONNECTED: g_screen.SetOn(); - CSettings::Get().SetBool("videoscreen.limitedrange", IsQuantRangeLimited()); - if (CSettings::Get().GetBool("videoscreen.updateresolutions")) + CSettings::GetInstance().SetBool("videoscreen.limitedrange", IsQuantRangeLimited()); + if (CSettings::GetInstance().GetBool("videoscreen.updateresolutions")) { - CApplicationMessenger::Get().SetupDisplayReconfigure(); + CApplicationMessenger::GetInstance().PostMsg(TMSG_DISPLAY_RECONFIGURE); CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, "VIDEO", g_localizeStrings.Get(13288)); } diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp index 695fcfe..147f7d1 100644 --- a/xbmc/utils/Screen.cpp +++ b/xbmc/utils/Screen.cpp @@ -42,12 +42,12 @@ CScreen::CScreen() , m_changedBlank(false) , m_timer(this) { - CAnnouncementManager::Get().AddAnnouncer(this); + CAnnouncementManager::GetInstance().AddAnnouncer(this); } CScreen::~CScreen() { - CAnnouncementManager::Get().RemoveAnnouncer(this); + CAnnouncementManager::GetInstance().RemoveAnnouncer(this); } void CScreen::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) @@ -56,7 +56,7 @@ void CScreen::Announce(AnnouncementFlag flag, const char *sender, const char *me g_application.SetRenderGUI(true); else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverDeactivated")) g_screen.SetOn(); - else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && CSettings::Get().GetString("screensaver.mode") == "screensaver.xbmc.builtin.black") + else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && CSettings::GetInstance().GetString("screensaver.mode") == "screensaver.xbmc.builtin.black") g_screen.SetOff(); /* else if (flag == Player && !strcmp(sender, "xbmc") && !strcmp(message, "OnPlay")) @@ -68,7 +68,7 @@ void CScreen::Announce(AnnouncementFlag flag, const char *sender, const char *me void CScreen::ScreenPowerOff(bool doBlank) { - if (!doBlank || !CSettings::Get().GetBool("videoscreen.blankcurrent")) + if (!doBlank || !CSettings::GetInstance().GetBool("videoscreen.blankcurrent")) return; m_changedBlank = true; diff --git a/xbmc/windowing/egl/EGLEdid.cpp b/xbmc/windowing/egl/EGLEdid.cpp index 89fffce..0a82225 100644 --- a/xbmc/windowing/egl/EGLEdid.cpp +++ b/xbmc/windowing/egl/EGLEdid.cpp @@ -79,7 +79,7 @@ void CEGLEdid::CalcSAR() // SAR value wasn't sane if (m_fSar == 0) { - RESOLUTION_INFO res = CDisplaySettings::Get().GetCurrentResolutionInfo(); + RESOLUTION_INFO res = CDisplaySettings::GetInstance().GetCurrentResolutionInfo(); CLog::Log(LOGWARNING, "%s: Screen SAR - not usable info",__FUNCTION__); -- 2.7.1 From 90a7189337d0dfa622e2c79260c294c5d3b48e6d Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 18 Nov 2015 22:46:01 +0100 Subject: [PATCH 141/250] fix -> std:: --- xbmc/peripherals/bus/PeripheralBus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/peripherals/bus/PeripheralBus.cpp b/xbmc/peripherals/bus/PeripheralBus.cpp index 2b04702..bc44f7d 100644 --- a/xbmc/peripherals/bus/PeripheralBus.cpp +++ b/xbmc/peripherals/bus/PeripheralBus.cpp @@ -215,7 +215,7 @@ size_t CPeripheralBus::GetNumberOfPeripheralsWithId(const int iVendorId, const i size_t CPeripheralBus::GetNumberOfPeripheralsWithFeature(const PeripheralFeature feature) const { - vector peripherals; + std::vector peripherals; GetPeripheralsWithFeature(peripherals, feature); return peripherals.size(); } -- 2.7.1 From 876465544dc93fb7a0f509c6896e57301a772f9d Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 18 Nov 2015 23:15:31 +0100 Subject: [PATCH 142/250] configure.ac fix platforms settings & deps configuration --- configure.ac | 18 ++++++++++-------- m4/xbmc_arch.m4 | 4 ++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 562b435..a8b2014 100644 --- a/configure.ac +++ b/configure.ac @@ -728,8 +728,12 @@ case $use_platform in use_neon=no use_cpu=arm1176jzf-s extrarpiflags=rpi1 + CFLAGS="$CFLAGS -pipe -O3 -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " + CXXFLAGS="$CXXFLAGS -pipe -O3 -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " + FFMPEG_EXTRACFLAGS="$FFMPEG_EXTRACFLAGS -pipe -O3 -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " ;; cubox-i) + use_arch=armv7-a target_platform="cubox-i" use_static_ffmpeg=yes use_joystick=no @@ -742,10 +746,13 @@ case $use_platform in use_neon=yes ;; raspberry-pi2) + use_arch=armv7-a target_platform=target_raspberry_pi use_neon=yes use_cpu=cortex-a7 extrarpiflags=rpi2 + CFLAGS="$CFLAGS -pipe -O3 -march=armv7-a -mfloat-abi=hard -mfpu=neon -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " + CXXFLAGS="$CXXFLAGS -pipe -O3 -march=armv7-a -mfloat-abi=hard -mfpu=neon -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " ;; esac @@ -857,13 +864,7 @@ if test "$host_vendor" = "apple" ; then #arm/ios LIBS="$LIBS -framework CoreFoundation" fi -elif test "$target_platform" = "target_raspberry_pi"; then - ARCH="arm" - use_arch="arm" - CFLAGS="$CFLAGS -pipe -O3 -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " - CXXFLAGS="$CXXFLAGS -pipe -O3 -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " - FFMPEG_EXTRACFLAGS="$FFMPEG_EXTRACFLAGS -pipe -O3 -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -mabi=aapcs-linux -Wno-psabi -Wa,-mno-warn-deprecated -Wno-deprecated-declarations " -elif test "$use_arch" = "arm"; then +elif test "$use_arch" = "arm" || test "$ARCH" = "arm"; then CFLAGS="$CFLAGS -mno-apcs-stack-check" CXXFLAGS="$CXXFLAGS -mno-apcs-stack-check" if test "$use_tegra" = "yes"; then @@ -1193,7 +1194,8 @@ int main() { )]) AC_LANG_POP([C++]) -if test "${target_platform}" = "target_linux" || test "${target_platform}" = "target_raspberry_pi" || test "${target_platform}" = "target_android"; then +if test "${target_platform}" = "target_linux" || test "${target_platform}" = "target_raspberry_pi" || test "${target_platform}" = "target_android" || \ + test "${target_platform}" = "cubox-i"; then PKG_CHECK_MODULES([UUID], [uuid],, AC_MSG_ERROR(libuuid not found)) fi diff --git a/m4/xbmc_arch.m4 b/m4/xbmc_arch.m4 index fa08537..516d060 100644 --- a/m4/xbmc_arch.m4 +++ b/m4/xbmc_arch.m4 @@ -77,8 +77,8 @@ if test "$target_platform" = "target_android" ; then AC_SUBST(ARCH_DEFINES, "-DTARGET_POSIX -DTARGET_LINUX -D_LINUX -DTARGET_ANDROID") fi -case $use_platform in - raspberry-pi) +case $target_platform in + target_raspberry_pi) AC_SUBST(ARCH_DEFINES, "-DTARGET_POSIX -DTARGET_LINUX -D_LINUX -D_ARMEL -DTARGET_RASPBERRY_PI") ;; esac -- 2.7.1 From 8665bfa6b3606e413c6abe1803afbbc50bfbf0f4 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 18 Nov 2015 23:16:12 +0100 Subject: [PATCH 143/250] configure.ac fix changed syntax --- configure.ac | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index a8b2014..5d1cb6b 100644 --- a/configure.ac +++ b/configure.ac @@ -765,11 +765,9 @@ if test "$target_platform" = "target_raspberry_pi" ; then USE_MMAL=1; AC_DEFINE([HAS_MMAL],[1],["Define to 1 if MMAL libs is enabled"]) CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" - ;; else ARCH="arm" - ;; -esac +fi if test "$host_vendor" = "apple"; then use_avahi=no -- 2.7.1 From e5ea7c9c6e6ab5527f63e0d4e780c4ef5921976b Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 18 Nov 2015 23:16:39 +0100 Subject: [PATCH 144/250] configure.ac update rpi INCLUDES/LIBS --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 5d1cb6b..a90538c 100644 --- a/configure.ac +++ b/configure.ac @@ -1070,7 +1070,8 @@ if test "$use_gles" = "yes"; then AC_DEFINE([HAVE_LIBEGL],[1],["Define to 1 if you have the `EGL' library (-lEGL)."]) AC_DEFINE([HAVE_LIBGLESV2],[1],["Define to 1 if you have the `GLESv2' library (-lGLESv2)."]) AC_MSG_RESULT(== WARNING: OpenGLES support is assumed.) - LIBS="$LIBS -lEGL -lGLESv2 -lbcm_host -lvcos -lvchiq_arm -lmmal -lmmal_core -lmmal_util" + INCLUDES="-I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux/ -I/opt/vc/include/interface/vcos/pthreads $INCLUDES" + LIBS="$LIBS -L/opt/vc/lib -lEGL -lGLESv2 -lbcm_host -lvcos -lvchiq_arm -lmmal -lmmal_core -lmmal_util -lvcsm" elif test "$target_platform" = "cubox-i"; then AC_DEFINE([HAVE_LIBEGL],[1],["Define to 1 if you have the `EGL' library (-lEGL)."]) AC_DEFINE([HAVE_LIBGLESV2],[1],["Define to 1 if you have the `GLESv2' library (-lGLESv2)."]) -- 2.7.1 From 06e90031490623ca409a20828680486b32a98dcb Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 18 Nov 2015 23:17:15 +0100 Subject: [PATCH 145/250] configure.ac libgif not able to get soname, change to simple LIBS=-lgif --- configure.ac | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index a90538c..2075b40 100644 --- a/configure.ac +++ b/configure.ac @@ -1560,9 +1560,7 @@ if test "$use_libgif" != "no"; then USE_LIBGIF=0 fi ]) - if test "$use_libgif" != "no"; then - XB_FIND_SONAME([GIF], [gif], [use_libgif]) - fi + LIBS=$LIBS -lgif if test "$use_libgif" != "no"; then AC_DEFINE([HAVE_LIBGIF], [1], [Whether to use libgif library.]) USE_LIBGIF=1 -- 2.7.1 From 67ba49e9278d6f879ad805f0f1e53dc0d6ce731a Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 15 Nov 2015 16:57:04 +0100 Subject: [PATCH 146/250] Revert "Fix incorrect frame rate detection of some videos with variable frame rate." This reverts commit 2b8daf00159ccd08cb227ea9869a3f21f47e8d61. --- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h | 4 +++ .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 29 ++++++++++++++-------- xbmc/cores/dvdplayer/DVDStreamInfo.cpp | 8 ++++++ xbmc/cores/dvdplayer/DVDStreamInfo.h | 2 ++ 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h index d93b1dc..e380056 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h @@ -149,6 +149,8 @@ public: { iFpsScale = 0; iFpsRate = 0; + irFpsScale = 0; + irFpsRate = 0; iHeight = 0; iWidth = 0; fAspect = 0.0; @@ -163,6 +165,8 @@ public: virtual ~CDemuxStreamVideo() {} int iFpsScale; // scale of 1000 and a rate of 29970 will result in 29.97 fps int iFpsRate; + int irFpsScale; + int irFpsRate; int iHeight; // height of the stream reported by the demuxer int iWidth; // width of the stream reported by the demuxer float fAspect; // display aspect of stream diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 4422fed..2e7ee0c 100644 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -1152,27 +1152,36 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) #else AVRational r_frame_rate = pStream->r_frame_rate; #endif - int rFrameRate = 0; - if (r_frame_rate.den && r_frame_rate.num) - rFrameRate = r_frame_rate.num / r_frame_rate.den; - bool rFrameRateValid = rFrameRate >= 5 && rFrameRate <= 100; - if (rFrameRateValid) - { - st->iFpsRate = r_frame_rate.num; - st->iFpsScale = r_frame_rate.den; - } - else if(pStream->avg_frame_rate.den && pStream->avg_frame_rate.num) + //average fps is more accurate for mkv files + if (m_bMatroska && pStream->avg_frame_rate.den && pStream->avg_frame_rate.num) { st->iFpsRate = pStream->avg_frame_rate.num; st->iFpsScale = pStream->avg_frame_rate.den; } + else if(r_frame_rate.den && r_frame_rate.num) + { + st->iFpsRate = r_frame_rate.num; + st->iFpsScale = r_frame_rate.den; + } else { st->iFpsRate = 0; st->iFpsScale = 0; } + // added for aml hw decoder, mkv frame-rate can be wrong. + if (r_frame_rate.den && r_frame_rate.num) + { + st->irFpsRate = r_frame_rate.num; + st->irFpsScale = r_frame_rate.den; + } + else + { + st->irFpsRate = 0; + st->irFpsScale = 0; + } + if (pStream->codec_info_nb_frames > 0 && pStream->codec_info_nb_frames <= 2 && m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)) diff --git a/xbmc/cores/dvdplayer/DVDStreamInfo.cpp b/xbmc/cores/dvdplayer/DVDStreamInfo.cpp index b48cd61..fa0defa 100644 --- a/xbmc/cores/dvdplayer/DVDStreamInfo.cpp +++ b/xbmc/cores/dvdplayer/DVDStreamInfo.cpp @@ -51,6 +51,8 @@ void CDVDStreamInfo::Clear() fpsscale = 0; fpsrate = 0; + rfpsscale= 0; + rfpsrate = 0; height = 0; width = 0; aspect = 0.0; @@ -94,6 +96,8 @@ bool CDVDStreamInfo::Equal(const CDVDStreamInfo& right, bool withextradata) // VIDEO if( fpsscale != right.fpsscale || fpsrate != right.fpsrate + || rfpsscale!= right.rfpsscale + || rfpsrate != right.rfpsrate || height != right.height || width != right.width || stills != right.stills @@ -154,6 +158,8 @@ void CDVDStreamInfo::Assign(const CDVDStreamInfo& right, bool withextradata) // VIDEO fpsscale = right.fpsscale; fpsrate = right.fpsrate; + rfpsscale= right.rfpsscale; + rfpsrate = right.rfpsrate; height = right.height; width = right.width; aspect = right.aspect; @@ -213,6 +219,8 @@ void CDVDStreamInfo::Assign(const CDemuxStream& right, bool withextradata) const CDemuxStreamVideo *stream = static_cast(&right); fpsscale = stream->iFpsScale; fpsrate = stream->iFpsRate; + rfpsscale = stream->irFpsScale; + rfpsrate = stream->irFpsRate; height = stream->iHeight; width = stream->iWidth; aspect = stream->fAspect; diff --git a/xbmc/cores/dvdplayer/DVDStreamInfo.h b/xbmc/cores/dvdplayer/DVDStreamInfo.h index 8953ff3..c0e22a2 100644 --- a/xbmc/cores/dvdplayer/DVDStreamInfo.h +++ b/xbmc/cores/dvdplayer/DVDStreamInfo.h @@ -58,6 +58,8 @@ public: // VIDEO int fpsscale; // scale of 1001 and a rate of 60000 will result in 59.94 fps int fpsrate; + int rfpsscale; + int rfpsrate; int height; // height of the stream reported by the demuxer int width; // width of the stream reported by the demuxer float aspect; // display aspect as reported by demuxer -- 2.7.1 From 15953076e3c237005cdd436c818b948f916438e8 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 19 Nov 2015 07:51:00 +0100 Subject: [PATCH 147/250] RenderManager: fix framewait() --- xbmc/cores/VideoRenderers/RenderManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp index 21d60a8..077adcb 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp @@ -342,7 +342,8 @@ void CXBMCRenderManager::FrameWait(int ms) bool CXBMCRenderManager::HasFrame() { CSingleLock lock(m_presentlock); - if (m_presentstep == PRESENT_FRAME || m_presentstep == PRESENT_FRAME2) + if (m_presentstep == PRESENT_READY || + m_presentstep == PRESENT_FRAME || m_presentstep == PRESENT_FRAME2) return true; else return false; -- 2.7.1 From f93cf30d0be7daa7879a4b06aa3ddaf363271059 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 19 Nov 2015 07:51:54 +0100 Subject: [PATCH 148/250] RenderManager: fix top/bot on deinterlacing forced --- xbmc/cores/VideoRenderers/RenderManager.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp index 077adcb..b229d16 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp @@ -714,21 +714,24 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L else if (interlacemethod == VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE) presentmethod = PRESENT_METHOD_BOB; else presentmethod = PRESENT_METHOD_SINGLE; - /* default to odd field if we want to deinterlace and don't know better */ - if (deinterlacemode == VS_DEINTERLACEMODE_FORCE && sync == FS_NONE) + if (presentmethod != PRESENT_METHOD_SINGLE) + { + /* default to odd field if we want to deinterlace and don't know better */ + if (deinterlacemode == VS_DEINTERLACEMODE_FORCE && sync == FS_NONE) #ifdef HAS_IMXVPU - sync = FS_BOT; + sync = FS_BOT; #else - sync = FS_TOP; + sync = FS_TOP; #endif - /* invert present field */ - if(invert) - { - if( sync == FS_BOT ) - sync = FS_TOP; - else - sync = FS_BOT; + /* invert present field */ + if(invert) + { + if( sync == FS_BOT ) + sync = FS_TOP; + else + sync = FS_BOT; + } } } } -- 2.7.1 From b14ca2b7d86ddc2ce6c8cfb1ff8872685684cff0 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 23 Nov 2015 14:00:08 +0100 Subject: [PATCH 149/250] crossguid: fix Makefile --- tools/depends/target/crossguid/Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/depends/target/crossguid/Makefile b/tools/depends/target/crossguid/Makefile index 487ab2a..fe072c0 100644 --- a/tools/depends/target/crossguid/Makefile +++ b/tools/depends/target/crossguid/Makefile @@ -37,9 +37,7 @@ LIBDYLIB=$(PLATFORM)/lib$(LIBNAME).a .PHONY: .installed-$(PLATFORM) -all: .installed-$(PLATFORM) $(PREFIX)/lib/lib$(LIBNAME).a -$(PREFIX)/lib/lib$(LIBNAME).a: - @make .installed-$(PLATFORM) +all: .installed-$(PLATFORM) $(LIBDYLIB) $(TARBALLS_LOCATION)/$(ARCHIVE): cd $(TARBALLS_LOCATION); $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE) -- 2.7.1 From 92ee37a2097a24b311cc90b3c0d75cd1a08e73a8 Mon Sep 17 00:00:00 2001 From: mkreisl Date: Tue, 24 Nov 2015 02:58:00 +0100 Subject: [PATCH 150/250] Fix to handle given addons list correctly --- project/cmake/addons/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/project/cmake/addons/CMakeLists.txt b/project/cmake/addons/CMakeLists.txt index 36d9340..115d8ae 100644 --- a/project/cmake/addons/CMakeLists.txt +++ b/project/cmake/addons/CMakeLists.txt @@ -121,7 +121,6 @@ if(NOT ADDONS_TO_BUILD) set(ADDONS_TO_BUILD "all") else() message(STATUS "Building following addons: ${ADDONS_TO_BUILD}") - separate_arguments(ADDONS_TO_BUILD) endif() if(NOT ADDONS_DEFINITION_DIR) @@ -217,6 +216,8 @@ if(NOT addons) endif() endif() +separate_arguments(ADDONS_TO_BUILD) + foreach(addon ${addons}) if(NOT (addon MATCHES platforms.txt)) file(STRINGS ${addon} def) -- 2.7.1 From 022b7c164a219cf935567cb0da4b632c03ddcb65 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 24 Nov 2015 11:24:20 +0100 Subject: [PATCH 151/250] CSettings: fix leftover "network.restartservices" in settings class --- xbmc/network/Network.cpp | 2 +- xbmc/settings/Settings.cpp | 1 + xbmc/settings/Settings.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index 56e0b86..08ddb74 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -419,7 +419,7 @@ void CNetwork::NetworkMessage(EMESSAGE message, int param) case NETWORK_CHANGED: m_signalNetworkChange.Set(); ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::Network, "network", "OnInterfacesChange"); - if (CSettings::GetInstance().GetBool("network.restartservices")) + if (CSettings::GetInstance().GetBool(CSettings::SETTING_NETWORK_RESTARTSERVICES)) { CLog::Log(LOGDEBUG, "%s - Network setup changed. Will restart network services",__FUNCTION__); NetworkMessage(SERVICES_DOWN, 0); diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp index def16e0..58fe858 100644 --- a/xbmc/settings/Settings.cpp +++ b/xbmc/settings/Settings.cpp @@ -379,6 +379,7 @@ const std::string CSettings::SETTING_NETWORK_HTTPPROXYPORT = "network.httpproxyp const std::string CSettings::SETTING_NETWORK_HTTPPROXYUSERNAME = "network.httpproxyusername"; const std::string CSettings::SETTING_NETWORK_HTTPPROXYPASSWORD = "network.httpproxypassword"; const std::string CSettings::SETTING_NETWORK_BANDWIDTH = "network.bandwidth"; +const std::string CSettings::SETTING_NETWORK_RESTARTSERVICES = "network.restartservices"; const std::string CSettings::SETTING_POWERMANAGEMENT_DISPLAYSOFF = "powermanagement.displaysoff"; const std::string CSettings::SETTING_POWERMANAGEMENT_SHUTDOWNTIME = "powermanagement.shutdowntime"; const std::string CSettings::SETTING_POWERMANAGEMENT_SHUTDOWNSTATE = "powermanagement.shutdownstate"; diff --git a/xbmc/settings/Settings.h b/xbmc/settings/Settings.h index 55e150d..ab3a029 100644 --- a/xbmc/settings/Settings.h +++ b/xbmc/settings/Settings.h @@ -335,6 +335,7 @@ public: static const std::string SETTING_NETWORK_HTTPPROXYUSERNAME; static const std::string SETTING_NETWORK_HTTPPROXYPASSWORD; static const std::string SETTING_NETWORK_BANDWIDTH; + static const std::string SETTING_NETWORK_RESTARTSERVICES; static const std::string SETTING_POWERMANAGEMENT_DISPLAYSOFF; static const std::string SETTING_POWERMANAGEMENT_SHUTDOWNTIME; static const std::string SETTING_POWERMANAGEMENT_SHUTDOWNSTATE; -- 2.7.1 From 2fa838e7de6a4f854ab4beb6e4374772f38faf24 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 24 Nov 2015 11:42:22 +0100 Subject: [PATCH 152/250] configure.ac: LIBS=xx xx needs to be inside brackets --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 2075b40..709d68a 100644 --- a/configure.ac +++ b/configure.ac @@ -1560,7 +1560,7 @@ if test "$use_libgif" != "no"; then USE_LIBGIF=0 fi ]) - LIBS=$LIBS -lgif + LIBS="$LIBS -lgif " if test "$use_libgif" != "no"; then AC_DEFINE([HAVE_LIBGIF], [1], [Whether to use libgif library.]) USE_LIBGIF=1 -- 2.7.1 From dd83662623cfa9bd0f36bd92e7c5c74ad7e91577 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 26 Nov 2015 03:57:33 +0100 Subject: [PATCH 153/250] Jarvis settings fixes. --- addons/resource.language.en_gb/resources/strings.po | 4 ++-- system/settings/settings.xml | 2 +- xbmc/cores/VideoRenderers/BaseRenderer.cpp | 18 +++++++++--------- xbmc/settings/Settings.cpp | 4 ++++ xbmc/settings/Settings.h | 4 ++++ 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 62a02c3..519ecaf 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -18204,10 +18204,10 @@ msgctxt "#40011" msgid "1080p" msgstr "" -#. Label of setting "Settings -> Videos -> Minimum horizontal resolution" +#. Label of setting "Settings -> Videos -> Minimum vertical resolution" #: system/settings/settings.xml msgctxt "#40012" -msgid "Only modes having higher horizontal resolution" +msgid "Only modes having higher vertical resolution" msgstr "" #. Label of setting "Settings -> Videos -> Allow non-CEA" diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 104bf30..6e77d35 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -612,7 +612,7 @@ - + 2 720 true diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp index 114a05b..42e6796 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp @@ -245,18 +245,18 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES int loop_diff = 0; // CHANGERESOLUTION - if (CSettings::GetInstance().GetBool("videoplayer.adjustresolution")) + if (CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTRESOLUTION)) { bool i_found = false; // if interlaced mode - if (m_iFlags & CONF_FLAGS_INTERLACED && CSettings::GetInstance().GetBool("videoplayer.adjustresolutioninterlaced")) + if (m_iFlags & CONF_FLAGS_INTERLACED && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTRESOLUTIONINTERLACED)) for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::GetInstance().ResolutionInfoSize(); i++) { const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); if (!(info.dwFlags & D3DPRESENTFLAG_INTERLACED) - || CSettings::GetInstance().GetInt("videoplayer.minimumhorizontal") > info.iScreenHeight - || (!CSettings::GetInstance().GetBool("videoplayer.adjustallownoncea") && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) + || CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_MINIMUMVERTICAL) > info.iScreenHeight + || (!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) || info.iScreenHeight != m_sourceHeight || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.11) continue; @@ -272,10 +272,10 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); if ((fabs(info.fRefreshRate - fRefreshRate) > 0.001 && fabs(info.fRefreshRate - 2*fRefreshRate) > 0.001) || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.11 - || CSettings::GetInstance().GetInt("videoplayer.minimumhorizontal") > info.iScreenHeight + || CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_MINIMUMVERTICAL) > info.iScreenHeight || (info.dwFlags & D3DPRESENTFLAG_INTERLACED && !(m_iFlags & CONF_FLAGS_INTERLACED)) - || (!CSettings::GetInstance().GetBool("videoplayer.adjustresolutioninterlaced") && (info.dwFlags & D3DPRESENTFLAG_INTERLACED)) - || (!CSettings::GetInstance().GetBool("videoplayer.adjustallownoncea") && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) + || (!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTRESOLUTIONINTERLACED) && (info.dwFlags & D3DPRESENTFLAG_INTERLACED)) + || (!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) || m_sourceWidth > info.iScreenWidth || m_sourceHeight > info.iScreenHeight || pow(info.iScreenWidth*info.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) > last_diff) continue; @@ -295,10 +295,10 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); if (m_sourceWidth > info.iScreenWidth || m_sourceHeight > info.iScreenHeight - || CSettings::GetInstance().GetInt("videoplayer.minimumhorizontal") > info.iScreenHeight + || CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_MINIMUMVERTICAL) > info.iScreenHeight || pow(info.iScreenWidth*info.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) > last_diff || info.iScreen != curr.iScreen - || (!CSettings::GetInstance().GetBool("videoplayer.adjustallownoncea") && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) + || (!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK)) { /* CLog::Log(LOGDEBUG, "curr %.2f, trying %.2f, mode nr. %d, %dx%d msk %d, m_msk %d", info.fPixelRatio, curr.fPixelRatio, i, diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp index 58fe858..2888bce 100644 --- a/xbmc/settings/Settings.cpp +++ b/xbmc/settings/Settings.cpp @@ -181,6 +181,10 @@ const std::string CSettings::SETTING_VIDEOPLAYER_USEVDA = "videoplayer.usevda"; const std::string CSettings::SETTING_VIDEOPLAYER_USEMMAL = "videoplayer.usemmal"; const std::string CSettings::SETTING_VIDEOPLAYER_USESTAGEFRIGHT = "videoplayer.usestagefright"; const std::string CSettings::SETTING_VIDEOPLAYER_LIMITGUIUPDATE = "videoplayer.limitguiupdate"; +const std::string CSettings::SETTING_VIDEOPLAYER_ADJUSTRESOLUTION = "videoplayer.adjustresolution"; +const std::string CSettings::SETTING_VIDEOPLAYER_ADJUSTRESOLUTIONINTERLACED = "videoplayer.adjustresolutioninterlaced"; +const std::string CSettings::SETTING_VIDEOPLAYER_MINIMUMVERTICAL = "videoplayer.minimumvertical"; +const std::string CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA = "videoplayer.adjustallownoncea"; const std::string CSettings::SETTING_MYVIDEOS_SELECTACTION = "myvideos.selectaction"; const std::string CSettings::SETTING_MYVIDEOS_EXTRACTFLAGS = "myvideos.extractflags"; const std::string CSettings::SETTING_MYVIDEOS_EXTRACTCHAPTERTHUMBS = "myvideos.extractchapterthumbs"; diff --git a/xbmc/settings/Settings.h b/xbmc/settings/Settings.h index ab3a029..de7a695 100644 --- a/xbmc/settings/Settings.h +++ b/xbmc/settings/Settings.h @@ -137,6 +137,10 @@ public: static const std::string SETTING_VIDEOPLAYER_USEMMAL; static const std::string SETTING_VIDEOPLAYER_USESTAGEFRIGHT; static const std::string SETTING_VIDEOPLAYER_LIMITGUIUPDATE; + static const std::string SETTING_VIDEOPLAYER_ADJUSTRESOLUTION; + static const std::string SETTING_VIDEOPLAYER_ADJUSTRESOLUTIONINTERLACED; + static const std::string SETTING_VIDEOPLAYER_MINIMUMVERTICAL; + static const std::string SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA; static const std::string SETTING_MYVIDEOS_SELECTACTION; static const std::string SETTING_MYVIDEOS_EXTRACTFLAGS; static const std::string SETTING_MYVIDEOS_EXTRACTCHAPTERTHUMBS; -- 2.7.1 From 961a4f146ba978cd2daac82faae958498b4b6526 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 26 Nov 2015 11:19:30 +0100 Subject: [PATCH 154/250] Fix crash on start if SDTV is used (cherry picked from commit eb1effb52f3985e86e567493d86fa7fe2573920a) Signed-off-by: Matus Kral --- xbmc/cores/VideoRenderers/BaseRenderer.cpp | 3 +++ xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp index 42e6796..f354053 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp @@ -229,6 +229,9 @@ void CBaseRenderer::FindResolutionFromFpsMatch(float fps, float& weight) RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RESOLUTION current, float& weight) { + if (CDisplaySettings::GetInstance().ResolutionInfoSize() < 2) + return current; + RESOLUTION_INFO curr = g_graphicsContext.GetResInfo(current); RESOLUTION orig_res = CDisplaySettings::GetInstance().GetCurrentResolution(); diff --git a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp index f003337..bb12eae 100644 --- a/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp @@ -554,6 +554,10 @@ bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector &r GetSupportedModes(HDMI_RES_GROUP_CEA, resolutions); GetSupportedModes(HDMI_RES_GROUP_DMT, resolutions); } + { + AddUniqueResolution(m_desktopRes, resolutions); + CLog::Log(LOGDEBUG, "EGL probe resolution %s:%x\n", m_desktopRes.strMode.c_str(), m_desktopRes.dwFlags); + } DLOG("CEGLNativeTypeRaspberryPI::ProbeResolutions\n"); return true; -- 2.7.1 From 97688dc6609accbeb670b98bfbdc170e4ee68e8f Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 28 Nov 2015 09:37:29 +0100 Subject: [PATCH 155/250] remove leftover from rebase --- xbmc/network/linux/NetworkLinux.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 16d1302..2b49777 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -323,7 +323,6 @@ CNetworkLinux::CNetworkLinux(void) { m_sock = socket(AF_INET, SOCK_DGRAM, 0); queryInterfaceList(); - NetworkMessage(NETWORK_CHANGED, 0); RegisterWatcher(WatcherProcess); CApplicationMessenger::GetInstance().PostMsg(TMSG_NETWORKMESSAGE, CNetwork::SERVICES_UP, 0); } -- 2.7.1 From fec61a11da7ae265c051b32efbdfd326e2c83c57 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 28 Nov 2015 09:27:47 +0100 Subject: [PATCH 156/250] - m_lock in CNetwork - rename it to be clear on purpose, reuse in win32, remove definition from win32. (cherry picked from commit 8321b231d19e3edacbec20bbd0fe0b4af9b5b555) --- xbmc/network/Network.h | 2 +- xbmc/network/linux/NetworkLinux.cpp | 4 ++-- xbmc/network/windows/NetworkWin32.cpp | 20 +++++++++----------- xbmc/network/windows/NetworkWin32.h | 7 +++---- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index 470c78f..8396fe4 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -377,7 +377,7 @@ public: virtual bool ForceRereadInterfaces() = 0; protected: - CCriticalSection m_lock; + CCriticalSection m_lockInterfaces; private: CEvent m_signalNetworkChange; diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 2b49777..245a5ea 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -332,7 +332,7 @@ CNetworkLinux::~CNetworkLinux(void) if (m_sock != -1) close(CNetworkLinux::m_sock); - CSingleLock lock(m_lock); + CSingleLock lock(m_lockInterfaces); InterfacesClear(); DeleteRemoved(); } @@ -408,7 +408,7 @@ bool CNetworkLinux::queryInterfaceList() { bool change = false; - CSingleLock lock(m_lock); + CSingleLock lock(m_lockInterfaces); // Query the list of interfaces. struct ifaddrs *list; diff --git a/xbmc/network/windows/NetworkWin32.cpp b/xbmc/network/windows/NetworkWin32.cpp index b731eb9..3e90b68 100644 --- a/xbmc/network/windows/NetworkWin32.cpp +++ b/xbmc/network/windows/NetworkWin32.cpp @@ -155,24 +155,20 @@ CNetworkWin32::CNetworkWin32(void) CNetworkWin32::~CNetworkWin32(void) { - CleanInterfaceList(); m_netrefreshTimer.Stop(); + CleanInterfaceList(); } void CNetworkWin32::CleanInterfaceList() { - std::vector::iterator it = m_interfaces.begin(); - while(it != m_interfaces.end()) - { - CNetworkInterface* nInt = *it; - delete nInt; - it = m_interfaces.erase(it); - } + CSingleLock lock (m_lockInterfaces); + auto it = m_interfaces.before_begin(); + m_interfaces.erase_after(it, m_interfaces.end()); } -std::vector& CNetworkWin32::GetInterfaceList(void) +std::forward_list& CNetworkWin32::GetInterfaceList(void) { - CSingleLock lock (m_critSection); + CSingleLock lock (m_lockInterfaces); if(m_netrefreshTimer.GetElapsedSeconds() >= 5.0f) queryInterfaceList(); @@ -186,6 +182,7 @@ void CNetworkWin32::queryInterfaceList() PIP_ADAPTER_INFO adapterInfo; PIP_ADAPTER_INFO adapter = NULL; + auto *pos = m_interfaces.before_begin(); ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO); @@ -206,7 +203,8 @@ void CNetworkWin32::queryInterfaceList() adapter = adapterInfo; while (adapter) { - m_interfaces.push_back(new CNetworkInterfaceWin32(this, *adapter)); + m_interfaces.insert_after(pos, new CNetworkInterfaceWin32(this, *adapter)); + ++pos; adapter = adapter->Next; } } diff --git a/xbmc/network/windows/NetworkWin32.h b/xbmc/network/windows/NetworkWin32.h index 8477156..1994326 100644 --- a/xbmc/network/windows/NetworkWin32.h +++ b/xbmc/network/windows/NetworkWin32.h @@ -22,10 +22,10 @@ #include #include +#include #include "network/Network.h" #include "Iphlpapi.h" #include "utils/stopwatch.h" -#include "threads/CriticalSection.h" class CNetworkWin32; @@ -71,7 +71,7 @@ public: virtual ~CNetworkWin32(void); // Return the list of interfaces - virtual std::vector& GetInterfaceList(void); + virtual std::forward_list& GetInterfaceList(void); // Ping remote host virtual bool PingHostImpl(const std::string &target, unsigned int timeout_ms = 2000); @@ -87,10 +87,9 @@ private: int GetSocket() { return m_sock; } void queryInterfaceList(); void CleanInterfaceList(); - std::vector m_interfaces; + std::forward_list m_interfaces; int m_sock; CStopWatch m_netrefreshTimer; - CCriticalSection m_critSection; }; #endif -- 2.7.1 From 08ad804d481905919b4f79c2831359dd8c81b75d Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 1 Dec 2015 18:24:55 +0100 Subject: [PATCH 157/250] remove unused variable --- xbmc/Application.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 259576b..03ee961 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -4544,7 +4544,6 @@ void CApplication::checkVTchange() { struct vt_stat vts; static int last_active; - static bool bRestartClock; int cur_tty = open("/dev/tty0", O_RDONLY | O_NONBLOCK | O_NOCTTY); if(cur_tty < 0 || ioctl(cur_tty, VT_GETSTATE, &vts) < 0) -- 2.7.1 From b57bb5ca7f249bc1e7241a184a2eef241e8c335b Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 2 Dec 2015 11:01:52 +0100 Subject: [PATCH 158/250] Add fallback for NETLINK netwatch (cherry picked from commit f8cb1e09887d75c9f6fb2e1aad0da9190166b168) --- xbmc/network/linux/NetworkLinux.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 245a5ea..8642986 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -1150,18 +1150,24 @@ void WatcherProcess() #endif if (-1 == bind(fds, (const struct sockaddr *) &addr, sizeof(struct sockaddr))) - return; - - fcntl(fds, F_SETFL, O_NONBLOCK); + { + close(fds); + fds = 0; + } + else + fcntl(fds, F_SETFL, O_NONBLOCK); while(!stopping) if (poll(&m_fds, 1, 1000) > 0) { - while (!stopping && recv(fds, &msg, sizeof(msg), 0) > 0); + while (!stopping && fds && recv(fds, &msg, sizeof(msg), 0) > 0); if (stopping) continue; - if (!g_application.getNetwork().ForceRereadInterfaces()) + if (!fds) + g_application.getNetwork().m_updThread->Sleep(5000); + + if (stopping || !g_application.getNetwork().ForceRereadInterfaces()) continue; CLog::Log(LOGINFO, "Interfaces change %s", __FUNCTION__); -- 2.7.1 From 1b5bd5733eab44d6b26a077f04602a6e9d155a73 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 2 Dec 2015 11:02:17 +0100 Subject: [PATCH 159/250] - OSX/FreeBSD fixes - fix FreeBSD/OSX MacAddr fetch - fix NetworkInterfaceLinux::IsConnected() (cherry picked from commit f443f3d1b2467666d968dea5e9bd75c8bc54add2) --- xbmc/network/linux/NetworkLinux.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 8642986..44ebf9c 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -138,7 +138,9 @@ bool CNetworkInterfaceLinux::IsConnected() if (IsRemoved() || m_interfaceFlags & IFF_LOOPBACK) return false; - unsigned int needFlags = IFF_RUNNING | IFF_LOWER_UP; + // Don't add IFF_LOWER_UP - looks it is driver dependent on Linux + // and missing on running interfaces on OSX (Maverick tested) + unsigned int needFlags = IFF_RUNNING; //IFF_LOWER_UP bool iRunning = (m_interfaceFlags & needFlags) == needFlags; // return only interfaces which has ip address @@ -415,6 +417,10 @@ bool CNetworkLinux::queryInterfaceList() if (getifaddrs(&list) < 0) return false; +#if !defined(TARGET_LINUX) + std::map t_hwaddrs; +#endif + DeleteRemoved(); InterfacesClear(); @@ -431,6 +437,15 @@ bool CNetworkLinux::queryInterfaceList() struct ifaddrs *cur; for(cur = list; cur != NULL; cur = cur->ifa_next) { + std::string name = cur->ifa_name; +#if !defined(TARGET_LINUX) + if(cur->ifa_addr->sa_family == AF_LINK) + { + struct ifaddrs &t = *cur; + t_hwaddrs[name] = t; + } +#endif + if(!cur->ifa_addr || (cur->ifa_addr->sa_family != AF_INET && cur->ifa_addr->sa_family != AF_INET6)) @@ -442,7 +457,6 @@ bool CNetworkLinux::queryInterfaceList() // Add the interface. std::string addr = CNetwork::GetIpStr(cur->ifa_addr); std::string mask = CNetwork::GetIpStr(cur->ifa_netmask); - std::string name = cur->ifa_name; if(addr.empty() || mask.empty()) continue; @@ -456,7 +470,11 @@ bool CNetworkLinux::queryInterfaceList() } char macAddrRaw[6] = {0}; +#if !defined(TARGET_LINUX) + GetMacAddress(&t_hwaddrs[name], macAddrRaw); +#else GetMacAddress(cur, macAddrRaw); +#endif CNetworkInterfaceLinux *i = new CNetworkInterfaceLinux(this, cur->ifa_addr->sa_family == AF_INET6, cur->ifa_flags, addr, mask, name, macAddrRaw); -- 2.7.1 From 55bc4f8e5574234c7ee3b333efab947c11ac1cd1 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 3 Dec 2015 23:00:28 +0100 Subject: [PATCH 160/250] when FB is going blank/off, we will loose video + audio this leads Kodi to timeout, resync, error, hard error -> collapse (specially on 1cpu systems) - this changes should avoid such case. - don't poweroff screen if player is active (audio/video) - in CEC settings add option to "action on TV power off" which will just apply same action as setting "action on switching source" - changed default configuration on "action on TV power off" from suspend to this new value - changed default configuration on "action on switching source" from pause to stop (mostly due to PVR/timeshift) - reordered this two settings --- .../resource.language.en_gb/resources/strings.po | 7 ++++- system/peripherals.xml | 8 +++--- xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 30 ++++++++++++++++------ xbmc/peripherals/devices/PeripheralCecAdapter.h | 2 ++ xbmc/utils/Screen.cpp | 2 ++ 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 519ecaf..0cd205a 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -5445,7 +5445,12 @@ msgctxt "#13005" msgid "Shutdown" msgstr "" -#empty strings from id 13006 to 13007 +#empty strings from id 13006 + +#: system/peripherals.xml +msgctxt "#13007" +msgid "Same as \"switching source\"" +msgstr "" #: system/settings/settings.xml msgctxt "#13008" diff --git a/system/peripherals.xml b/system/peripherals.xml index 1a31659..1431fda 100644 --- a/system/peripherals.xml +++ b/system/peripherals.xml @@ -16,11 +16,11 @@ - - - + + + + - diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index dfd9bef..99ecaf1 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -644,7 +644,11 @@ int CPeripheralCecAdapter::CecCommand(void *cbParam, const cec_command command) g_application.ExecuteXBMCAction("Shutdown"); } if (command.initiator == CECDEVICE_TV) + { + if (adapter->GetSettingInt("standby_pc_on_tv_standby") == 13007) + CecEventPostAction(cbParam, 0, true); g_screen.SetOff(); + } break; case CEC_OPCODE_SET_MENU_LANGUAGE: if (adapter->m_configuration.bUseTVMenuLanguage == 1 && command.initiator == CECDEVICE_TV && command.parameters.size == 3) @@ -1156,16 +1160,13 @@ void CPeripheralCecAdapter::OnSettingChanged(const std::string &strChangedSettin } } -void CPeripheralCecAdapter::CecSourceActivated(void *cbParam, const CEC::cec_logical_address address, const uint8_t activated) + +void CPeripheralCecAdapter::CecEventPostAction(void *cbParam, const uint8_t activated, bool wait) { CPeripheralCecAdapter *adapter = (CPeripheralCecAdapter *)cbParam; if (!adapter) return; - // wake up the screensaver, so the user doesn't switch to a black screen - if (activated == 1) - g_application.WakeUpScreenSaverAndDPMS(); - if (adapter->GetSettingInt("pause_or_stop_playback_on_deactivate") != LOCALISED_ID_NONE) { bool bShowingSlideshow = (g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW); @@ -1187,16 +1188,29 @@ void CPeripheralCecAdapter::CecSourceActivated(void *cbParam, const CEC::cec_log pSlideShow->OnAction(CAction(ACTION_PAUSE)); else // pause/resume player - CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_PAUSE); + CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_PAUSE, wait); } else if (adapter->GetSettingInt("pause_or_stop_playback_on_deactivate") == LOCALISED_ID_STOP) { if (pSlideShow) pSlideShow->OnAction(CAction(ACTION_STOP)); else - CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_STOP); + CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_STOP, wait); } } +} + +void CPeripheralCecAdapter::CecSourceActivated(void *cbParam, const CEC::cec_logical_address address, const uint8_t activated) +{ + CPeripheralCecAdapter *adapter = (CPeripheralCecAdapter *)cbParam; + if (!adapter) + return; + + // wake up the screensaver, so the user doesn't switch to a black screen + if (activated == 1) + g_application.WakeUpScreenSaverAndDPMS(); + + CecEventPostAction(cbParam, activated, true); if (activated != 1) g_screen.SetOff(); @@ -1303,7 +1317,7 @@ void CPeripheralCecAdapter::SetConfigurationFromLibCEC(const CEC::libcec_configu bChanged |= SetSetting("standby_pc_on_tv_standby", m_configuration.bPowerOffOnStandby == 1 ? 13011 : - m_configuration.bShutdownOnStandby == 1 ? 13005 : 36028); + m_configuration.bShutdownOnStandby == 1 ? 13005 : GetSettingInt("standby_pc_on_tv_standby")); if (bChanged) CLog::Log(LOGDEBUG, "SetConfigurationFromLibCEC - settings updated by libCEC"); diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.h b/xbmc/peripherals/devices/PeripheralCecAdapter.h index 8e21ccc..e55d3f1 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.h +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.h @@ -144,6 +144,8 @@ namespace PERIPHERALS bool GetAudioSystemConnected(); void SetMenuLanguage(const char *strLanguage); + static void CecEventPostAction(void *cbParam, const uint8_t activated, bool wait); + // callbacks from libCEC static int CecLogMessage(void *cbParam, const CEC::cec_log_message message); static int CecCommand(void *cbParam, const CEC::cec_command command); diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp index 147f7d1..eead168 100644 --- a/xbmc/utils/Screen.cpp +++ b/xbmc/utils/Screen.cpp @@ -117,6 +117,8 @@ void CScreen::SetState(bool state, bool doBlank) switch (state) { case true: + if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPausedPlayback()) + break; g_VideoReferenceClock.Stop(); if (!g_application.IsInScreenSaver()) -- 2.7.1 From d37bfba7fa77c36ce63042ecdd645e94dd57d17a Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 4 Dec 2015 01:07:21 +0100 Subject: [PATCH 161/250] add support for NTSC modes/timings controlled via sysfs fb control file 'ntsc_mode' --- xbmc/guilib/Resolution.h | 3 +- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 79 ++++++++++++++++++++++++++++----- xbmc/windowing/egl/EGLNativeTypeIMX.h | 4 ++ 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/xbmc/guilib/Resolution.h b/xbmc/guilib/Resolution.h index acc7ceb..dcfacdc 100644 --- a/xbmc/guilib/Resolution.h +++ b/xbmc/guilib/Resolution.h @@ -95,6 +95,7 @@ struct RESOLUTION_INFO uint32_t dwFlags; float fPixelRatio; float fRefreshRate; + float refresh_rate; std::string strMode; std::string strOutput; std::string strId; @@ -127,6 +128,6 @@ public: iScreenWidth = res.iScreenWidth; iScreenHeight = res.iScreenHeight; iSubtitles = res.iSubtitles; dwFlags = res.dwFlags; fPixelRatio = res.fPixelRatio; fRefreshRate = res.fRefreshRate; - iBlanking = res.iBlanking; + refresh_rate = res.refresh_rate; iBlanking = res.iBlanking; } }; diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index a7f34ef..2978eda 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -40,6 +40,7 @@ #include "windowing/WindowingFactory.h" #include "cores/AudioEngine/AEFactory.h" #include +#include #include "peripherals/Peripherals.h" #include "peripherals/bus/linux/PeripheralBusPLATFORMLibUdev.h" @@ -51,6 +52,7 @@ CEGLNativeTypeIMX::CEGLNativeTypeIMX() #ifdef HAS_IMXVPU : m_display(NULL) , m_window(NULL) + , m_ntsc(0) #endif { #ifdef HAS_IMXVPU @@ -180,6 +182,8 @@ void CEGLNativeTypeIMX::Destroy() } close(fd); + if (!m_readonly) + SysfsUtils::SetString("/sys/class/graphics/fb0/mode", m_init.strId + "\n"); SysfsUtils::SetInt("/sys/class/graphics/fb1/blank", 1); system("/usr/bin/splash --force -i -m 'stopping kodi...'"); @@ -279,6 +283,21 @@ bool CEGLNativeTypeIMX::DestroyNativeWindow() #endif } +#ifdef HAS_IMXVPU +bool ntsc_mode() +{ + std::ifstream file("/sys/class/graphics/fb0/ntsc_mode"); + return file.is_open(); +} + +bool get_ntsc() +{ + std::string mode; + SysfsUtils::GetString("/sys/class/graphics/fb0/ntsc_mode", mode); + return mode.find("active") != std::string::npos; +} +#endif + bool CEGLNativeTypeIMX::GetNativeResolution(RESOLUTION_INFO *res) const { #ifdef HAS_IMXVPU @@ -286,7 +305,14 @@ bool CEGLNativeTypeIMX::GetNativeResolution(RESOLUTION_INFO *res) const SysfsUtils::GetString("/sys/class/graphics/fb0/mode", mode); CLog::Log(LOGDEBUG,": %s, %s", __FUNCTION__, mode.c_str()); - return ModeToResolution(mode, res); + bool ret = ModeToResolution(mode, res); + if (ntsc_mode() && get_ntsc()) + res->fRefreshRate = (float)res->refresh_rate * (1000.0f/1001.0f); + else if (!ntsc_mode()) + return ret; + + SetStrMode(res); + return ret; #else return false; #endif @@ -299,19 +325,32 @@ bool CEGLNativeTypeIMX::SetNativeResolution(const RESOLUTION_INFO &res) return false; std::string mode; + int new_ntsc; + + if (ntsc_mode()) + new_ntsc = fabs(res.refresh_rate - res.fRefreshRate) < FLT_EPSILON ? 0 : 1; + else + new_ntsc = 0; + SysfsUtils::GetString("/sys/class/graphics/fb0/mode", mode); - if (res.strId == mode) + + if (res.strId == mode && m_ntsc == new_ntsc) { - CLog::Log(LOGDEBUG,": %s - not changing res (%s vs %s)", __FUNCTION__, res.strId.c_str(), mode.c_str()); + CLog::Log(LOGDEBUG,": %s - not changing res (%s vs %s)%s", __FUNCTION__, res.strId.c_str(), mode.c_str(), new_ntsc ? " mode NTSC" : ""); return true; } - ShowWindow(false); - DestroyNativeWindow(); DestroyNativeDisplay(); - CLog::Log(LOGDEBUG,": %s - changing resolution to %s", __FUNCTION__, res.strId.c_str()); + if (ntsc_mode()) + { + SysfsUtils::SetInt("/sys/class/graphics/fb0/ntsc_mode", new_ntsc); + m_ntsc = new_ntsc; + } + + ShowWindow(false); + CLog::Log(LOGDEBUG,": %s - changing resolution to %s%s", __FUNCTION__, res.strId.c_str(), new_ntsc ? " mode NTSC" : ""); SysfsUtils::SetString("/sys/class/graphics/fb0/mode", res.strId + "\n"); CreateNativeDisplay(); @@ -369,7 +408,19 @@ bool CEGLNativeTypeIMX::ProbeResolutions(std::vector &resolutio if(ModeToResolution(probe_str[i], &res)) if(!FindMatchingResolution(res, resolutions)) + { resolutions.push_back(res); + if (!ntsc_mode()) + continue; + + if (res.refresh_rate == 24 || res.refresh_rate == 30 || res.refresh_rate == 60) + { + RESOLUTION_INFO res2 = res; + res2.fRefreshRate = (float)res.refresh_rate * (1000.0f/1001.0f); + SetStrMode(&res2); + resolutions.push_back(res2); + } + } } return resolutions.size() > 0; #else @@ -452,6 +503,14 @@ bool CEGLEdid::ReadEdidData() return true; } +void CEGLNativeTypeIMX::SetStrMode(RESOLUTION_INFO *res) const +{ + res->strMode = StringUtils::Format("%4sx%4s @ %.3f%s - Full Screen (%.3f) %s", StringUtils::Format("%d", res->iScreenWidth).c_str(), + StringUtils::Format("%d", res->iScreenHeight).c_str(), res->fRefreshRate, + res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : " ", res->fPixelRatio, + res->dwFlags & D3DPRESENTFLAG_MODE3DSBS ? "- 3DSBS" : res->dwFlags & D3DPRESENTFLAG_MODE3DTB ? "- 3DTB" : ""); +} + bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) const { if (!res) @@ -495,10 +554,11 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->iHeight= h; res->iScreenWidth = w; res->iScreenHeight= h; - if (StringUtils::isasciilowercaseletter(mode[0])) + if (!ntsc_mode() && StringUtils::isasciilowercaseletter(mode[0])) res->fRefreshRate = (float)r * 1000 / 1001; else res->fRefreshRate = (float)r; + res->refresh_rate = (float)r; res->dwFlags |= p[0] == 'p' ? D3DPRESENTFLAG_PROGRESSIVE : D3DPRESENTFLAG_INTERLACED; res->iScreen = 0; @@ -506,11 +566,8 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->iSubtitles = (int)(0.965 * res->iHeight); res->fPixelRatio *= (g_EGLEdid.GetSAR() ? (float)g_EGLEdid.GetSAR() / res->iScreenWidth * res->iScreenHeight : (float)1.0f); - res->strMode = StringUtils::Format("%4sx%4s @ %.3f%s - Full Screen (%.3f) %s", StringUtils::Format("%d", res->iScreenWidth).c_str(), - StringUtils::Format("%d", res->iScreenHeight).c_str(), res->fRefreshRate, - res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : " ", res->fPixelRatio, - res->dwFlags & D3DPRESENTFLAG_MODE3DSBS ? "- 3DSBS" : res->dwFlags & D3DPRESENTFLAG_MODE3DTB ? "- 3DTB" : ""); res->strId = mode; + SetStrMode(res); return res->iWidth > 0 && res->iHeight> 0; } diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.h b/xbmc/windowing/egl/EGLNativeTypeIMX.h index 694ef16..ead9dfe 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.h +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.h @@ -61,5 +61,9 @@ protected: EGLNativeDisplayType m_display; EGLNativeWindowType m_window; + +private: + void SetStrMode(RESOLUTION_INFO *res) const; + int m_ntsc; #endif }; -- 2.7.1 From 4b1cc20e5b07e65871788461599661a400eb1215 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 5 Dec 2015 13:18:28 +0100 Subject: [PATCH 162/250] reorder restoreresolution & splash calls in destructor --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 2978eda..84cdc87 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -182,11 +182,11 @@ void CEGLNativeTypeIMX::Destroy() } close(fd); + system("/usr/bin/splash --force -i -m 'stopping kodi...'"); + if (!m_readonly) SysfsUtils::SetString("/sys/class/graphics/fb0/mode", m_init.strId + "\n"); SysfsUtils::SetInt("/sys/class/graphics/fb1/blank", 1); - - system("/usr/bin/splash --force -i -m 'stopping kodi...'"); #endif return; } -- 2.7.1 From 5644c8794b08d2417833a5783c8bf854ac0471be Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 5 Dec 2015 18:33:54 +0100 Subject: [PATCH 163/250] AESinkALSA: change error handling in AddPackets() --- xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp index 21b4b6e..09d9f8c 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp @@ -928,16 +928,12 @@ unsigned int CAESinkALSA::AddPackets(uint8_t **data, unsigned int frames, unsign if (ret < 0) { CLog::Log(ret == -32 ? LOGDEBUG : LOGERROR, "CAESinkALSA - snd_pcm_writei(%d) %s - trying to recover", ret, snd_strerror(ret)); - ret = snd_pcm_recover(m_pcm, ret, 1); - if(ret < 0) + HandleError("snd_pcm_writei(1)", ret); + ret = snd_pcm_writei(m_pcm, buffer, amount); + if (ret < 0) { - HandleError("snd_pcm_writei(1)", ret); - ret = snd_pcm_writei(m_pcm, buffer, amount); - if (ret < 0) - { - HandleError("snd_pcm_writei(2)", ret); - ret = 0; - } + HandleError("snd_pcm_writei(2)", ret); + ret = 0; } } -- 2.7.1 From ea9ac3bcca38ca29fa699e6c876e52749ce58897 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 5 Dec 2015 20:54:30 +0100 Subject: [PATCH 164/250] get limited colours from FB settings --- xbmc/windowing/WinSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/windowing/WinSystem.cpp b/xbmc/windowing/WinSystem.cpp index 5d67639..457acc7 100644 --- a/xbmc/windowing/WinSystem.cpp +++ b/xbmc/windowing/WinSystem.cpp @@ -242,7 +242,7 @@ REFRESHRATE CWinSystemBase::DefaultRefreshRate(int screen, std::vectorGetValue(); #else -- 2.7.1 From 10f7e086360fc209d04004a7f5e0c4e4a0ad1b0a Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 28 Nov 2015 09:39:12 +0100 Subject: [PATCH 165/250] Auto framelimiter after 3s of user inactivity. - there is no wakeup delay - actual fps is taken from settings->video->accel->gui fps --- xbmc/Application.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 03ee961..40ac680 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -2858,13 +2858,19 @@ void CApplication::FrameMove(bool processEvents, bool processGUI) if (processGUI && m_renderGUI) { m_skipGuiRender = false; + int idleSeconds = 3; int fps = 0; #if defined(TARGET_RASPBERRY_PI) || defined(HAS_IMXVPU) // This code reduces rendering fps of the GUI layer when playing videos in fullscreen mode // it makes only sense on architectures with multiple layers - if (g_graphicsContext.IsFullScreenVideo() && !m_pPlayer->IsPausedPlayback() && g_renderManager.IsVideoLayer()) + idleSeconds *= !(g_graphicsContext.IsFullScreenVideo() && !m_pPlayer->IsPausedPlayback() && g_renderManager.IsVideoLayer()); +#endif + if ((idleSeconds && m_screenSaverTimer.GetElapsedSeconds() > idleSeconds) || !idleSeconds) +#if defined(TARGET_RASPBERRY_PI) || defined(HAS_IMXVPU) fps = CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_LIMITGUIUPDATE); +#else + fps = 5; #endif unsigned int now = XbmcThreads::SystemClockMillis(); -- 2.7.1 From 27332a147cdc74eae7abc227bcd01965049ed2cf Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 4 Dec 2015 22:16:46 +0100 Subject: [PATCH 166/250] - remove network api calls from wakeonlan, use new CNetwork API (cherry picked from commit 858ee60cdaa113f01c14f537a6f7d85a2f612257) --- xbmc/network/Network.cpp | 11 +++++++++++ xbmc/network/Network.h | 1 + xbmc/network/WakeOnAccess.cpp | 21 ++++++++------------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index 08ddb74..a91f9a5 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -182,6 +182,17 @@ std::string CNetwork::GetIpStr(unsigned long address) return addr; } +bool CNetworkInterface::GetHostMacAddress(const std::string &host, std::string &mac) +{ + struct sockaddr_in in; + + if (!CNetwork::ConvIPv4(host, &in)) + return false; + + unsigned long ip = in.sin_addr.s_addr; + return GetHostMacAddress(ip, mac); +} + int CNetwork::ParseHex(char *str, unsigned char *addr) { int len = 0; diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index 8396fe4..3cdb0f3 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -90,6 +90,7 @@ public: virtual void GetMacAddressRaw(char rawMac[6]) = 0; virtual bool GetHostMacAddress(unsigned long host, std::string& mac) = 0; + bool GetHostMacAddress(const std::string &host, std::string& mac); virtual std::string GetCurrentIPAddress() = 0; virtual std::string GetCurrentNetmask() = 0; diff --git a/xbmc/network/WakeOnAccess.cpp b/xbmc/network/WakeOnAccess.cpp index a93f76c..ce780e9 100644 --- a/xbmc/network/WakeOnAccess.cpp +++ b/xbmc/network/WakeOnAccess.cpp @@ -59,11 +59,11 @@ static int GetTotalSeconds(const CDateTimeSpan& ts) return ts.GetSeconds() + minutes * 60; } -static unsigned long HostToIP(const std::string& host) +std::string HostToIP(const std::string& host) { std::string ip; CDNSNameCache::Lookup(host, ip); - return inet_addr(ip.c_str()); + return ip; } CWakeOnAccess::WakeUpEntry::WakeUpEntry (bool isAwake) @@ -98,9 +98,9 @@ private: bool CMACDiscoveryJob::DoWork() { - unsigned long ipAddress = HostToIP(m_host); + std::string ipAddress = HostToIP(m_host); - if (ipAddress == INADDR_NONE) + if (ipAddress.empty()) { CLog::Log(LOGERROR, "%s - can't determine ip of '%s'", __FUNCTION__, m_host.c_str()); return false; @@ -231,8 +231,7 @@ public: } virtual bool SuccessWaiting () const { - unsigned long address = ntohl(HostToIP(m_host)); - bool online = g_application.getNetwork().HasInterfaceForIP(address); + bool online = g_application.getNetwork().HasInterfaceForIP(m_host); if (!online) // setup endtime so we dont return true until network is consistently connected m_end.Set (m_settle_time_ms); @@ -273,9 +272,7 @@ public: static bool Ping (const CWakeOnAccess::WakeUpEntry& server) { - ULONG dst_ip = HostToIP(server.host); - - return g_application.getNetwork().PingHost(dst_ip, server.ping_port, 2000, server.ping_mode & 1); + return g_application.getNetwork().PingHost(server.host, server.ping_port, 2000, server.ping_mode & 1); } private: @@ -368,7 +365,7 @@ bool CWakeOnAccess::WakeUpHost(const WakeUpEntry& server) if (dlg.ShowAndWait (waitObj, m_netinit_sec, LOCALIZED(13028)) != ProgressDialogHelper::Success) { - if (g_application.getNetwork().IsConnected() && HostToIP(server.host) == INADDR_NONE) + if (g_application.getNetwork().IsConnected() && HostToIP(server.host).empty()) { // network connected (at least one interface) but dns-lookup failed (host by name, not ip-address), so dont abort yet CLog::Log(LOGWARNING, "WakeOnAccess timeout/cancel while waiting for network (proceeding anyway)"); @@ -382,9 +379,7 @@ bool CWakeOnAccess::WakeUpHost(const WakeUpEntry& server) } { - ULONG dst_ip = HostToIP(server.host); - - if (g_application.getNetwork().PingHost(dst_ip, server.ping_port, 500)) // quick ping with short timeout to not block too long + if (g_application.getNetwork().PingHost(HostToIP(server.host), server.ping_port, 500)) // quick ping with short timeout to not block too long { CLog::Log(LOGNOTICE,"WakeOnAccess success exit, server already running"); return true; -- 2.7.1 From ab6ffa721daa1b10bfabacd479a832099c6bc533 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 6 Dec 2015 00:12:09 +0100 Subject: [PATCH 167/250] - move HostToIp() to CDNSNameCache / rename to Lookup() - rename all calls accordingly - remove Lookup() failure logging (as this is logged in CDNSNameCache itself) --- xbmc/network/DNSNameCache.cpp | 8 ++++++++ xbmc/network/DNSNameCache.h | 1 + xbmc/network/WakeOnAccess.cpp | 16 +++------------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/xbmc/network/DNSNameCache.cpp b/xbmc/network/DNSNameCache.cpp index 7d79bd6..f9881b0 100644 --- a/xbmc/network/DNSNameCache.cpp +++ b/xbmc/network/DNSNameCache.cpp @@ -152,6 +152,14 @@ bool CDNSNameCache::Lookup(const std::string& strHostName, std::string& strIpAdd return bReturn; } +std::string CDNSNameCache::Lookup(const std::string& strHostName) +{ + std::string ip; + + Lookup(strHostName, ip); + return ip; +} + bool CDNSNameCache::GetCached(const std::string& strHostName, std::string& strIpAddress) { CSingleLock lock(m_critical); diff --git a/xbmc/network/DNSNameCache.h b/xbmc/network/DNSNameCache.h index 86afcfd..18c7afa 100644 --- a/xbmc/network/DNSNameCache.h +++ b/xbmc/network/DNSNameCache.h @@ -38,6 +38,7 @@ public: CDNSNameCache(void); virtual ~CDNSNameCache(void); static bool Lookup(const std::string& strHostName, std::string& strIpAddress); + static std::string Lookup(const std::string& strHostName); static void Add(const std::string& strHostName, const std::string& strIpAddress); void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data); diff --git a/xbmc/network/WakeOnAccess.cpp b/xbmc/network/WakeOnAccess.cpp index ce780e9..b257aa0 100644 --- a/xbmc/network/WakeOnAccess.cpp +++ b/xbmc/network/WakeOnAccess.cpp @@ -59,13 +59,6 @@ static int GetTotalSeconds(const CDateTimeSpan& ts) return ts.GetSeconds() + minutes * 60; } -std::string HostToIP(const std::string& host) -{ - std::string ip; - CDNSNameCache::Lookup(host, ip); - return ip; -} - CWakeOnAccess::WakeUpEntry::WakeUpEntry (bool isAwake) : timeout (0, 0, 0, DEFAULT_TIMEOUT_SEC) , wait_online1_sec(DEFAULT_WAIT_FOR_ONLINE_SEC_1) @@ -98,13 +91,10 @@ private: bool CMACDiscoveryJob::DoWork() { - std::string ipAddress = HostToIP(m_host); + std::string ipAddress = CDNSNameCache::Lookup(m_host); if (ipAddress.empty()) - { - CLog::Log(LOGERROR, "%s - can't determine ip of '%s'", __FUNCTION__, m_host.c_str()); return false; - } for (auto &&iface : g_application.getNetwork().GetInterfaceList()) if (iface->GetHostMacAddress(ipAddress, m_macAddres)) @@ -365,7 +355,7 @@ bool CWakeOnAccess::WakeUpHost(const WakeUpEntry& server) if (dlg.ShowAndWait (waitObj, m_netinit_sec, LOCALIZED(13028)) != ProgressDialogHelper::Success) { - if (g_application.getNetwork().IsConnected() && HostToIP(server.host).empty()) + if (g_application.getNetwork().IsConnected() && CDNSNameCache::Lookup(server.host).empty()) { // network connected (at least one interface) but dns-lookup failed (host by name, not ip-address), so dont abort yet CLog::Log(LOGWARNING, "WakeOnAccess timeout/cancel while waiting for network (proceeding anyway)"); @@ -379,7 +369,7 @@ bool CWakeOnAccess::WakeUpHost(const WakeUpEntry& server) } { - if (g_application.getNetwork().PingHost(HostToIP(server.host), server.ping_port, 500)) // quick ping with short timeout to not block too long + if (g_application.getNetwork().PingHost(CDNSNameCache::Lookup(server.host), server.ping_port, 500)) // quick ping with short timeout to not block too long { CLog::Log(LOGNOTICE,"WakeOnAccess success exit, server already running"); return true; -- 2.7.1 From 2e6d0b9d16b7052473864a3489d210d0eb76204b Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 11 Dec 2015 00:45:48 +0100 Subject: [PATCH 168/250] do clean interfaces list on each refresh run - as we test for IF list .empty() in CNetwork --- xbmc/network/linux/NetworkLinux.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 44ebf9c..7db0e51 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -341,6 +341,7 @@ CNetworkLinux::~CNetworkLinux(void) void CNetworkLinux::DeleteRemoved(void) { + CSingleLock lock(m_lockInterfaces); m_interfaces.remove_if(IsRemoved); } @@ -352,7 +353,8 @@ void CNetworkLinux::InterfacesClear(void) std::forward_list& CNetworkLinux::GetInterfaceList(void) { - return m_interfaces; + CSingleLock lock(m_lockInterfaces); + return m_interfaces; } // Overwrite the GetFirstConnectedInterface and requery @@ -421,7 +423,6 @@ bool CNetworkLinux::queryInterfaceList() std::map t_hwaddrs; #endif - DeleteRemoved(); InterfacesClear(); // find last IPv4 record, we will add new interfaces @@ -486,7 +487,11 @@ bool CNetworkLinux::queryInterfaceList() } freeifaddrs(list); - return change | std::count_if(m_interfaces.begin(), m_interfaces.end(), IsRemoved); + + change |= std::count_if(m_interfaces.begin(), m_interfaces.end(), IsRemoved); + DeleteRemoved(); + + return change; } std::vector CNetworkLinux::GetNameServers(void) -- 2.7.1 From b886cf15ae3f3222c69f6e238a662192698cca68 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 12 Dec 2015 12:21:56 +0100 Subject: [PATCH 169/250] Revert "configure.ac: LIBS=xx xx needs to be inside brackets" This reverts commit 51cdf9f947063b3f526f3a976f81eeed084b7fb7. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 709d68a..2075b40 100644 --- a/configure.ac +++ b/configure.ac @@ -1560,7 +1560,7 @@ if test "$use_libgif" != "no"; then USE_LIBGIF=0 fi ]) - LIBS="$LIBS -lgif " + LIBS=$LIBS -lgif if test "$use_libgif" != "no"; then AC_DEFINE([HAVE_LIBGIF], [1], [Whether to use libgif library.]) USE_LIBGIF=1 -- 2.7.1 From 45905771b2e247f66865e106692d008aa8534576 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 12 Dec 2015 12:22:01 +0100 Subject: [PATCH 170/250] Revert "configure.ac libgif not able to get soname, change to simple LIBS=-lgif" This reverts commit ecc640e6ce03f5c79d5077108236a16e2d224da2. --- configure.ac | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 2075b40..a90538c 100644 --- a/configure.ac +++ b/configure.ac @@ -1560,7 +1560,9 @@ if test "$use_libgif" != "no"; then USE_LIBGIF=0 fi ]) - LIBS=$LIBS -lgif + if test "$use_libgif" != "no"; then + XB_FIND_SONAME([GIF], [gif], [use_libgif]) + fi if test "$use_libgif" != "no"; then AC_DEFINE([HAVE_LIBGIF], [1], [Whether to use libgif library.]) USE_LIBGIF=1 -- 2.7.1 From a5d2a04abb182af14f9a7038cdd2df34e3608b3b Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 15 Dec 2015 13:27:42 +0100 Subject: [PATCH 171/250] don't switch non-CEA resolutions if it is not allowed --- xbmc/cores/VideoRenderers/BaseRenderer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp index f354053..89fba4f 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp @@ -337,6 +337,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES if (((int) m_sourceWidth < orig.iScreenWidth) // orig res large enough || (info.iScreenWidth < orig.iScreenWidth) // new width would be smaller || (info.iScreenHeight < orig.iScreenHeight) // new height would be smaller + || (!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK)) // don't switch to interlaced modes { continue; -- 2.7.1 From aa7de3b93f41d342372d2f67fe472b715fd4afe6 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 16 Dec 2015 18:48:50 +0100 Subject: [PATCH 172/250] libpng: add -fPIC --- tools/depends/target/libpng/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/depends/target/libpng/Makefile b/tools/depends/target/libpng/Makefile index 5467abf..b9c041f 100644 --- a/tools/depends/target/libpng/Makefile +++ b/tools/depends/target/libpng/Makefile @@ -9,7 +9,7 @@ SOURCE=$(LIBNAME)-$(VERSION) ARCHIVE=$(SOURCE).tar.gz # configuration settings -CONFIGURE=cp -f $(CONFIG_SUB) $(CONFIG_GUESS) .; \ +CONFIGURE=cp -f $(CONFIG_SUB) $(CONFIG_GUESS) .; CFLAGS=-fPIC \ ./configure --prefix=$(PREFIX) --disable-shared LIBDYLIB=$(PLATFORM)/.libs/$(LIBNAME)15.a -- 2.7.1 From 1d58e5c9c834e0c3fcb74721d7cf797aa3fcbd24 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 16 Dec 2015 22:13:37 +0100 Subject: [PATCH 173/250] fix TexturePacker's location --- configure.ac | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index a90538c..20c432f 100644 --- a/configure.ac +++ b/configure.ac @@ -2179,11 +2179,10 @@ PKG_CHECK_MODULES([SQUISH], [squish], AC_MSG_ERROR("squish not found")) if test "x$use_texturepacker" != "xno"; then - AC_PATH_PROG([TEXTUREPACKER], [TexturePacker], ["none"], - [$PATH$PATH_SEPARATOR${abs_top_srcdir}/tools/depends/native/TexturePacker/bin]) - if test "$TEXTUREPACKER" = "none"; then + AC_CHECK_PROG(TEXTUREPACKER, ${abs_top_srcdir}/tools/TexturePacker/TexturePacker, "yes", "no",) + if test "$TEXTUREPACKER" = "no"; then make -C ${abs_top_srcdir}/tools/depends/native/TexturePacker - TEXTUREPACKER="${abs_top_srcdir}/tools/depends/native/TexturePacker/bin/TexturePacker" + TEXTUREPACKER="${abs_top_srcdir}/tools/TexturePacker/TexturePacker" fi if test -x "$TEXTUREPACKER"; then final_message="$final_message\n TexturePacker:Yes" -- 2.7.1 From f63a1d5d620461807d6d2a62f6ac93e8df0a3d76 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 18 Dec 2015 02:37:53 +0100 Subject: [PATCH 174/250] fix invalid free() on stopping non-running thread --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 42b3331..f89003f 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1335,7 +1335,6 @@ CIMXContext::~CIMXContext() { StopThread(false); Dispose(); - Blank(); CloseDevices(); } @@ -1469,9 +1468,9 @@ bool CIMXContext::TaskRestart() { CLog::Log(LOGINFO, "iMX : %s - restarting IMX rendererer\n", __FUNCTION__); // Stop the ipu thread - CThread::StopThread(false); - CloseDevices(); StopThread(); + MemMap(); + CloseDevices(); Create(); return true; @@ -1490,7 +1489,10 @@ bool CIMXContext::OpenDevices() { m_fbHandle = open(m_deviceName.c_str(), O_RDWR, 0); if (m_fbHandle < 0) + { + m_fbHandle = 0; CLog::Log(LOGWARNING, "iMX : Failed to open framebuffer: %s\n", m_deviceName.c_str()); + } return m_fbHandle > 0; } @@ -2114,10 +2116,14 @@ void CIMXContext::OnExit() void CIMXContext::StopThread(bool bWait /*= true*/) { + if (!IsRunning()) + return; + + Blank(); CThread::StopThread(false); m_inputNotFull.notifyAll(); m_inputNotEmpty.notifyAll(); - if (bWait) + if (bWait && IsRunning()) CThread::StopThread(true); } -- 2.7.1 From 2a2bebd51e89ece82a12f72734c4997d1b5b5945 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 18 Dec 2015 03:14:33 +0100 Subject: [PATCH 175/250] update m_adapter->m_bIsReady to true later --- xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index 99ecaf1..08b0e45 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -1621,7 +1621,6 @@ bool CPeripheralCecAdapterUpdateThread::SetInitialConfiguration(void) if (!WaitReady()) return false; - m_adapter->m_bIsReady = true; UpdateMenuLanguage(); CTimer m_timer(this); m_timer.Start(10000); @@ -1639,6 +1638,7 @@ bool CPeripheralCecAdapterUpdateThread::SetInitialConfiguration(void) CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(36000), strNotification); CSingleLock lock(m_critSection); + m_adapter->m_bIsReady = true; m_bIsUpdating = false; return true; } -- 2.7.1 From cf71542599ae2607a3f686f0b2ffb055527a1bcd Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 22 Dec 2015 03:33:10 +0100 Subject: [PATCH 176/250] NetworkLinux: fix netwatcher --- xbmc/network/linux/NetworkLinux.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 7db0e51..556a02e 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -1189,11 +1189,14 @@ void WatcherProcess() if (!fds) g_application.getNetwork().m_updThread->Sleep(5000); + else + g_application.getNetwork().m_updThread->Sleep(1000); if (stopping || !g_application.getNetwork().ForceRereadInterfaces()) continue; CLog::Log(LOGINFO, "Interfaces change %s", __FUNCTION__); - CApplicationMessenger::GetInstance().PostMsg(TMSG_NETWORKMESSAGE, CNetwork::NETWORK_CHANGED, 0); + CApplicationMessenger::GetInstance().SendMsg(TMSG_NETWORKMESSAGE, CNetwork::NETWORK_CHANGED, 0); } } + -- 2.7.1 From b18704117e98481c41839b81ccb4d009c064f3ee Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 22 Dec 2015 03:43:01 +0100 Subject: [PATCH 177/250] remove event handling through timers --- xbmc/utils/Screen.cpp | 17 +---------------- xbmc/utils/Screen.h | 6 +----- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp index eead168..17fe8ec 100644 --- a/xbmc/utils/Screen.cpp +++ b/xbmc/utils/Screen.cpp @@ -40,7 +40,6 @@ CScreen g_screen; CScreen::CScreen() : m_state(false) , m_changedBlank(false) - , m_timer(this) { CAnnouncementManager::GetInstance().AddAnnouncer(this); } @@ -118,7 +117,7 @@ void CScreen::SetState(bool state, bool doBlank) { case true: if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPausedPlayback()) - break; + return; g_VideoReferenceClock.Stop(); if (!g_application.IsInScreenSaver()) @@ -136,19 +135,5 @@ void CScreen::SetState(bool state, bool doBlank) ; } - // SetRenderGui(false) doesn't need to be timed (delayed) - // It was just try to let ScreenSaver kick in (rewrite screen - black for instance) - // before we stop render. But somehow has not the expected effect (perhaps the actual - // delay between event <> saver launch is longer. - if (!state) - OnTimeout(); - else if (m_timer.IsRunning()) - m_timer.Restart(); - else - m_timer.Start(2500); -} - -void CScreen::OnTimeout() -{ g_application.SetRenderGUI(!m_state); } diff --git a/xbmc/utils/Screen.h b/xbmc/utils/Screen.h index 22b4f12..3ff1ac6 100644 --- a/xbmc/utils/Screen.h +++ b/xbmc/utils/Screen.h @@ -23,7 +23,7 @@ #include "threads/CriticalSection.h" #include "threads/Timer.h" -class CScreen : public ANNOUNCEMENT::IAnnouncer, protected ITimerCallback +class CScreen : public ANNOUNCEMENT::IAnnouncer { public: CScreen(); @@ -37,9 +37,6 @@ public: bool GetScreenState() { return m_state; } -protected: - void OnTimeout(); - private: void SetState(bool status, bool doBlank = true); void ScreenPowerOn(bool doBlank); @@ -48,7 +45,6 @@ private: bool m_state; bool m_changedBlank; CCriticalSection m_critSection; - CTimer m_timer; }; extern CScreen g_screen; -- 2.7.1 From aed0b0086cb7c13370a9ce53b31813809d28101a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 14 Dec 2013 16:55:05 +0000 Subject: [PATCH 178/250] logging: Add microsecond timer to log messages (cherry picked from commit ea9b9ae62bec3444e4ea3f0b652e4dcd360b74a7) Signed-off-by: Matus Kral --- xbmc/utils/log.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/xbmc/utils/log.cpp b/xbmc/utils/log.cpp index b719ccd..715006c 100644 --- a/xbmc/utils/log.cpp +++ b/xbmc/utils/log.cpp @@ -25,6 +25,7 @@ #include "threads/Thread.h" #include "utils/StringUtils.h" #include "CompileInfo.h" +#include "utils/TimeUtils.cpp" static const char* const levelNames[] = {"DEBUG", "INFO", "NOTICE", "WARNING", "ERROR", "SEVERE", "FATAL", "NONE"}; @@ -199,19 +200,31 @@ void CLog::PrintDebugString(const std::string& line) bool CLog::WriteLogString(int logLevel, const std::string& logString) { +#if defined(TARGET_LINUX) + static const char* prefixFormat = "%02.2d:%02.2d:%02.2d %10.6f T:%" PRIu64" %7s: "; +#else static const char* prefixFormat = "%02.2d:%02.2d:%02.2d T:%" PRIu64" %7s: "; - +#endif std::string strData(logString); /* fixup newline alignment, number of spaces should equal prefix length */ StringUtils::Replace(strData, "\n", "\n "); int hour, minute, second; s_globals.m_platform.GetCurrentLocalTime(hour, minute, second); - + +#if defined(TARGET_LINUX) + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + float Now = now.tv_sec + now.tv_nsec * 1e-9; +#endif + strData = StringUtils::Format(prefixFormat, hour, minute, second, +#if defined(TARGET_LINUX) + Now, +#endif (uint64_t)CThread::GetCurrentThreadId(), levelNames[logLevel]) + strData; -- 2.7.1 From 8d4260ef7505e7116dca92d4735a886713692b1c Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 23 Dec 2015 12:42:09 +0100 Subject: [PATCH 179/250] proper DMT&CEA modes recognition --- xbmc/cores/VideoRenderers/BaseRenderer.cpp | 11 +++++----- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 33 +++++++++++++++--------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp index 89fba4f..a116c8e 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp @@ -258,8 +258,8 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES { const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); if (!(info.dwFlags & D3DPRESENTFLAG_INTERLACED) - || CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_MINIMUMVERTICAL) > info.iScreenHeight - || (!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) + || CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_MINIMUMVERTICAL) > info.iScreenHeight + || ((int)CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) < GETFLAGS_GROUP(info.dwFlags)-1) || info.iScreenHeight != m_sourceHeight || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.11) continue; @@ -278,7 +278,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES || CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_MINIMUMVERTICAL) > info.iScreenHeight || (info.dwFlags & D3DPRESENTFLAG_INTERLACED && !(m_iFlags & CONF_FLAGS_INTERLACED)) || (!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTRESOLUTIONINTERLACED) && (info.dwFlags & D3DPRESENTFLAG_INTERLACED)) - || (!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) + || ((int)CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) < GETFLAGS_GROUP(info.dwFlags)-1) || m_sourceWidth > info.iScreenWidth || m_sourceHeight > info.iScreenHeight || pow(info.iScreenWidth*info.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) > last_diff) continue; @@ -301,7 +301,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES || CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_MINIMUMVERTICAL) > info.iScreenHeight || pow(info.iScreenWidth*info.iScreenHeight - m_sourceWidth*m_sourceHeight, 2) > last_diff || info.iScreen != curr.iScreen - || (!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) + || ((int)CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) < GETFLAGS_GROUP(info.dwFlags)-1) || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK)) { /* CLog::Log(LOGDEBUG, "curr %.2f, trying %.2f, mode nr. %d, %dx%d msk %d, m_msk %d", info.fPixelRatio, curr.fPixelRatio, i, @@ -328,6 +328,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES if (info.iScreenWidth != curr.iScreenWidth || info.iScreenHeight != curr.iScreenHeight || info.iScreen != curr.iScreen + || ((int)CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) < GETFLAGS_GROUP(info.dwFlags)-1) || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK) || info.fRefreshRate < (fRefreshRate * multiplier / 1.001) - 0.001) { @@ -337,7 +338,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES if (((int) m_sourceWidth < orig.iScreenWidth) // orig res large enough || (info.iScreenWidth < orig.iScreenWidth) // new width would be smaller || (info.iScreenHeight < orig.iScreenHeight) // new height would be smaller - || (!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) && !(GETFLAGS_GROUP(info.dwFlags) & HDMI_RES_GROUP_CEA)) + || ((int)CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) < GETFLAGS_GROUP(info.dwFlags)-1) || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK)) // don't switch to interlaced modes { continue; diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 84cdc87..6c380a5 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -505,9 +505,9 @@ bool CEGLEdid::ReadEdidData() void CEGLNativeTypeIMX::SetStrMode(RESOLUTION_INFO *res) const { - res->strMode = StringUtils::Format("%4sx%4s @ %.3f%s - Full Screen (%.3f) %s", StringUtils::Format("%d", res->iScreenWidth).c_str(), + res->strMode = StringUtils::Format("%4sx%4s @ %.3f%s - Full Screen %s (%.3f) %s", StringUtils::Format("%d", res->iScreenWidth).c_str(), StringUtils::Format("%d", res->iScreenHeight).c_str(), res->fRefreshRate, - res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : " ", res->fPixelRatio, + res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : " ", HDMI_RES_GROUP_NAME(GETFLAGS_GROUP(res->dwFlags)), res->fPixelRatio, res->dwFlags & D3DPRESENTFLAG_MODE3DSBS ? "- 3DSBS" : res->dwFlags & D3DPRESENTFLAG_MODE3DTB ? "- 3DTB" : ""); } @@ -525,20 +525,12 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) std::string fromMode = StringUtils::Mid(mode, 2); StringUtils::Trim(fromMode); - res->dwFlags = MAKEFLAGS(HDMI_RES_GROUP_CEA, 0, 0); - res->fPixelRatio = 1.0f; + if (StringUtils::StartsWithNoCase(mode, "U:") || StringUtils::StartsWithNoCase(mode, "V:")) + res->dwFlags = HDMI_RES_GROUP_DMT; + else + res->dwFlags = HDMI_RES_GROUP_CEA; - if (StringUtils::StartsWithNoCase(mode, "H:")) { - res->dwFlags |= D3DPRESENTFLAG_MODE3DSBS; - res->fPixelRatio = 2.0f; - } else if (StringUtils::StartsWithNoCase(mode, "T:")) { - res->dwFlags |= D3DPRESENTFLAG_MODE3DTB; - res->fPixelRatio = 0.5f; - } else if (StringUtils::StartsWithNoCase(mode, "U:") || StringUtils::StartsWithNoCase(mode, "V:")) { - res->dwFlags &= ~(MAKEFLAGS(HDMI_RES_GROUP_CEA, 0, 0)); - } else if (StringUtils::StartsWithNoCase(mode, "F:")) { - return false; - } + res->fPixelRatio = 1.0f; CRegExp split(true); split.RegComp("([0-9]+)x([0-9]+)([pi])-([0-9]+)"); @@ -559,7 +551,16 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) else res->fRefreshRate = (float)r; res->refresh_rate = (float)r; - res->dwFlags |= p[0] == 'p' ? D3DPRESENTFLAG_PROGRESSIVE : D3DPRESENTFLAG_INTERLACED; + + res->dwFlags = MAKEFLAGS(res->dwFlags, 0, p[0] != 'p'); + + if (StringUtils::StartsWithNoCase(mode, "H:")) { + res->dwFlags |= D3DPRESENTFLAG_MODE3DSBS; + res->fPixelRatio = 2.0f; + } else if (StringUtils::StartsWithNoCase(mode, "T:")) { + res->dwFlags |= D3DPRESENTFLAG_MODE3DTB; + res->fPixelRatio = 0.5f; + } res->iScreen = 0; res->bFullScreen = true; -- 2.7.1 From a86d8dd94ed19a3f44913179500042ecf7cde65a Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 23 Dec 2015 12:43:21 +0100 Subject: [PATCH 180/250] more verbose error info --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index f89003f..0e0b169 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1430,14 +1430,14 @@ bool CIMXContext::AdaptScreen() struct fb_fix_screeninfo fb_fix; - if (ioctl(m_fbHandle, FBIOPUT_VSCREENINFO, &m_fbVar) < 0) + if (ioctl(m_fbHandle, FBIOPUT_VSCREENINFO, &m_fbVar) == -1) { - CLog::Log(LOGWARNING, "iMX : Failed to setup %s\n", m_deviceName.c_str()); + CLog::Log(LOGWARNING, "iMX : Failed to setup %s (%s)\n", m_deviceName.c_str(), strerror(errno)); goto Err; } - else if (ioctl(m_fbHandle, FBIOGET_FSCREENINFO, &fb_fix) < 0) + else if (ioctl(m_fbHandle, FBIOGET_FSCREENINFO, &fb_fix) == -1) { - CLog::Log(LOGWARNING, "iMX : Failed to query fixed screen info at %s\n", m_deviceName.c_str()); + CLog::Log(LOGWARNING, "iMX : Failed to query fixed screen info at %s (%s)\n", m_deviceName.c_str(), strerror(errno)); goto Err; } -- 2.7.1 From fc2ce191a9c16a9f30c5669fd63fee22f0891e84 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 23 Dec 2015 12:44:21 +0100 Subject: [PATCH 181/250] 20ms is ok interval for events check (5ms is useless) --- xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index 08b0e45..ebbc886 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -389,7 +389,7 @@ void CPeripheralCecAdapter::Process(void) ProcessStandbyDevices(); if (!m_bStop) - Sleep(5); + Sleep(20); } m_queryThread->StopThread(true); -- 2.7.1 From e018d7c9158de2bf69508ba55b6a78e7a736d351 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 29 Dec 2015 18:30:42 +0100 Subject: [PATCH 182/250] update --- xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index ebbc886..38dd36b 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -1602,21 +1602,23 @@ std::string CPeripheralCecAdapterUpdateThread::UpdateAudioSystemStatus(void) bool CPeripheralCecAdapterUpdateThread::SetInitialConfiguration(void) { + std::string strNotification; + std::string strAmpName = UpdateAudioSystemStatus(); + if (!strAmpName.empty()) + strNotification += StringUtils::Format("- %s", strAmpName.c_str()); + // devices to wake are set if (!m_configuration.wakeDevices.IsEmpty() && (m_configuration.wakeDevices.primary != CECDEVICE_TV || m_configuration.bActivateSource == 0)) { m_adapter->m_cecAdapter->PowerOnDevices(m_configuration.wakeDevices.primary); + if (m_configuration.wakeDevices.primary == CECDEVICE_AUDIOSYSTEM && m_adapter->GetAudioSystemConnected()) + WaitReady(); } // the option to make XBMC the active source is set if (m_configuration.bActivateSource == 1) m_adapter->ActivateSource(); - std::string strNotification; - std::string strAmpName = UpdateAudioSystemStatus(); - if (!strAmpName.empty()) - strNotification += StringUtils::Format("- %s", strAmpName.c_str()); - // wait until power up if (!WaitReady()) return false; -- 2.7.1 From c685047ffa030884addbf3f2773a5a0442a5353e Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 11 Sep 2015 11:31:02 +0200 Subject: [PATCH 183/250] PeripheralCecDevice don't use langutils for now in the init process (cherry picked from commit 8eaeb003715c2ccee4ab47b1105e286ae309ad34) --- xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index 38dd36b..daf5565 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -1634,10 +1634,10 @@ bool CPeripheralCecAdapterUpdateThread::SetInitialConfiguration(void) // request the OSD name of the TV cec_osd_name tvName = m_adapter->m_cecAdapter->GetDeviceOSDName(CECDEVICE_TV); - strNotification = StringUtils::Format("%s: %s", g_localizeStrings.Get(36016).c_str(), tvName.name); + strNotification = StringUtils::Format("%s: %s", /*g_localizeStrings.Get(36016).c_str()*/"Connected", tvName.name); // and let the gui know that we're done - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(36000), strNotification); + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, /*g_localizeStrings.Get(36000)*/"Pulse-Eight CEC adapter", strNotification); CSingleLock lock(m_critSection); m_adapter->m_bIsReady = true; -- 2.7.1 From 2a47a826ed609489408c282d6c825c726bb9eda5 Mon Sep 17 00:00:00 2001 From: Rechi Date: Thu, 31 Dec 2015 18:50:24 +0100 Subject: [PATCH 184/250] CNetworkLinux::GetNameServers(): also return ipv6 nameservers (Upstream commit 254d0d8317c186e63661e2aae6cca544d1bf1dac) --- xbmc/network/linux/NetworkLinux.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 556a02e..1c4e084 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -530,10 +530,18 @@ std::vector CNetworkLinux::GetNameServers(void) #else int res = res_init(); - for (int i = 0; i < _res.nscount && !res; i ++) + for (int i = 0; i < MAXNS && !res; i++) { - std::string strIp = CNetwork::GetIpStr((struct sockaddr *)&_res.nsaddr_list[i]); - result.push_back(strIp); + std::string strIp = CNetwork::GetIpStr((struct sockaddr *)&_res.nsaddr_list[i]); + if (!strIp.empty()) + result.push_back(strIp); + + strIp = CNetwork::GetIpStr((struct sockaddr *)_res._u._ext.nsaddrs[i]); + if (!strIp.empty()) + result.push_back(strIp); + + if (_res.nscount + _res._u._ext.nscount6 == result.size()) + break; } #endif if (result.empty()) -- 2.7.1 From aacd1465fab49b3b74852aa7f3fd66d79f7903a0 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 11 Jan 2016 22:15:01 +0100 Subject: [PATCH 185/250] GetNameServers() - merge DARWIN & LINUX code. --- xbmc/network/linux/NetworkLinux.cpp | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 1c4e084..807ff90 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -498,27 +498,7 @@ std::vector CNetworkLinux::GetNameServers(void) { std::vector result; -#if defined(TARGET_DARWIN) - FILE* pipe = popen("scutil --dns | grep \"nameserver\" | tail -n2", "r"); - Sleep(100); - if (pipe) - { - std::vector tmpStr; - char buffer[256] = {'\0'}; - if (fread(buffer, sizeof(char), sizeof(buffer), pipe) > 0 && !ferror(pipe)) - { - tmpStr = StringUtils::Split(buffer, "\n"); - for (unsigned int i = 0; i < tmpStr.size(); i ++) - { - // result looks like this - > ' nameserver[0] : 192.168.1.1' - // 2 blank spaces + 13 in 'nameserver[0]' + blank + ':' + blank == 18 :) - if (tmpStr[i].length() >= 18) - result.push_back(tmpStr[i].substr(18)); - } - } - pclose(pipe); - } -#elif defined(TARGET_ANDROID) +#if defined(TARGET_ANDROID) char nameserver[PROP_VALUE_MAX]; if (__system_property_get("net.dns1",nameserver)) @@ -536,13 +516,20 @@ std::vector CNetworkLinux::GetNameServers(void) if (!strIp.empty()) result.push_back(strIp); +#if !defined(TARGET_DARWIN) strIp = CNetwork::GetIpStr((struct sockaddr *)_res._u._ext.nsaddrs[i]); if (!strIp.empty()) result.push_back(strIp); +#endif - if (_res.nscount + _res._u._ext.nscount6 == result.size()) + if (_res.nscount +#if !defined(TARGET_DARWIN) + + _res._u._ext.nscount6 +#endif + == result.size()) break; } + #endif if (result.empty()) CLog::Log(LOGWARNING, "Unable to determine nameserver"); -- 2.7.1 From a69c053085d6d3e322367b08c5c1f7c5e0376482 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 11 Jan 2016 23:00:39 +0100 Subject: [PATCH 186/250] interlaced content displayed with interlaced resolution must be displayed as is, without any zooming / stretching etc. --- xbmc/cores/VideoRenderers/BaseRenderer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp index a116c8e..37202ba 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp @@ -587,6 +587,14 @@ void CBaseRenderer::CalcNormalDisplayRect(float offsetX, float offsetY, float sc return; } + RESOLUTION_INFO info = g_graphicsContext.GetResInfo(m_resolution); + + if (info.dwFlags & D3DPRESENTFLAG_INTERLACED) + { + inputFrameRatio = (float) screenWidth / screenHeight; + zoomAmount = 1.0f; + } + // scale up image as much as possible // and keep the aspect ratio (introduces with black bars) // calculate the correct output frame ratio (using the users pixel ratio setting -- 2.7.1 From 17ccc94ec14ee57b79ece979353413165e970333 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 11 Jan 2016 23:13:44 +0100 Subject: [PATCH 187/250] dispose dropped frames early in GetPicture() --- .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 0e0b169..16f0771 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1096,6 +1096,15 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) #endif m_frameCounter++; + + if (m_dropState) + { + pDvdVideoPicture->iFlags = DVP_FLAG_DROPPED; + SAFE_RELEASE(m_currentBuffer); + m_dropState = false; + return true; + } + pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED; if (m_initInfo.nInterlace) @@ -1122,14 +1131,6 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) pDvdVideoPicture->pts = m_currentBuffer->GetPts(); pDvdVideoPicture->dts = m_currentBuffer->GetDts(); - if (m_dropState) - { - pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED; - SAFE_RELEASE(m_currentBuffer); - m_dropState = false; - return true; - } - pDvdVideoPicture->IMXBuffer = m_currentBuffer; m_currentBuffer = NULL; -- 2.7.1 From 9870de84c44bac4dad144a22d7fe955ee368fa49 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 11 Jan 2016 23:14:57 +0100 Subject: [PATCH 188/250] drop repeated frames as well. we have it on the screen already --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 16f0771..e8e9295 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -968,6 +968,7 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s - Frame repeat.\n", __FUNCTION__); + m_dropState = true; } else if (decRet & VPU_DEC_OUTPUT_DROPPED) { -- 2.7.1 From 99bbeff9179c8d3faf654b1c9198888cba469a00 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 11 Jan 2016 23:18:31 +0100 Subject: [PATCH 189/250] implement OnLostDevice() --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 6 ++++++ xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 1 + xbmc/windowing/egl/WinSystemEGL.cpp | 7 +++++++ 3 files changed, 14 insertions(+) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index e8e9295..18ba348 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1457,6 +1457,12 @@ Err: return false; } +void CIMXContext::OnLostDevice() +{ + CSingleLock lk(m_pageSwapLock); + m_bFbIsConfigured = false; +} + void CIMXContext::OnResetDevice() { CSingleLock lk(m_pageSwapLock); diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h index 7266b25..0929028 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h @@ -142,6 +142,7 @@ public: void *GetCaptureBuffer() const { if (m_bufferCapture) return m_bufferCapture->buf_vaddr; else return NULL; } void WaitCapture(); + void OnLostDevice(); void OnResetDevice(); private: diff --git a/xbmc/windowing/egl/WinSystemEGL.cpp b/xbmc/windowing/egl/WinSystemEGL.cpp index b6f550b..513ef2c 100644 --- a/xbmc/windowing/egl/WinSystemEGL.cpp +++ b/xbmc/windowing/egl/WinSystemEGL.cpp @@ -294,6 +294,13 @@ bool CWinSystemEGL::CreateNewWindow(const std::string& name, bool fullScreen, RE #endif } + { + CSingleLock lock(m_resourceSection); + // tell any shared resources + for (std::vector::iterator i = m_resources.begin(); i != m_resources.end(); ++i) + (*i)->OnLostDevice(); + } + m_bFullScreen = fullScreen; // Destroy any existing window if (m_surface != EGL_NO_SURFACE) -- 2.7.1 From 040917067541721f88a0c58afe37f94bc0b7e1a1 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 11 Jan 2016 23:20:24 +0100 Subject: [PATCH 190/250] reorder events --- xbmc/utils/Screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp index 17fe8ec..15c1519 100644 --- a/xbmc/utils/Screen.cpp +++ b/xbmc/utils/Screen.cpp @@ -120,9 +120,9 @@ void CScreen::SetState(bool state, bool doBlank) return; g_VideoReferenceClock.Stop(); + ScreenPowerOff(doBlank); if (!g_application.IsInScreenSaver()) g_application.ActivateScreenSaver(); - ScreenPowerOff(doBlank); break; case false: -- 2.7.1 From 64c1fc621389379a9a7b0877133c43744a47612a Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 11 Jan 2016 23:22:37 +0100 Subject: [PATCH 191/250] don't store m_interfaceIpv6 flag. Get it always from actual ipaddr --- xbmc/network/linux/NetworkLinux.cpp | 6 ++---- xbmc/network/linux/NetworkLinux.h | 7 +++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 807ff90..5da06f1 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -83,10 +83,9 @@ using namespace KODI::MESSAGING; -CNetworkInterfaceLinux::CNetworkInterfaceLinux(CNetworkLinux* network, bool sa_ipv6, unsigned int ifa_flags, +CNetworkInterfaceLinux::CNetworkInterfaceLinux(CNetworkLinux* network, unsigned int ifa_flags, std::string ifa_addr, std::string ifa_netmask, std::string interfaceName, char interfaceMacAddrRaw[6]) : - m_interfaceIpv6(sa_ipv6), m_interfaceFlags(ifa_flags), m_interfaceAddr(ifa_addr), m_interfaceNetmask(ifa_netmask), @@ -477,8 +476,7 @@ bool CNetworkLinux::queryInterfaceList() GetMacAddress(cur, macAddrRaw); #endif - CNetworkInterfaceLinux *i = new CNetworkInterfaceLinux(this, cur->ifa_addr->sa_family == AF_INET6, - cur->ifa_flags, addr, mask, name, macAddrRaw); + CNetworkInterfaceLinux *i = new CNetworkInterfaceLinux(this, cur->ifa_flags, addr, mask, name, macAddrRaw); m_interfaces.insert_after(pos, i); if (i->isIPv4()) diff --git a/xbmc/network/linux/NetworkLinux.h b/xbmc/network/linux/NetworkLinux.h index 1b71e6f..fc18d1e 100644 --- a/xbmc/network/linux/NetworkLinux.h +++ b/xbmc/network/linux/NetworkLinux.h @@ -35,7 +35,7 @@ class CNetworkInterfaceLinux : public CNetworkInterface friend class CNetworkLinux; public: - CNetworkInterfaceLinux(CNetworkLinux* network, bool sa_ipv6, + CNetworkInterfaceLinux(CNetworkLinux* network, unsigned int ifa_flags, std::string ifa_addr, std::string ifa_netmask, std::string interfaceName, char interfaceMacAddrRaw[6]); ~CNetworkInterfaceLinux(void); @@ -59,8 +59,8 @@ public: virtual void GetSettings(NetworkAssignment& assignment, std::string& ipAddress, std::string& networkMask, std::string& defaultGateway, std::string& essId, std::string& key, EncMode& encryptionMode); virtual void SetSettings(NetworkAssignment& assignment, std::string& ipAddress, std::string& networkMask, std::string& defaultGateway, std::string& essId, std::string& key, EncMode& encryptionMode); - bool isIPv6() { return m_interfaceIpv6; } - bool isIPv4() { return !m_interfaceIpv6; } + bool isIPv6() { return CNetwork::ConvIPv6(m_interfaceAddr); } + bool isIPv4() { return CNetwork::ConvIPv4(m_interfaceAddr); } // Returns the list of access points in the area virtual std::vector GetAccessPoints(void); @@ -76,7 +76,6 @@ protected: private: void WriteSettings(FILE* fw, NetworkAssignment assignment, std::string& ipAddress, std::string& networkMask, std::string& defaultGateway, std::string& essId, std::string& key, EncMode& encryptionMode); - bool m_interfaceIpv6; unsigned int m_interfaceFlags; /* Flags from SIOCGIFFLAGS */ std::string m_interfaceAddr; /* Address of interface */ std::string m_interfaceNetmask; /* Netmask of interface */ -- 2.7.1 From 8cad87c9de8a858ccde4504434fc1a6cf2256a65 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 11 Jan 2016 23:23:49 +0100 Subject: [PATCH 192/250] recognise dual scan modes --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 6c380a5..301e4c1 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -552,7 +552,7 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) res->fRefreshRate = (float)r; res->refresh_rate = (float)r; - res->dwFlags = MAKEFLAGS(res->dwFlags, 0, p[0] != 'p'); + res->dwFlags = MAKEFLAGS(res->dwFlags, 0, p[0] != 'p' && p[0] != 'd'); if (StringUtils::StartsWithNoCase(mode, "H:")) { res->dwFlags |= D3DPRESENTFLAG_MODE3DSBS; -- 2.7.1 From e891602dc25226b0ec5a2123df301dc254a5c182 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 12 Jan 2016 10:20:08 +0100 Subject: [PATCH 193/250] fix/introduce a way to pass size(addr) from unisex struct sockaddr_storage down to socks layer --- xbmc/network/Network.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index a91f9a5..05ed539 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -39,6 +39,28 @@ using namespace KODI::MESSAGING; +/* + * in all the geniality of new AF/AF6 compatible system functions & structs, + * most of *UNIX socket interface calls vitally depends on (struct)addr size to be specified. + * + * TODO for v18: as was initially discussed in PR#7030 let's define common 'ADT' to represent + * network entity (physical as well as logical ones (connectors/listeners/servers(services), + * but also interfaces, hosts). + * + * ((someone nicely started back in 2008 - xbmc/network/Socket.{cpp,h})) + */ +socklen_t sa_len(struct sockaddr *addr) +{ + switch(((struct sockaddr_storage*)addr)->ss_family) + { + case AF_INET: + return sizeof(struct sockaddr_in); + case AF_INET6: + return sizeof(struct sockaddr_in6); + } + return 0; +} + /* slightly modified in_ether taken from the etherboot project (http://sourceforge.net/projects/etherboot) */ bool in_ether (const char *bufp, unsigned char *addr) { @@ -501,7 +523,7 @@ bool CNetwork::WakeOnLan(const char* mac) } // ping helper -static const char* ConnectHostPort(SOCKET soc, const struct sockaddr_in& addr, struct timeval& timeOut, bool tryRead) +static const char* ConnectHostPort(SOCKET soc, struct sockaddr *addr, struct timeval& timeOut, bool tryRead) { // set non-blocking #ifdef TARGET_WINDOWS @@ -514,7 +536,7 @@ static const char* ConnectHostPort(SOCKET soc, const struct sockaddr_in& addr, s if (result != 0) return "set non-blocking option failed"; - result = connect(soc, (struct sockaddr *)&addr, sizeof(addr)); // non-blocking connect, will fail .. + result = connect(soc, addr, sa_len(addr)); // non-blocking connect, will fail .. if (result < 0) { @@ -598,7 +620,7 @@ bool CNetwork::PingHost(const std::string &ipaddr, unsigned short port, unsigned tmout.tv_sec = timeOutMs / 1000; tmout.tv_usec = (timeOutMs % 1000) * 1000; - err_msg = ConnectHostPort (soc, (const struct sockaddr_in&)addr, tmout, readability_check); + err_msg = ConnectHostPort (soc, (struct sockaddr *)addr, tmout, readability_check); (void) closesocket (soc); } -- 2.7.1 From 71ed7ecd040936970a737d1d8df0c1da5e0640bf Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 3 Dec 2015 17:11:53 +0100 Subject: [PATCH 194/250] - stop and start NetworkUpdater thread with OnSleep/OnWake announcements. This avoids unnecessary reconfigurations when IFs are changing back to IFF_UP as part of resuming process. (cherry picked from commit 0abfb57222b041976dacbe095d8e175a6eb44ae2) --- xbmc/network/Network.cpp | 21 +++++++++++++++++++++ xbmc/network/Network.h | 10 +++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index 05ed539..83f31f0 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -38,6 +38,7 @@ #include "xbmc/interfaces/AnnouncementManager.h" using namespace KODI::MESSAGING; +using namespace ANNOUNCEMENT; /* * in all the geniality of new AF/AF6 compatible system functions & structs, @@ -688,6 +689,26 @@ int CNetwork::PrefixLengthIPv6(const std::string &address) return m; } +CNetwork::CNetworkUpdater::CNetworkUpdater(void (*watcher)()) + : CThread("NetConfUpdater") + , m_watcher(watcher) +{ + CAnnouncementManager::GetInstance().AddAnnouncer(this); +} + +CNetwork::CNetworkUpdater::~CNetworkUpdater() +{ + CAnnouncementManager::GetInstance().RemoveAnnouncer(this); +} + +void CNetwork::CNetworkUpdater::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) +{ + if (flag == System && !strcmp(sender, "xbmc") && !strcmp(message, "OnSleep")) + StopThread(false); + else if (flag == System && !strcmp(sender, "xbmc") && !strcmp(message, "OnWake")) + Create(false); +} + //creates, binds and listens a tcp socket on the desired port. Set bindLocal to //true to bind to localhost only. The socket will listen over ipv6 if possible //and fall back to ipv4 if ipv6 is not available on the platform. diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index 3cdb0f3..bdfff26 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -28,6 +28,7 @@ #include "threads/CriticalSection.h" #include "threads/Thread.h" #include "Application.h" +#include "interfaces/AnnouncementManager.h" #include "settings/lib/ISettingCallback.h" #include @@ -110,15 +111,18 @@ public: class CNetwork { - class CNetworkUpdater : public CThread + class CNetworkUpdater : public CThread, public ANNOUNCEMENT::IAnnouncer { public: - CNetworkUpdater(void (*watcher)()) : CThread("NetConfUpdater"), m_watcher(watcher) {} - virtual ~CNetworkUpdater(void) {}; + CNetworkUpdater(void (*watcher)()); + virtual ~CNetworkUpdater(void); bool Stopping() { return m_bStop; } + void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data); + protected: void Process() { m_watcher(); } + private: void (*m_watcher)(); }; -- 2.7.1 From 76e0bc841460cc413431052407dea63b7e7edc99 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 16 Jan 2016 02:46:20 +0100 Subject: [PATCH 195/250] remove lock, as all callers to DeleteRemoved() are already creating lock. --- xbmc/network/linux/NetworkLinux.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 5da06f1..9626740 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -340,7 +340,6 @@ CNetworkLinux::~CNetworkLinux(void) void CNetworkLinux::DeleteRemoved(void) { - CSingleLock lock(m_lockInterfaces); m_interfaces.remove_if(IsRemoved); } -- 2.7.1 From e2dc5edb93c6d8d26dd5664e30d878fea5d49fc2 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 16 Jan 2016 07:08:17 +0100 Subject: [PATCH 196/250] use black as default screensaver --- system/settings/settings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 6e77d35..3ad5a3d 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -323,7 +323,7 @@ 0 - screensaver.xbmc.builtin.dim + screensaver.xbmc.builtin.black xbmc.ui.screensaver true -- 2.7.1 From 2f3f5660447b7f19d486ad9d1991f81d8933b610 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 21 Jan 2016 20:18:18 +0100 Subject: [PATCH 197/250] imx6: use display as clock set to true (default value) --- system/settings/imx6.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/system/settings/imx6.xml b/system/settings/imx6.xml index 43337ce..30da551 100644 --- a/system/settings/imx6.xml +++ b/system/settings/imx6.xml @@ -9,6 +9,9 @@ false + + true + -- 2.7.1 From 0a06e2241ce5b64a0e894fa95fe31ae2415056a9 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 22 Jan 2016 00:46:41 +0100 Subject: [PATCH 198/250] PeripheralVideo: return on XBMC shutting down --- xbmc/peripherals/devices/PeripheralVideo.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xbmc/peripherals/devices/PeripheralVideo.cpp b/xbmc/peripherals/devices/PeripheralVideo.cpp index 9737129..b9e7331 100644 --- a/xbmc/peripherals/devices/PeripheralVideo.cpp +++ b/xbmc/peripherals/devices/PeripheralVideo.cpp @@ -48,6 +48,9 @@ CPeripheralVideo::~CPeripheralVideo() void CPeripheralVideo::OnDeviceChanged(int state) { + if (g_application.m_bStop) + return; + if (!GetSettingBool("pass_events")) return; -- 2.7.1 From f47dada1c06abfbb1a988c081a1fbe9aaafd0d91 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 22 Jan 2016 00:48:06 +0100 Subject: [PATCH 199/250] CodecIMX: change decode loop break conditions --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 18ba348..c0f4956 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -996,8 +996,8 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) CLog::Log(LOGNOTICE, "%s - EOS encountered.\n", __FUNCTION__); } - if ((decRet & VPU_DEC_NO_ENOUGH_INBUF) || - (decRet & VPU_DEC_OUTPUT_DIS)) + if (decRet & (VPU_DEC_NO_ENOUGH_INBUF | VPU_DEC_OUTPUT_DROPPED | + VPU_DEC_OUTPUT_REPEAT | VPU_DEC_OUTPUT_DIS)) { // We are done with VPU decoder that time break; -- 2.7.1 From 6162f19db2492a679b1b9c5cc995b219713ced81 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 22 Jan 2016 00:48:29 +0100 Subject: [PATCH 200/250] CEC: update --- xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index daf5565..9d7e493 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -180,11 +180,11 @@ void CPeripheralCecAdapter::Announce(AnnouncementFlag flag, const char *sender, // Don't put devices to standby if application is currently playing if ((!g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused()) && m_configuration.bPowerOffScreensaver == 1) { - if (!(CEC_POWER_STATUS_ON == m_cecAdapter->GetDevicePowerStatus(CECDEVICE_TV) && m_cecAdapter->IsLibCECActiveSource())) - g_screen.SetOff(); // only power off when we're the active source if (m_cecAdapter->IsLibCECActiveSource()) StandbyDevices(); + if (!(CEC_POWER_STATUS_ON == m_cecAdapter->GetDevicePowerStatus(CECDEVICE_TV) && m_cecAdapter->IsLibCECActiveSource())) + g_screen.SetOff(); } } else if (flag == System && !strcmp(sender, "xbmc") && !strcmp(message, "OnSleep")) -- 2.7.1 From a0d4dadfce6fb3e39cd3d134f8c4251e6436c821 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 23 Jan 2016 12:30:47 +0100 Subject: [PATCH 201/250] report DROP back to VideoPlayer on return from Decode() --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index c0f4956..3a3fa01 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -969,12 +969,14 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s - Frame repeat.\n", __FUNCTION__); m_dropState = true; + retStatus |= VC_DROPPED; } else if (decRet & VPU_DEC_OUTPUT_DROPPED) { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "%s - Frame dropped.\n", __FUNCTION__); m_dropState = true; + retStatus |= VC_DROPPED; } else if (decRet & VPU_DEC_NO_ENOUGH_BUF) { -- 2.7.1 From 1e3f6b8da5bed4e5f69f69e0014b3273b4fbff42 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 23 Jan 2016 12:32:40 +0100 Subject: [PATCH 202/250] reconfigure decoder if input stream parameters changed --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 3a3fa01..e4beb77 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -806,13 +806,18 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) CLog::Log(LOGDEBUG, "%s - VPU dec 0x%x decode takes : %lld\n\n", __FUNCTION__, decRet, XbmcThreads::SystemClockMillis() - before_dec); #endif - if (ret != VPU_DEC_RET_SUCCESS) + if (ret == VPU_DEC_RET_WRONG_CALL_SEQUENCE && + decRet & VPU_DEC_RESOLUTION_CHANGED) { - CLog::Log(LOGERROR, "%s - VPU decode failed with error code %d.\n", __FUNCTION__, ret); + VpuFreeBuffers(); + } + else if (ret != VPU_DEC_RET_SUCCESS) + { + CLog::Log(LOGERROR, "%s - VPU decode failed with error code %d (0x%x).\n", __FUNCTION__, ret, decRet); goto out_error; } - if (decRet & VPU_DEC_INIT_OK) + if (decRet & VPU_DEC_INIT_OK || decRet & VPU_DEC_RESOLUTION_CHANGED) // VPU decoding init OK : We can retrieve stream info { ret = VPU_DecGetInitialInfo(m_vpuHandle, &m_initInfo); -- 2.7.1 From 32a76c19407dff5be47f94e0a6faaef21f04f261 Mon Sep 17 00:00:00 2001 From: Rechi Date: Sat, 16 Jan 2016 16:08:22 +0100 Subject: [PATCH 203/250] cleanup CNetworkInterfaceLinux::GetHostMacAddress(...) --- xbmc/network/linux/NetworkLinux.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 9626740..5844f45 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -585,12 +585,12 @@ bool CNetworkLinux::PingHostImpl(const std::string &target, unsigned int timeout return result == 0; } -#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) bool CNetworkInterfaceLinux::GetHostMacAddress(unsigned long host_ip, std::string& mac) { if (m_network->GetFirstConnectedFamily() == AF_INET6 || isIPv6()) return false; +#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) bool ret = false; size_t needed; char *buf, *next; @@ -637,13 +637,7 @@ bool CNetworkInterfaceLinux::GetHostMacAddress(unsigned long host_ip, std::strin } } return ret; -} #else -bool CNetworkInterfaceLinux::GetHostMacAddress(unsigned long host_ip, std::string& mac) -{ - if (m_network->GetFirstConnectedFamily() == AF_INET6 || isIPv6()) - return false; - struct arpreq areq; struct sockaddr_in* sin; @@ -677,8 +671,8 @@ bool CNetworkInterfaceLinux::GetHostMacAddress(unsigned long host_ip, std::strin return true; return false; -} #endif +} std::vector CNetworkInterfaceLinux::GetAccessPoints(void) { -- 2.7.1 From bdee79c4fcd2275f86504d24a2b1c85a1ab70f98 Mon Sep 17 00:00:00 2001 From: Rechi Date: Sat, 16 Jan 2016 16:02:29 +0100 Subject: [PATCH 204/250] add CNetwork::PrefixLength(...) and CNetwork::CompareAddresses(...) --- xbmc/network/Network.cpp | 28 ++++++++++++++++++++++++++++ xbmc/network/Network.h | 17 +++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index 83f31f0..8cafd94 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -18,6 +18,7 @@ * */ +#include #include #include @@ -689,6 +690,33 @@ int CNetwork::PrefixLengthIPv6(const std::string &address) return m; } +uint8_t CNetwork::PrefixLength(const struct sockaddr *netmask) +{ + uint8_t prefixLength = 0; + switch (netmask->sa_family) + { + case AF_INET: + prefixLength = std::bitsetsin_addr.s_addr)>(((struct sockaddr_in *) netmask)->sin_addr.s_addr).count(); + break; + case AF_INET6: + for (unsigned int i = 0; i < sizeof(((struct sockaddr_in6 *) netmask)->sin6_addr.s6_addr); ++i) + prefixLength += std::bitsetsin6_addr.s6_addr)>(((struct sockaddr_in6 *) netmask)->sin6_addr.s6_addr[i]).count(); + break; + } + return prefixLength; +} + +bool CNetwork::CompareAddresses(const struct sockaddr * sa, const struct sockaddr * sb) +{ + if (sa->sa_family != sb->sa_family) + return false; + else if (sa->sa_family == AF_INET) + return ((struct sockaddr_in *)(sa))->sin_addr.s_addr == ((struct sockaddr_in *)(sb))->sin_addr.s_addr; + else if (sa->sa_family == AF_INET6) + return (memcmp((char *) &(((struct sockaddr_in6 *)(sa))->sin6_addr), (char *) &(((struct sockaddr_in6 *)(sb))->sin6_addr), sizeof(((struct sockaddr_in6 *)(sa))->sin6_addr))) == 0; + return false; +} + CNetwork::CNetworkUpdater::CNetworkUpdater(void (*watcher)()) : CThread("NetConfUpdater") , m_watcher(watcher) diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index bdfff26..b525493 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -334,6 +334,23 @@ public: // doesn't comply to standard) static int PrefixLengthIPv6(const std::string &address); + /*! + \brief computes the prefix length for a (IPv4/IPv6) netmask + \param struct sockaddr + \return The prefix length of the netmask + For IPv4 it can be between 0 and 32 + For IPv6 it can be between 0 and 128 + */ + static uint8_t PrefixLength(const struct sockaddr *netmask); + + /*! + \brief compares two ip addresses (IPv4/IPv6) + \param ip address 1 + \param ip address 2 + \return if the two addresses are the same + */ + static bool CompareAddresses(const struct sockaddr *sa, const struct sockaddr *sb); + /*! \brief fully IPv4/IPv6 compatible - IPv6 part is limited to addr/mask match only (IPv4 way) -- 2.7.1 From 2834217f6cb90a7b2db40910c52b144562b544e0 Mon Sep 17 00:00:00 2001 From: Rechi Date: Sat, 16 Jan 2016 17:00:51 +0100 Subject: [PATCH 205/250] rework CNetworkInterfaceLinux --- xbmc/network/linux/NetworkLinux.cpp | 31 ++++++++++++++++--------------- xbmc/network/linux/NetworkLinux.h | 19 +++++++++---------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 5844f45..52af1e6 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -84,11 +84,9 @@ using namespace KODI::MESSAGING; CNetworkInterfaceLinux::CNetworkInterfaceLinux(CNetworkLinux* network, unsigned int ifa_flags, - std::string ifa_addr, std::string ifa_netmask, std::string interfaceName, - char interfaceMacAddrRaw[6]) : + struct sockaddr *address, struct sockaddr *netmask, + std::string interfaceName, char interfaceMacAddrRaw[6]) : m_interfaceFlags(ifa_flags), - m_interfaceAddr(ifa_addr), - m_interfaceNetmask(ifa_netmask), m_removed(false), m_interfaceName(interfaceName), m_interfaceMacAdr(StringUtils::Format("%02X:%02X:%02X:%02X:%02X:%02X", @@ -100,11 +98,17 @@ CNetworkInterfaceLinux::CNetworkInterfaceLinux(CNetworkLinux* network, unsigned (uint8_t)interfaceMacAddrRaw[5])) { m_network = network; + m_address = (struct sockaddr *) malloc(sizeof(struct sockaddr_storage)); + m_netmask = (struct sockaddr *) malloc(sizeof(struct sockaddr_storage)); + memcpy(m_address, address, sizeof(struct sockaddr_storage)); + memcpy(m_netmask, netmask, sizeof(struct sockaddr_storage)); memcpy(m_interfaceMacAddrRaw, interfaceMacAddrRaw, sizeof(m_interfaceMacAddrRaw)); } CNetworkInterfaceLinux::~CNetworkInterfaceLinux(void) { + free(m_address); + free(m_netmask); } std::string& CNetworkInterfaceLinux::GetName(void) @@ -142,8 +146,7 @@ bool CNetworkInterfaceLinux::IsConnected() unsigned int needFlags = IFF_RUNNING; //IFF_LOWER_UP bool iRunning = (m_interfaceFlags & needFlags) == needFlags; - // return only interfaces which has ip address - return iRunning && !m_interfaceAddr.empty(); + return iRunning; } std::string CNetworkInterfaceLinux::GetMacAddress() @@ -158,10 +161,7 @@ void CNetworkInterfaceLinux::GetMacAddressRaw(char rawMac[6]) std::string CNetworkInterfaceLinux::GetCurrentIPAddress(void) { - std::string result; - - result = m_interfaceAddr; - return result; + return CNetwork::GetIpStr(m_address); } std::string CNetworkInterfaceLinux::GetCurrentNetmask(void) @@ -169,9 +169,9 @@ std::string CNetworkInterfaceLinux::GetCurrentNetmask(void) std::string result; if (isIPv4()) - result = m_interfaceNetmask; + result = CNetwork::GetIpStr(m_netmask); else - result = StringUtils::Format("%d", CNetwork::PrefixLengthIPv6(m_interfaceNetmask)); + result = StringUtils::Format("%u", CNetwork::PrefixLength(m_netmask)); return result; } @@ -397,7 +397,7 @@ void CNetworkLinux::GetMacAddress(struct ifaddrs *tif, char *mac) #endif } -CNetworkInterfaceLinux *CNetworkLinux::Exists(const std::string &addr, const std::string &mask, const std::string &name) +CNetworkInterfaceLinux *CNetworkLinux::Exists(const struct sockaddr *addr, const struct sockaddr *mask, const std::string &name) { for (auto &&iface: m_interfaces) if (((CNetworkInterfaceLinux*)iface)->Exists(addr, mask, name)) @@ -460,7 +460,7 @@ bool CNetworkLinux::queryInterfaceList() if(addr.empty() || mask.empty()) continue; - CNetworkInterfaceLinux *iface = Exists(addr, mask, name); + CNetworkInterfaceLinux *iface = Exists(cur->ifa_addr, cur->ifa_netmask, name); if (iface) { iface->SetRemoved(false); @@ -475,7 +475,8 @@ bool CNetworkLinux::queryInterfaceList() GetMacAddress(cur, macAddrRaw); #endif - CNetworkInterfaceLinux *i = new CNetworkInterfaceLinux(this, cur->ifa_flags, addr, mask, name, macAddrRaw); + CNetworkInterfaceLinux *i = new CNetworkInterfaceLinux(this, cur->ifa_flags, cur->ifa_addr, + cur->ifa_netmask, name, macAddrRaw); m_interfaces.insert_after(pos, i); if (i->isIPv4()) diff --git a/xbmc/network/linux/NetworkLinux.h b/xbmc/network/linux/NetworkLinux.h index fc18d1e..b71f10f 100644 --- a/xbmc/network/linux/NetworkLinux.h +++ b/xbmc/network/linux/NetworkLinux.h @@ -35,9 +35,8 @@ class CNetworkInterfaceLinux : public CNetworkInterface friend class CNetworkLinux; public: - CNetworkInterfaceLinux(CNetworkLinux* network, - unsigned int ifa_flags, std::string ifa_addr, std::string ifa_netmask, - std::string interfaceName, char interfaceMacAddrRaw[6]); + CNetworkInterfaceLinux(CNetworkLinux* network, unsigned int ifa_flags, struct sockaddr *address, + struct sockaddr *netmask, std::string interfaceName, char interfaceMacAddrRaw[6]); ~CNetworkInterfaceLinux(void); virtual std::string& GetName(void); @@ -59,15 +58,15 @@ public: virtual void GetSettings(NetworkAssignment& assignment, std::string& ipAddress, std::string& networkMask, std::string& defaultGateway, std::string& essId, std::string& key, EncMode& encryptionMode); virtual void SetSettings(NetworkAssignment& assignment, std::string& ipAddress, std::string& networkMask, std::string& defaultGateway, std::string& essId, std::string& key, EncMode& encryptionMode); - bool isIPv6() { return CNetwork::ConvIPv6(m_interfaceAddr); } - bool isIPv4() { return CNetwork::ConvIPv4(m_interfaceAddr); } + bool isIPv6() { return m_address->sa_family == AF_INET6; } + bool isIPv4() { return m_address->sa_family == AF_INET; } // Returns the list of access points in the area virtual std::vector GetAccessPoints(void); - bool Exists(const std::string &addr, const std::string &mask, const std::string &name) + bool Exists(const struct sockaddr *address, const struct sockaddr *netmask, const std::string &name) { - return (addr == m_interfaceAddr && mask == m_interfaceNetmask && name == m_interfaceName); + return CNetwork::CompareAddresses(m_address, address) && CNetwork::CompareAddresses(m_netmask, netmask) && name == m_interfaceName; } protected: @@ -77,8 +76,8 @@ protected: private: void WriteSettings(FILE* fw, NetworkAssignment assignment, std::string& ipAddress, std::string& networkMask, std::string& defaultGateway, std::string& essId, std::string& key, EncMode& encryptionMode); unsigned int m_interfaceFlags; /* Flags from SIOCGIFFLAGS */ - std::string m_interfaceAddr; /* Address of interface */ - std::string m_interfaceNetmask; /* Netmask of interface */ + struct sockaddr* m_address; + struct sockaddr* m_netmask; bool m_removed; std::string m_interfaceName; std::string m_interfaceMacAdr; @@ -111,7 +110,7 @@ public: bool ForceRereadInterfaces() { return queryInterfaceList(); } private: - CNetworkInterfaceLinux *Exists(const std::string &addr, const std::string &mask, const std::string &name); + CNetworkInterfaceLinux *Exists(const struct sockaddr *addr, const struct sockaddr *mask, const std::string &name); void InterfacesClear(void); void DeleteRemoved(void); -- 2.7.1 From 749cb3caae149499588b57506dfb8a237561df58 Mon Sep 17 00:00:00 2001 From: Rechi Date: Sat, 16 Jan 2016 17:17:50 +0100 Subject: [PATCH 206/250] remove CNetwork::PrefixLengthIPv6(...) --- xbmc/network/Network.cpp | 36 ------------------------------------ xbmc/network/Network.h | 14 -------------- 2 files changed, 50 deletions(-) diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index 8cafd94..aae3131 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -654,42 +654,6 @@ std::string CNetwork::CanonizeIPv6(const std::string &address) return result; } -int CNetwork::PrefixLengthIPv6(const std::string &address) -{ - struct sockaddr_in6 mask; - if (!ConvIPv6(address, &mask)) - return -1; - - unsigned int m; - unsigned int segment_size = 128 / sizeof(mask.sin6_addr.s6_addr); - auto segment_tmax = mask.sin6_addr.s6_addr[0]; - segment_tmax = -1; - - // let's assume mask being ff80:: - in binary form: - // 11111111:10000000 - // as prefix-length is count of leftmost contiguous bits, - // we can simply check how many segments are full of bits (0xff). - // this * nr_bits in segment + individual bits from the first segment - // not full is our prefix-length. - for (m = 0; - m < sizeof(mask.sin6_addr.s6_addr) && (mask.sin6_addr.s6_addr[m] == segment_tmax); - m += 1); - - m *= segment_size; - // if we didn't match all segments (prefixlength not /128) - if (m < 128) - { - // we shift left until we get all bits zero, - // then we have final length (in this case it is /9) - auto leftover_bits = mask.sin6_addr.s6_addr[m / segment_size]; - do { - m++; - } while (leftover_bits <<= 1); - } - - return m; -} - uint8_t CNetwork::PrefixLength(const struct sockaddr *netmask) { uint8_t prefixLength = 0; diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h index b525493..f975a7a 100644 --- a/xbmc/network/Network.h +++ b/xbmc/network/Network.h @@ -320,20 +320,6 @@ public: */ static std::string CanonizeIPv6(const std::string &address); - // Networking API calls are providing IPv6 mask information - // in the same data structure as address itself (128bit information) - // e.g. FFFF:FFFF:FFFF:FFF0:0000:0000:0000:0000 - // This function returns decimal value specifying how many of the - // leftmost contiguous bits of the address comprise - // the prefix. This representation is called prefix-length. - // Above mask represents prefix of length 60 and formal (and canonised) - // address/mask specification would look like this: - // 12AB:0:0:CD30::/60 - // This is also the common preferred way of displaying IPv6 addresses - // return 0-128, -1 in case of error (for instance string's notation - // doesn't comply to standard) - static int PrefixLengthIPv6(const std::string &address); - /*! \brief computes the prefix length for a (IPv4/IPv6) netmask \param struct sockaddr -- 2.7.1 From 3d5cb51bad1ab30ca1cbc4190072e92d638300c0 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 25 Jan 2016 06:13:32 +0100 Subject: [PATCH 207/250] Settings: add static const for "videoscreen.blankcurrent" --- xbmc/settings/Settings.cpp | 1 + xbmc/settings/Settings.h | 1 + xbmc/utils/Screen.cpp | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp index 2888bce..8dbd2fc 100644 --- a/xbmc/settings/Settings.cpp +++ b/xbmc/settings/Settings.cpp @@ -348,6 +348,7 @@ const std::string CSettings::SETTING_VIDEOSCREEN_VSYNC = "videoscreen.vsync"; const std::string CSettings::SETTING_VIDEOSCREEN_GUICALIBRATION = "videoscreen.guicalibration"; const std::string CSettings::SETTING_VIDEOSCREEN_TESTPATTERN = "videoscreen.testpattern"; const std::string CSettings::SETTING_VIDEOSCREEN_LIMITEDRANGE = "videoscreen.limitedrange"; +const std::string CSettings::SETTING_VIDEOSCREEN_BLANKCURRENT = "videoscreen.blankcurrent"; const std::string CSettings::SETTING_AUDIOOUTPUT_AUDIODEVICE = "audiooutput.audiodevice"; const std::string CSettings::SETTING_AUDIOOUTPUT_CHANNELS = "audiooutput.channels"; const std::string CSettings::SETTING_AUDIOOUTPUT_CONFIG = "audiooutput.config"; diff --git a/xbmc/settings/Settings.h b/xbmc/settings/Settings.h index de7a695..b94e80d 100644 --- a/xbmc/settings/Settings.h +++ b/xbmc/settings/Settings.h @@ -304,6 +304,7 @@ public: static const std::string SETTING_VIDEOSCREEN_GUICALIBRATION; static const std::string SETTING_VIDEOSCREEN_TESTPATTERN; static const std::string SETTING_VIDEOSCREEN_LIMITEDRANGE; + static const std::string SETTING_VIDEOSCREEN_BLANKCURRENT; static const std::string SETTING_AUDIOOUTPUT_AUDIODEVICE; static const std::string SETTING_AUDIOOUTPUT_CHANNELS; static const std::string SETTING_AUDIOOUTPUT_CONFIG; diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp index 15c1519..1fd14de 100644 --- a/xbmc/utils/Screen.cpp +++ b/xbmc/utils/Screen.cpp @@ -67,7 +67,7 @@ void CScreen::Announce(AnnouncementFlag flag, const char *sender, const char *me void CScreen::ScreenPowerOff(bool doBlank) { - if (!doBlank || !CSettings::GetInstance().GetBool("videoscreen.blankcurrent")) + if (!doBlank || !CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOSCREEN_BLANKCURRENT)) return; m_changedBlank = true; -- 2.7.1 From 71ca4b71b07595e5f16dceb76cdd5832e5b47ed1 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 25 Jan 2016 06:14:26 +0100 Subject: [PATCH 208/250] Screen: fix blanking screen on video/pause/still active --- xbmc/utils/Screen.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp index 1fd14de..ce947c5 100644 --- a/xbmc/utils/Screen.cpp +++ b/xbmc/utils/Screen.cpp @@ -56,7 +56,11 @@ void CScreen::Announce(AnnouncementFlag flag, const char *sender, const char *me else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverDeactivated")) g_screen.SetOn(); else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && CSettings::GetInstance().GetString("screensaver.mode") == "screensaver.xbmc.builtin.black") - g_screen.SetOff(); + { + if (g_application.m_pPlayer->IsPlaying() && g_application.m_pPlayer->IsPausedPlayback() && + !CSettings::GetInstance().GetBool(CSettings::SETTING_SCREENSAVER_USEDIMONPAUSE)) + g_screen.SetOff(); + } /* else if (flag == Player && !strcmp(sender, "xbmc") && !strcmp(message, "OnPlay")) g_VideoReferenceClock.Start(); -- 2.7.1 From e6406cf90eef6ed6eb51897a0d62ae45b5133945 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 1 Feb 2016 04:30:54 +0100 Subject: [PATCH 209/250] allow first frame to pass to VideoPlayer to pass media info --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index e4beb77..44f6054 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1103,13 +1103,15 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) previous = current; #endif - m_frameCounter++; - if (m_dropState) { pDvdVideoPicture->iFlags = DVP_FLAG_DROPPED; - SAFE_RELEASE(m_currentBuffer); m_dropState = false; + } + + if (m_frameCounter++ && pDvdVideoPicture->iFlags == DVP_FLAG_DROPPED) + { + SAFE_RELEASE(m_currentBuffer); return true; } @@ -1154,7 +1156,7 @@ void CDVDVideoCodecIMX::SetDropState(bool bDrop) if (m_dropRequest != bDrop) { - m_dropRequest = bDrop; + m_dropRequest = bDrop && !!m_frameCounter; #ifdef TRACE_FRAMES CLog::Log(LOGDEBUG, "%s : %d\n", __FUNCTION__, bDrop); #endif -- 2.7.1 From bbec7cda5fa36460a7d32607efe17ec4eee196ee Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 1 Feb 2016 04:36:13 +0100 Subject: [PATCH 210/250] check result and fail on VpuAllocBuffers() allocation error --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 44f6054..cd0fff3 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -199,7 +199,9 @@ bool CDVDVideoCodecIMX::VpuOpen() CLog::Log(LOGERROR, "%s - iMX VPU query mem error (%d).\n", __FUNCTION__, ret); goto VpuOpenError; } - VpuAllocBuffers(&memInfo); + + if (!VpuAllocBuffers(&memInfo)) + goto VpuOpenError; m_decOpenParam.nReorderEnable = 1; #ifdef IMX_INPUT_FORMAT_I420 -- 2.7.1 From b41484375680a557ddc015c014a7ca88294b05ae Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 1 Feb 2016 04:40:11 +0100 Subject: [PATCH 211/250] fix --- xbmc/utils/Screen.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/xbmc/utils/Screen.cpp b/xbmc/utils/Screen.cpp index ce947c5..f361086 100644 --- a/xbmc/utils/Screen.cpp +++ b/xbmc/utils/Screen.cpp @@ -57,8 +57,9 @@ void CScreen::Announce(AnnouncementFlag flag, const char *sender, const char *me g_screen.SetOn(); else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && CSettings::GetInstance().GetString("screensaver.mode") == "screensaver.xbmc.builtin.black") { - if (g_application.m_pPlayer->IsPlaying() && g_application.m_pPlayer->IsPausedPlayback() && - !CSettings::GetInstance().GetBool(CSettings::SETTING_SCREENSAVER_USEDIMONPAUSE)) + if ((g_application.m_pPlayer->IsPlaying() && g_application.m_pPlayer->IsPausedPlayback() && + !CSettings::GetInstance().GetBool(CSettings::SETTING_SCREENSAVER_USEDIMONPAUSE)) + || !g_application.m_pPlayer->IsPlaying()) g_screen.SetOff(); } /* -- 2.7.1 From d42d3158a351843d9676fe9006eb11bd48b498a9 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 1 Feb 2016 07:55:00 +0100 Subject: [PATCH 212/250] CNetwork functions expect IP address, not HostName. Try to resolve before. --- xbmc/network/WakeOnAccess.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/network/WakeOnAccess.cpp b/xbmc/network/WakeOnAccess.cpp index b257aa0..a33724d 100644 --- a/xbmc/network/WakeOnAccess.cpp +++ b/xbmc/network/WakeOnAccess.cpp @@ -221,7 +221,7 @@ public: } virtual bool SuccessWaiting () const { - bool online = g_application.getNetwork().HasInterfaceForIP(m_host); + bool online = g_application.getNetwork().HasInterfaceForIP(CDNSNameCache::Lookup(m_host)); if (!online) // setup endtime so we dont return true until network is consistently connected m_end.Set (m_settle_time_ms); @@ -262,7 +262,7 @@ public: static bool Ping (const CWakeOnAccess::WakeUpEntry& server) { - return g_application.getNetwork().PingHost(server.host, server.ping_port, 2000, server.ping_mode & 1); + return g_application.getNetwork().PingHost(CDNSNameCache::Lookup(server.host), server.ping_port, 2000, server.ping_mode & 1); } private: -- 2.7.1 From 4070be1f86b0f674a63d80cc3af17914390c6387 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 2 Feb 2016 00:16:15 +0100 Subject: [PATCH 213/250] suppress ping's output with >/dev/null 2>&1 --- xbmc/network/linux/NetworkLinux.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/xbmc/network/linux/NetworkLinux.cpp b/xbmc/network/linux/NetworkLinux.cpp index 52af1e6..b300386 100644 --- a/xbmc/network/linux/NetworkLinux.cpp +++ b/xbmc/network/linux/NetworkLinux.cpp @@ -566,9 +566,11 @@ bool CNetworkLinux::PingHostImpl(const std::string &target, unsigned int timeout #if defined (TARGET_DARWIN_IOS) // no timeout option available sprintf(cmd_line, "%s -c 1 %s", ping.c_str(), target.c_str()); #elif defined (TARGET_DARWIN) || defined (TARGET_FREEBSD) - sprintf(cmd_line, "%s -c 1 -%s %d %s", ping.c_str(), isIPv6 ? "i" : "t", timeout_ms / 1000 + (timeout_ms % 1000) != 0, target.c_str()); + sprintf(cmd_line, "%s -c 1 -%s %d %s >/dev/null 2>&1", + ping.c_str(), isIPv6 ? "i" : "t", timeout_ms / 1000 + (timeout_ms % 1000) != 0, target.c_str()); #else - sprintf(cmd_line, "%s -c 1 -w %d %s", ping.c_str(), timeout_ms / 1000 + (timeout_ms % 1000) != 0, target.c_str()); + sprintf(cmd_line, "%s -c 1 -w %d %s >/dev/null 2>&1", + ping.c_str(), timeout_ms / 1000 + (timeout_ms % 1000) != 0, target.c_str()); #endif int status = system (cmd_line); -- 2.7.1 From c87407025b3db95033964a358d8dd38ce66b2421 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 2 Feb 2016 00:39:41 +0100 Subject: [PATCH 214/250] rewrite CAESinkALSA::AddPackets and update CActiveAESink::OutputSamples --- .../AudioEngine/Engines/ActiveAE/ActiveAESink.cpp | 22 +++++------- xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 39 +++++++++++----------- xbmc/cores/AudioEngine/Sinks/AESinkALSA.h | 2 +- 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp index 3665492..f801041 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp @@ -820,25 +820,21 @@ unsigned int CActiveAESink::OutputSamples(CSampleBuffer* samples) { maxFrames = std::min(frames, m_sinkFormat.m_frames); written = m_sink->AddPackets(buffer, maxFrames, samples->pkt->nb_samples-frames); - if (written == 0) + if (written == 0 && retry++ < 4) { Sleep(500*m_sinkFormat.m_frames/m_sinkFormat.m_sampleRate); - retry++; - if (retry > 4) - { - m_extError = true; - CLog::Log(LOGERROR, "CActiveAESink::OutputSamples - failed"); - status.SetDelay(0); - m_stats->UpdateSinkDelay(status, frames, 0); - return 0; - } - else - continue; + continue; + } + else if (written == 0) + { + m_extError = true; + status.SetDelay(0); + m_stats->UpdateSinkDelay(status, frames, 0); + return 0; } else if (written > maxFrames) { m_extError = true; - CLog::Log(LOGERROR, "CActiveAESink::OutputSamples - sink returned error"); status.SetDelay(0); m_stats->UpdateSinkDelay(status, samples->pool ? maxFrames : 0, 0); return 0; diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp index 09d9f8c..1bc680a 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp @@ -916,46 +916,43 @@ unsigned int CAESinkALSA::AddPackets(uint8_t **data, unsigned int frames, unsign unsigned int amount = 0; int64_t data_left = (int64_t) frames; int frames_written = 0; + int ret = 0; - while (data_left > 0) + snd_pcm_nonblock(m_pcm, 0); + while (data_left > 0 && HandleError(__func__, ret)) { if (m_fragmented) amount = std::min((unsigned int) data_left, m_originalPeriodSize); else // take care as we can come here a second time if the sink does not eat all data amount = (unsigned int) data_left; - int ret = snd_pcm_writei(m_pcm, buffer, amount); - if (ret < 0) - { - CLog::Log(ret == -32 ? LOGDEBUG : LOGERROR, "CAESinkALSA - snd_pcm_writei(%d) %s - trying to recover", ret, snd_strerror(ret)); - HandleError("snd_pcm_writei(1)", ret); - ret = snd_pcm_writei(m_pcm, buffer, amount); - if (ret < 0) - { - HandleError("snd_pcm_writei(2)", ret); - ret = 0; - } - } + ret = snd_pcm_writei(m_pcm, buffer, amount); - if ( ret > 0 && snd_pcm_state(m_pcm) == SND_PCM_STATE_PREPARED) + if (ret < 0) + continue; + else if (ret > 0 && snd_pcm_state(m_pcm) == SND_PCM_STATE_PREPARED) snd_pcm_start(m_pcm); - if (ret <= 0) - break; - frames_written += ret; data_left -= ret; buffer = data[0]+offset*m_format.m_frameSize + frames_written*m_format.m_frameSize; } + return frames_written; } -void CAESinkALSA::HandleError(const char* name, int err) +inline +int CAESinkALSA::HandleError(const char* name, int err) { + static int recoveries; + + if (err >= 0) + recoveries = -2; + switch(err) { case -EPIPE: - CLog::Log(LOGERROR, "CAESinkALSA::HandleError(%s) - underrun", name); + CLog::Log(LOGDEBUG, "CAESinkALSA::HandleError(%s) - underrun", name); if ((err = snd_pcm_prepare(m_pcm)) < 0) CLog::Log(LOGERROR, "CAESinkALSA::HandleError(%s) - snd_pcm_prepare returned %d (%s)", name, err, snd_strerror(err)); break; @@ -974,9 +971,11 @@ void CAESinkALSA::HandleError(const char* name, int err) break; default: - CLog::Log(LOGERROR, "CAESinkALSA::HandleError(%s) - snd_pcm_writei returned %d (%s)", name, err, snd_strerror(err)); break; } + + snd_pcm_avail_update(m_pcm); + return recoveries++; } void CAESinkALSA::Drain() diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h index 2059eaa..8be7041 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h +++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.h @@ -73,7 +73,7 @@ private: #endif void GetAESParams(const AEAudioFormat& format, std::string& params); - void HandleError(const char* name, int err); + int HandleError(const char* name, int err); std::string m_initDevice; AEAudioFormat m_initFormat; -- 2.7.1 From 713773d78dd24e303f8e1b9ee0bd919924485fe2 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 2 Feb 2016 02:30:23 +0100 Subject: [PATCH 215/250] add handling VPU_DEC_NO_ENOUGH_INBUF and VPU_DEC_OUTPUT_NODIS --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index cd0fff3..8da7595 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -813,6 +813,10 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) { VpuFreeBuffers(); } + else if (decRet & VPU_DEC_NO_ENOUGH_INBUF) + { + break; + } else if (ret != VPU_DEC_RET_SUCCESS) { CLog::Log(LOGERROR, "%s - VPU decode failed with error code %d (0x%x).\n", __FUNCTION__, ret, decRet); @@ -1004,8 +1008,7 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) { CLog::Log(LOGNOTICE, "%s - EOS encountered.\n", __FUNCTION__); } - - if (decRet & (VPU_DEC_NO_ENOUGH_INBUF | VPU_DEC_OUTPUT_DROPPED | + if (decRet & (VPU_DEC_OUTPUT_DROPPED| VPU_DEC_OUTPUT_NODIS | VPU_DEC_OUTPUT_REPEAT | VPU_DEC_OUTPUT_DIS)) { // We are done with VPU decoder that time -- 2.7.1 From 2dd85d4b4740b101bb73de1a0276083ba718df45 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 3 Feb 2016 21:32:41 +0100 Subject: [PATCH 216/250] fix double rate deinterlacing --- xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 6 ++++++ xbmc/cores/VideoRenderers/RenderManager.cpp | 4 ---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp index ecce6d1..860c8bb 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp @@ -664,7 +664,13 @@ void CLinuxRendererGLES::RenderUpdateVideo(bool clear, DWORD flags, DWORD alpha) { fieldFmt |= IPU_DEINTERLACE_RATE_EN; if (flags & RENDER_FLAG_FIELD1) + { fieldFmt |= IPU_DEINTERLACE_RATE_FRAME1; + // CXBMCRenderManager::PresentFields() is swapping field flag for frame1 + // this makes IPU render same picture as before, just shifted one line + // correct this + fieldFmt ^= 0x3; + } } g_IMXContext.BlitAsync(NULL, buffer, fieldFmt); diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp index b229d16..ce60bc3 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp @@ -718,11 +718,7 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L { /* default to odd field if we want to deinterlace and don't know better */ if (deinterlacemode == VS_DEINTERLACEMODE_FORCE && sync == FS_NONE) -#ifdef HAS_IMXVPU - sync = FS_BOT; -#else sync = FS_TOP; -#endif /* invert present field */ if(invert) -- 2.7.1 From d92ca2d352789a4de5b42af032283d3c9962b79b Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 3 Feb 2016 21:36:22 +0100 Subject: [PATCH 217/250] fix logging on deinterlacing change --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 8da7595..1a7082d 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1594,12 +1594,15 @@ void CIMXContext::SetFieldData(uint8_t fieldFmt) if (!g_graphicsContext.IsFullScreenVideo()) fieldFmt = 0; + bool dr = IsDoubleRate(); bool deint = !!m_currentFieldFmt; m_currentFieldFmt = fieldFmt; - if (!!fieldFmt == deint) + if (!!fieldFmt == deint && dr == IsDoubleRate()) return; CLog::Log(LOGDEBUG, "iMX : Deinterlacing parameters changed (%s) %s\n", !!fieldFmt ? "active" : "not active", IsDoubleRate() ? "DR" : ""); + if (!!fieldFmt == deint) + return; CSingleLock lk(m_pageSwapLock); m_bFbIsConfigured = false; -- 2.7.1 From e12ac82af76223c35a58fc05a09eb85cfd3ae23c Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 10 Feb 2016 02:41:51 +0100 Subject: [PATCH 218/250] call splash after resolution restore --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 301e4c1..aee2956 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -182,11 +182,11 @@ void CEGLNativeTypeIMX::Destroy() } close(fd); - system("/usr/bin/splash --force -i -m 'stopping kodi...'"); - if (!m_readonly) SysfsUtils::SetString("/sys/class/graphics/fb0/mode", m_init.strId + "\n"); SysfsUtils::SetInt("/sys/class/graphics/fb1/blank", 1); + + system("/usr/bin/splash --force -i -m 'stopping kodi...'"); #endif return; } -- 2.7.1 From 26aa354e8ec1297f5283545a066a6a6b3144400a Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 10 Feb 2016 02:47:22 +0100 Subject: [PATCH 219/250] change buffer count to fix playing videos needing 6+ min frame buffers --- xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 2 +- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp index 860c8bb..1472bcf 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp @@ -3047,7 +3047,7 @@ CRenderInfo CLinuxRendererGLES::GetRenderInfo() info.optimal_buffer_size = info.max_buffer_size; } else - info.optimal_buffer_size = 3; + info.optimal_buffer_size = NUM_BUFFERS; return info; } diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 1a7082d..672395a 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -27,6 +27,7 @@ #include "DVDClock.h" #include "windowing/WindowingFactory.h" #include "guilib/GraphicContext.h" +#include "cores/VideoRenderers/BaseRenderer.h" #include #include @@ -41,7 +42,7 @@ #define IMX_VDI_MAX_WIDTH 968 #define FRAME_ALIGN 16 #define MEDIAINFO 1 -#define RENDER_QUEUE_SIZE 5 +#define RENDER_QUEUE_SIZE 3 #define _4CC(c1,c2,c3,c4) (((uint32_t)(c4)<<24)|((uint32_t)(c3)<<16)|((uint32_t)(c2)<<8)|(uint32_t)(c1)) #define Align(ptr,align) (((unsigned int)ptr + (align) - 1)/(align)*(align)) #define Align2(ptr,align) (((unsigned int)ptr)/(align)*(align)) -- 2.7.1 From 515136095554882ac123000607192ed3f9b7ff79 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 10 Feb 2016 02:52:07 +0100 Subject: [PATCH 220/250] load on gui init --- xbmc/video/dialogs/GUIDialogVideoOSD.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/video/dialogs/GUIDialogVideoOSD.cpp b/xbmc/video/dialogs/GUIDialogVideoOSD.cpp index c1e99cf..5e3a31b 100644 --- a/xbmc/video/dialogs/GUIDialogVideoOSD.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoOSD.cpp @@ -30,7 +30,7 @@ using namespace PVR; CGUIDialogVideoOSD::CGUIDialogVideoOSD(void) : CGUIDialog(WINDOW_DIALOG_VIDEO_OSD, "VideoOSD.xml") { - m_loadType = KEEP_IN_MEMORY; + m_loadType = LOAD_ON_GUI_INIT; } CGUIDialogVideoOSD::~CGUIDialogVideoOSD(void) -- 2.7.1 From ff62ce24cc66e1d60dba039404cb5bc3bb9865bb Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 11 Feb 2016 18:20:38 +0100 Subject: [PATCH 221/250] skip 3D modes in extra res. matching --- xbmc/cores/VideoRenderers/BaseRenderer.cpp | 6 +++--- xbmc/windowing/egl/vc_hdmi.h | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp index 37202ba..b16a3c7 100644 --- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp @@ -248,7 +248,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES int loop_diff = 0; // CHANGERESOLUTION - if (CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTRESOLUTION)) + if (CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTRESOLUTION) && !CONF_FLAGS_STEREO_MODE_MASK(m_iFlags)) { bool i_found = false; @@ -261,7 +261,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES || CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_MINIMUMVERTICAL) > info.iScreenHeight || ((int)CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTALLOWNONCEA) < GETFLAGS_GROUP(info.dwFlags)-1) || info.iScreenHeight != m_sourceHeight - || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.11) + || IS_3D(info.dwFlags)) continue; current = (RESOLUTION)i; @@ -274,7 +274,7 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES { const RESOLUTION_INFO info = g_graphicsContext.GetResInfo((RESOLUTION)i); if ((fabs(info.fRefreshRate - fRefreshRate) > 0.001 && fabs(info.fRefreshRate - 2*fRefreshRate) > 0.001) - || fabs(info.fPixelRatio - curr.fPixelRatio) > 0.11 + || IS_3D(info.dwFlags) || CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_MINIMUMVERTICAL) > info.iScreenHeight || (info.dwFlags & D3DPRESENTFLAG_INTERLACED && !(m_iFlags & CONF_FLAGS_INTERLACED)) || (!CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_ADJUSTRESOLUTIONINTERLACED) && (info.dwFlags & D3DPRESENTFLAG_INTERLACED)) diff --git a/xbmc/windowing/egl/vc_hdmi.h b/xbmc/windowing/egl/vc_hdmi.h index 8f07c00..c8e21ce 100644 --- a/xbmc/windowing/egl/vc_hdmi.h +++ b/xbmc/windowing/egl/vc_hdmi.h @@ -33,6 +33,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef _VC_HDMI_H_ #define _VC_HDMI_H_ +#include "guilib/gui3d.h" + typedef int VC_HDMI_BOOL_T; /** @@ -558,4 +560,6 @@ typedef VC_HDMI_ERROR_T HDMI_RESULT_T; #define GETFLAGS_GROUP(f) ( (HDMI_RES_GROUP_T)( ((f) >> 16) & 0xff )) #define GETFLAGS_MODE(f) ( ( (f) >>24 ) & 0xff ) +#define IS_3D(f) ( f & (D3DPRESENTFLAG_MODE3DSBS | D3DPRESENTFLAG_MODE3DTB) ) + #endif /*HDMI_RES_GROUP_NAME*/ -- 2.7.1 From 87239c154413345ca9d763343922d8a7ccb46fb8 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Thu, 11 Feb 2016 20:16:45 +0100 Subject: [PATCH 222/250] When IPU is double rate deinterlacing - depending on top/bot and frame0/frame1 it starts with offset of one stride inside the source image. let's compensate. --- .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 20 +++++++++++++++++--- .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 672395a..9986ae8 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -28,6 +28,7 @@ #include "windowing/WindowingFactory.h" #include "guilib/GraphicContext.h" #include "cores/VideoRenderers/BaseRenderer.h" +#include "cores/VideoRenderers/RenderFlags.h" #include #include @@ -1640,7 +1641,7 @@ bool CIMXContext::PushCaptureTask(CIMXBuffer *source, CRect *dest) return PushTask(ipu); } -bool CIMXContext::ShowPage(int page) +bool CIMXContext::ShowPage(int page, bool shift) { if (!m_fbHandle) return false; if (page < 0 || page >= m_fbPages) return false; @@ -1653,7 +1654,7 @@ bool CIMXContext::ShowPage(int page) m_fbVar.activate = FB_ACTIVATE_VBL; - m_fbVar.yoffset = (m_fbVar.yres + 1) * page; + m_fbVar.yoffset = (m_fbVar.yres + 1) * page + !shift; if (ioctl(m_fbHandle, FBIOPAN_DISPLAY, &m_fbVar) < 0) { CLog::Log(LOGWARNING, "Panning failed: %s\n", strerror(errno)); @@ -2153,6 +2154,18 @@ void CIMXContext::StopThread(bool bWait /*= true*/) CThread::StopThread(true); } +#define MASK1 (IPU_DEINTERLACE_RATE_FRAME1 | RENDER_FLAG_TOP) +#define MASK2 (IPU_DEINTERLACE_RATE_FRAME1 | RENDER_FLAG_BOT) +#define VAL1 MASK1 +#define VAL2 RENDER_FLAG_BOT + +inline +bool checkIPUStrideOffset(struct ipu_deinterlace *d) +{ + return ((d->field_fmt & MASK1) == VAL1) || + ((d->field_fmt & MASK2) == VAL2); +} + void CIMXContext::Process() { bool ret; @@ -2181,6 +2194,7 @@ void CIMXContext::Process() break; ret = DoTask(*task, (1-m_fbCurrentPage) & m_vsync); + bool shift = checkIPUStrideOffset(&task->task.input.deinterlace); // Free resources task->Done(); @@ -2194,7 +2208,7 @@ void CIMXContext::Process() // Show back buffer if (task->task.output.width && ret) - ShowPage(1-m_fbCurrentPage); + ShowPage(1-m_fbCurrentPage, shift); } // Mark all pending jobs as done diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h index 0929028..c53460e 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h @@ -127,7 +127,7 @@ public: uint8_t fieldFmt = 0, CRect *dest = NULL); // Shows a page vsynced - bool ShowPage(int page); + bool ShowPage(int page, bool shift = false); // Returns the visible page int GetCurrentPage() const { return m_fbCurrentPage; } -- 2.7.1 From b913acd1a197b52d4afcb7d3f71bc0bd7e958f3c Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 12 Feb 2016 08:26:44 +0100 Subject: [PATCH 223/250] Revert "Pvr & Epg: All LOGDEBUG loggin can be turned on/off via component log setup." This reverts commit 81ae8bb77c8085f5c150fc4565c2352651ea97b7. --- .../resource.language.en_gb/resources/strings.po | 7 +---- xbmc/commons/ilog.h | 1 - xbmc/epg/Epg.cpp | 9 ++---- xbmc/epg/EpgContainer.cpp | 12 +++----- xbmc/epg/EpgDatabase.cpp | 15 ++++------ xbmc/epg/GUIEPGGridContainer.cpp | 1 - xbmc/pvr/PVRActionListener.cpp | 3 +- xbmc/pvr/PVRDatabase.cpp | 30 +++++++------------ xbmc/pvr/PVRManager.cpp | 34 +++++++--------------- xbmc/pvr/addons/PVRClient.cpp | 26 ++++++----------- xbmc/pvr/addons/PVRClients.cpp | 10 ++----- xbmc/pvr/channels/PVRChannel.cpp | 6 ++-- xbmc/pvr/channels/PVRChannelGroup.cpp | 19 +++++------- xbmc/pvr/channels/PVRChannelGroups.cpp | 28 ++++++------------ xbmc/pvr/channels/PVRChannelGroupsContainer.cpp | 4 +-- xbmc/pvr/recordings/PVRRecordings.cpp | 16 ++++------ xbmc/pvr/timers/PVRTimers.cpp | 27 +++++++---------- xbmc/settings/AdvancedSettings.cpp | 1 - 18 files changed, 81 insertions(+), 168 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 0cd205a..720057a 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -2989,12 +2989,7 @@ msgctxt "#680" msgid "Verbose logging for the [B]Video[/B] component" msgstr "" -#: xbmc/settings/AdvancedSettings.cpp -msgctxt "#681" -msgid "Verbose logging for the [B]PVR[/B] component" -msgstr "" - -#empty strings from id 682 to 699 +#empty strings from id 681 to 699 msgctxt "#700" msgid "Cleaning up library" diff --git a/xbmc/commons/ilog.h b/xbmc/commons/ilog.h index d4ee6cc..de90359 100644 --- a/xbmc/commons/ilog.h +++ b/xbmc/commons/ilog.h @@ -53,7 +53,6 @@ #define LOGUPNP (1 << (LOGMASKBIT + 8)) #define LOGCEC (1 << (LOGMASKBIT + 9)) #define LOGVIDEO (1 << (LOGMASKBIT + 10)) -#define LOGPVR (1 << (LOGMASKBIT + 11)) #include "utils/params_check_macros.h" diff --git a/xbmc/epg/Epg.cpp b/xbmc/epg/Epg.cpp index 4a96a97..0de86c0 100644 --- a/xbmc/epg/Epg.cpp +++ b/xbmc/epg/Epg.cpp @@ -353,8 +353,7 @@ bool CEpg::Load(void) int iEntriesLoaded = database->Get(*this); if (iEntriesLoaded <= 0) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "EPG - %s - no database entries found for table '%s'.", __FUNCTION__, m_strName.c_str()); + CLog::Log(LOGDEBUG, "EPG - %s - no database entries found for table '%s'.", __FUNCTION__, m_strName.c_str()); } else { @@ -651,13 +650,11 @@ bool CEpg::UpdateFromScraper(time_t start, time_t end) } else if (!g_PVRClients->SupportsEPG(channel->ClientID())) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "EPG - %s - the backend for channel '%s' on client '%i' does not support EPGs", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); + CLog::Log(LOGDEBUG, "EPG - %s - the backend for channel '%s' on client '%i' does not support EPGs", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); } else { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "EPG - %s - updating EPG for channel '%s' from client '%i'", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); + CLog::Log(LOGDEBUG, "EPG - %s - updating EPG for channel '%s' from client '%i'", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); bGrabSuccess = (g_PVRClients->GetEPGForChannel(channel, this, start, end) == PVR_ERROR_NO_ERROR); } } diff --git a/xbmc/epg/EpgContainer.cpp b/xbmc/epg/EpgContainer.cpp index c565d6f..279d920 100644 --- a/xbmc/epg/EpgContainer.cpp +++ b/xbmc/epg/EpgContainer.cpp @@ -520,8 +520,7 @@ bool CEpgContainer::DeleteEpg(const CEpg &epg, bool bDeleteFromDatabase /* = fal if (epgEntry == m_epgs.end()) return false; - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "deleting EPG table %s (%d)", epg.Name().c_str(), epg.EpgID()); + CLog::Log(LOGDEBUG, "deleting EPG table %s (%d)", epg.Name().c_str(), epg.EpgID()); if (bDeleteFromDatabase && !m_bIgnoreDbForClient && m_database.IsOpen()) m_database.Delete(*epgEntry->second); @@ -829,8 +828,7 @@ void CEpgContainer::UpdateRequest(int clientID, unsigned int channelID) void CEpgContainer::UpdateEpgEvents() { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "EPGContainer - %s", __FUNCTION__); + CLog::Log(LOGDEBUG, "EPGContainer - %s", __FUNCTION__); CSingleLock lock(m_critSection); CDateTime now = CDateTime::GetUTCDateTime(); int count = 0; @@ -850,8 +848,7 @@ void CEpgContainer::UpdateEpgEvents() ++event; } m_lastEpgEventPurge = now; - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "EPGContainer - %s - %d item(s) purged", __FUNCTION__, count); + CLog::Log(LOGDEBUG, "EPGContainer - %s - %d item(s) purged", __FUNCTION__, count); } // Fill updated entries @@ -880,8 +877,7 @@ void CEpgContainer::UpdateEpgEvents() ++count; } } - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "EPGContainer - %s - %d item(s) updated", __FUNCTION__, count); + CLog::Log(LOGDEBUG, "EPGContainer - %s - %d item(s) updated", __FUNCTION__, count); } void CEpgContainer::CleanupEpgEvents(const CEpgPtr& epg) diff --git a/xbmc/epg/EpgDatabase.cpp b/xbmc/epg/EpgDatabase.cpp index bf132f0..da1ccf6 100644 --- a/xbmc/epg/EpgDatabase.cpp +++ b/xbmc/epg/EpgDatabase.cpp @@ -42,8 +42,7 @@ void CEpgDatabase::CreateTables(void) { CLog::Log(LOGINFO, "EpgDB - %s - creating tables", __FUNCTION__); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epg'", __FUNCTION__); + CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epg'", __FUNCTION__); m_pDS->exec( "CREATE TABLE epg (" "idEpg integer primary key, " @@ -52,8 +51,7 @@ void CEpgDatabase::CreateTables(void) ")" ); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epgtags'", __FUNCTION__); + CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epgtags'", __FUNCTION__); m_pDS->exec( "CREATE TABLE epgtags (" "idBroadcast integer primary key, " @@ -85,8 +83,7 @@ void CEpgDatabase::CreateTables(void) "iFlags integer" ")" ); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'lastepgscan'", __FUNCTION__); + CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'lastepgscan'", __FUNCTION__); m_pDS->exec("CREATE TABLE lastepgscan (" "idEpg integer primary key, " "sLastScan varchar(20)" @@ -96,8 +93,7 @@ void CEpgDatabase::CreateTables(void) void CEpgDatabase::CreateAnalytics() { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "%s - creating indices", __FUNCTION__); + CLog::Log(LOGDEBUG, "%s - creating indices", __FUNCTION__); m_pDS->exec("CREATE UNIQUE INDEX idx_epg_idEpg_iStartTime on epgtags(idEpg, iStartTime desc);"); m_pDS->exec("CREATE INDEX idx_epg_iEndTime on epgtags(iEndTime);"); } @@ -129,8 +125,7 @@ void CEpgDatabase::UpdateTables(int iVersion) bool CEpgDatabase::DeleteEpg(void) { bool bReturn(false); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "EpgDB - %s - deleting all EPG data from the database", __FUNCTION__); + CLog::Log(LOGDEBUG, "EpgDB - %s - deleting all EPG data from the database", __FUNCTION__); bReturn = DeleteValues("epg") || bReturn; bReturn = DeleteValues("epgtags") || bReturn; diff --git a/xbmc/epg/GUIEPGGridContainer.cpp b/xbmc/epg/GUIEPGGridContainer.cpp index 2fde748..b08bf5c 100644 --- a/xbmc/epg/GUIEPGGridContainer.cpp +++ b/xbmc/epg/GUIEPGGridContainer.cpp @@ -37,7 +37,6 @@ #include "epg/Epg.h" #include "pvr/channels/PVRChannel.h" -#include "settings/AdvancedSettings.h" #include "Epg.h" #include "GUIEPGGridContainer.h" diff --git a/xbmc/pvr/PVRActionListener.cpp b/xbmc/pvr/PVRActionListener.cpp index 71475a3..d8e29a1 100644 --- a/xbmc/pvr/PVRActionListener.cpp +++ b/xbmc/pvr/PVRActionListener.cpp @@ -111,8 +111,7 @@ bool CPVRActionListener::OnAction(const CAction &action) CFileItemPtr fileItem = group->GetLastPlayedChannel(playingChannel->ChannelID()); if (fileItem && fileItem->HasPVRChannelInfoTag()) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "%s - switch to channel number %d", __FUNCTION__, fileItem->GetPVRChannelInfoTag()->ChannelNumber()); + CLog::Log(LOGDEBUG, "%s - switch to channel number %d", __FUNCTION__, fileItem->GetPVRChannelInfoTag()->ChannelNumber()); CApplicationMessenger::GetInstance().SendMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1,static_cast( new CAction(ACTION_CHANNEL_SWITCH, static_cast(fileItem->GetPVRChannelInfoTag()->ChannelNumber())))); } diff --git a/xbmc/pvr/PVRDatabase.cpp b/xbmc/pvr/PVRDatabase.cpp index da37e8e..5b19bff 100644 --- a/xbmc/pvr/PVRDatabase.cpp +++ b/xbmc/pvr/PVRDatabase.cpp @@ -47,8 +47,7 @@ void CPVRDatabase::CreateTables() { CLog::Log(LOGINFO, "PVR - %s - creating tables", __FUNCTION__); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channels'", __FUNCTION__); + CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channels'", __FUNCTION__); m_pDS->exec( "CREATE TABLE channels (" "idChannel integer primary key, " @@ -72,8 +71,7 @@ void CPVRDatabase::CreateTables() ")" ); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelgroups'", __FUNCTION__); + CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelgroups'", __FUNCTION__); m_pDS->exec( "CREATE TABLE channelgroups (" "idGroup integer primary key," @@ -86,8 +84,7 @@ void CPVRDatabase::CreateTables() ")" ); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channelgroups_channels'", __FUNCTION__); + CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channelgroups_channels'", __FUNCTION__); m_pDS->exec( "CREATE TABLE map_channelgroups_channels (" "idChannel integer, " @@ -189,8 +186,7 @@ void CPVRDatabase::UpdateTables(int iVersion) bool CPVRDatabase::DeleteChannels(void) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - deleting all channels from the database", __FUNCTION__); + CLog::Log(LOGDEBUG, "PVR - %s - deleting all channels from the database", __FUNCTION__); return DeleteValues("channels"); } @@ -203,8 +199,7 @@ bool CPVRDatabase::DeleteClientChannels(const CPVRClient &client) return false; } - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - deleting all channels from client '%i' from the database", __FUNCTION__, client.GetID()); + CLog::Log(LOGDEBUG, "PVR - %s - deleting all channels from client '%i' from the database", __FUNCTION__, client.GetID()); Filter filter; filter.AppendWhere(PrepareSQL("iClientId = %u", client.GetID())); @@ -218,8 +213,7 @@ bool CPVRDatabase::Delete(const CPVRChannel &channel) if (channel.ChannelID() <= 0) return false; - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - deleting channel '%s' from the database", __FUNCTION__, channel.ChannelName().c_str()); + CLog::Log(LOGDEBUG, "PVR - %s - deleting channel '%s' from the database", __FUNCTION__, channel.ChannelName().c_str()); Filter filter; filter.AppendWhere(PrepareSQL("idChannel = %u", channel.ChannelID())); @@ -266,8 +260,7 @@ int CPVRDatabase::Get(CPVRChannelGroupInternal &results) channel->UpdateEncryptionName(); #if PVRDB_DEBUGGING - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); + CLog::Log(LOGDEBUG, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); #endif PVRChannelGroupMember newMember = { channel, (unsigned int)m_pDS->fv("iChannelNumber").get_asInt() }; results.m_sortedMembers.push_back(newMember); @@ -446,8 +439,7 @@ bool CPVRDatabase::RemoveStaleChannelsFromGroup(const CPVRChannelGroup &group) bool CPVRDatabase::DeleteChannelGroups(void) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - deleting all channel groups from the database", __FUNCTION__); + CLog::Log(LOGDEBUG, "PVR - %s - deleting all channel groups from the database", __FUNCTION__); return DeleteValues("channelgroups") && DeleteValues("map_channelgroups_channels"); @@ -488,8 +480,7 @@ bool CPVRDatabase::Get(CPVRChannelGroups &results) data.SetPosition(m_pDS->fv("iPosition").get_asInt()); results.Update(data); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - group '%s' loaded from the database", __FUNCTION__, data.GroupName().c_str()); + CLog::Log(LOGDEBUG, "PVR - %s - group '%s' loaded from the database", __FUNCTION__, data.GroupName().c_str()); m_pDS->next(); } m_pDS->close(); @@ -531,8 +522,7 @@ int CPVRDatabase::Get(CPVRChannelGroup &group) if (channel) { #if PVRDB_DEBUGGING - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); + CLog::Log(LOGDEBUG, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); #endif PVRChannelGroupMember newMember = { channel, (unsigned int)iChannelNumber }; group.m_sortedMembers.push_back(newMember); diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index 325ff60..9ceacf6 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -62,7 +62,6 @@ #include "utils/StringUtils.h" #include "utils/Variant.h" #include "video/VideoDatabase.h" -#include "settings/AdvancedSettings.h" using namespace MUSIC_INFO; using namespace PVR; @@ -108,8 +107,7 @@ CPVRManager::~CPVRManager(void) { CAnnouncementManager::GetInstance().RemoveAnnouncer(this); Stop(); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG,"PVRManager - destroyed"); + CLog::Log(LOGDEBUG,"PVRManager - destroyed"); } void CPVRManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) @@ -347,8 +345,7 @@ bool CPVRManager::UpgradeOutdatedAddons(void) g_EpgContainer.Start(true); } - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVRManager - %s - restarted", __FUNCTION__); + CLog::Log(LOGDEBUG, "PVRManager - %s - restarted", __FUNCTION__); return true; } @@ -527,8 +524,7 @@ void CPVRManager::Process(void) g_EpgContainer.Start(true); /* main loop */ - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVRManager - %s - entering main loop", __FUNCTION__); + CLog::Log(LOGDEBUG, "PVRManager - %s - entering main loop", __FUNCTION__); bool bRestart(false); while (IsStarted() && m_addons && m_addons->HasConnectedClients() && !bRestart) @@ -639,8 +635,7 @@ bool CPVRManager::Load(void) if (!IsInitialising() || !m_addons || !m_addons->HasConnectedClients()) return false; - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVRManager - %s - active clients found. continue to start", __FUNCTION__); + CLog::Log(LOGDEBUG, "PVRManager - %s - active clients found. continue to start", __FUNCTION__); /* reset observer for pvr windows */ for (std::size_t i = 0; i != ARRAY_SIZE(m_pvrWindowIds); i++) @@ -756,8 +751,7 @@ bool CPVRManager::ContinueLastChannel(void) return true; } - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVRManager - %s - no last played channel to continue playback found", __FUNCTION__); + CLog::Log(LOGDEBUG, "PVRManager - %s - no last played channel to continue playback found", __FUNCTION__); return false; } @@ -883,10 +877,7 @@ int CPVRManager::GetCurrentEpg(CFileItemList &results) const if (channel) iReturn = channel->GetEPG(results); else - { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG,"PVRManager - %s - no current channel set", __FUNCTION__); - } + CLog::Log(LOGDEBUG,"PVRManager - %s - no current channel set", __FUNCTION__); return iReturn; } @@ -1067,9 +1058,8 @@ bool CPVRManager::OpenLiveStream(const CFileItem &fileItem) if (!fileItem.HasPVRChannelInfoTag()) return bReturn; - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG,"PVRManager - %s - opening live stream on channel '%s'", - __FUNCTION__, fileItem.GetPVRChannelInfoTag()->ChannelName().c_str()); + CLog::Log(LOGDEBUG,"PVRManager - %s - opening live stream on channel '%s'", + __FUNCTION__, fileItem.GetPVRChannelInfoTag()->ChannelName().c_str()); // check if we're allowed to play this file if (IsParentalLocked(fileItem.GetPVRChannelInfoTag())) @@ -1345,9 +1335,8 @@ bool CPVRManager::PerformChannelSwitch(const CPVRChannelPtr &channel, bool bPrev CSingleLock lock(m_critSection); if (m_bIsSwitchingChannels) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVRManager - %s - can't switch to channel '%s'. waiting for the previous switch to complete", - __FUNCTION__, channel->ChannelName().c_str()); + CLog::Log(LOGDEBUG, "PVRManager - %s - can't switch to channel '%s'. waiting for the previous switch to complete", + __FUNCTION__, channel->ChannelName().c_str()); return false; } @@ -1362,8 +1351,7 @@ bool CPVRManager::PerformChannelSwitch(const CPVRChannelPtr &channel, bool bPrev m_bIsSwitchingChannels = true; } - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVRManager - %s - switching to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); + CLog::Log(LOGDEBUG, "PVRManager - %s - switching to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); // will be deleted by CPVRChannelSwitchJob::DoWork() CFileItem* previousFile = m_currentFile; diff --git a/xbmc/pvr/addons/PVRClient.cpp b/xbmc/pvr/addons/PVRClient.cpp index b38a37f..395caca 100644 --- a/xbmc/pvr/addons/PVRClient.cpp +++ b/xbmc/pvr/addons/PVRClient.cpp @@ -174,8 +174,7 @@ ADDON_STATUS CPVRClient::Create(int iClientId) /* initialise the add-on */ bool bReadyToUse(false); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - creating PVR add-on instance '%s'", __FUNCTION__, Name().c_str()); + CLog::Log(LOGDEBUG, "PVR - %s - creating PVR add-on instance '%s'", __FUNCTION__, Name().c_str()); try { if ((status = CAddonDll::Create()) == ADDON_STATUS_OK) @@ -203,8 +202,7 @@ void CPVRClient::Destroy(void) m_bReadyToUse = false; /* reset 'ready to use' to false */ - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - destroying PVR add-on '%s'", __FUNCTION__, GetFriendlyName().c_str()); + CLog::Log(LOGDEBUG, "PVR - %s - destroying PVR add-on '%s'", __FUNCTION__, GetFriendlyName().c_str()); /* destroy the add-on */ try { CAddonDll::Destroy(); } @@ -844,9 +842,8 @@ PVR_ERROR CPVRClient::GetChannelGroupMembers(CPVRChannelGroup *group) PVR_CHANNEL_GROUP tag; WriteClientGroupInfo(*group, tag); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - get group members for group '%s' from add-on '%s'", - __FUNCTION__, tag.strGroupName, GetFriendlyName().c_str()); + CLog::Log(LOGDEBUG, "PVR - %s - get group members for group '%s' from add-on '%s'", + __FUNCTION__, tag.strGroupName, GetFriendlyName().c_str()); retVal = m_pStruct->GetChannelGroupMembers(&handle, tag); LogError(retVal, __FUNCTION__); @@ -1705,13 +1702,11 @@ bool CPVRClient::OpenStream(const CPVRChannelPtr &channel, bool bIsSwitchingChan if(!CanPlayChannel(channel)) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "add-on '%s' can not play channel '%s'", GetFriendlyName().c_str(), channel->ChannelName().c_str()); + CLog::Log(LOGDEBUG, "add-on '%s' can not play channel '%s'", GetFriendlyName().c_str(), channel->ChannelName().c_str()); } else if (!channel->StreamURL().empty()) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "opening live stream on url '%s'", channel->StreamURL().c_str()); + CLog::Log(LOGDEBUG, "opening live stream on url '%s'", channel->StreamURL().c_str()); bReturn = true; // the Njoy N7 sometimes doesn't switch channels, but opens a stream to the previous channel @@ -1727,8 +1722,7 @@ bool CPVRClient::OpenStream(const CPVRChannelPtr &channel, bool bIsSwitchingChan } else { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "opening live stream for channel '%s'", channel->ChannelName().c_str()); + CLog::Log(LOGDEBUG, "opening live stream for channel '%s'", channel->ChannelName().c_str()); PVR_CHANNEL tag; WriteClientChannelInfo(channel, tag); @@ -1951,16 +1945,14 @@ bool CPVRClient::Autoconfigure(void) { // %s service found at %s std::string strLogLine(StringUtils::Format(g_localizeStrings.Get(19689).c_str(), (*it).GetName().c_str(), (*it).GetIP().c_str())); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "%s - %s", __FUNCTION__, strLogLine.c_str()); + CLog::Log(LOGDEBUG, "%s - %s", __FUNCTION__, strLogLine.c_str()); if (DialogResponse::YES != HELPERS::ShowYesNoDialogLines(CVariant{19688}, // Scanning for PVR services CVariant{strLogLine}, CVariant{19690})) // Do you want to use this service? { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "%s - %s service found but not enabled by the user", __FUNCTION__, (*it).GetName().c_str()); + CLog::Log(LOGDEBUG, "%s - %s service found but not enabled by the user", __FUNCTION__, (*it).GetName().c_str()); m_rejectedAvahiHosts.push_back(*it); } else diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp index 687c81f..da39071 100644 --- a/xbmc/pvr/addons/PVRClients.cpp +++ b/xbmc/pvr/addons/PVRClients.cpp @@ -36,7 +36,6 @@ #include "pvr/PVRManager.h" #include "pvr/recordings/PVRRecordings.h" #include "pvr/timers/PVRTimers.h" -#include "settings/AdvancedSettings.h" #include "settings/Settings.h" #include "utils/Variant.h" @@ -368,8 +367,7 @@ bool CPVRClients::SwitchChannel(const CPVRChannelPtr &channel) CSingleLock lock(m_critSection); if (m_bIsSwitchingChannels) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVRClients - %s - can't switch to channel '%s'. waiting for the previous switch to complete", __FUNCTION__, channel->ChannelName().c_str()); + CLog::Log(LOGDEBUG, "PVRClients - %s - can't switch to channel '%s'. waiting for the previous switch to complete", __FUNCTION__, channel->ChannelName().c_str()); return false; } m_bIsSwitchingChannels = true; @@ -1113,8 +1111,7 @@ int CPVRClients::RegisterClient(AddonPtr client) if (!client->Enabled() || !database.Open()) return -1; - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "%s - registering add-on '%s'", __FUNCTION__, client->Name().c_str()); + CLog::Log(LOGDEBUG, "%s - registering add-on '%s'", __FUNCTION__, client->Name().c_str()); // check whether we already know this client iClientId = database.GetAddonId(client); //database->GetClientId(client->ID()); @@ -1399,8 +1396,7 @@ bool CPVRClients::UpdateAddons(void) if (bDisable) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "%s - disabling add-on '%s'", __FUNCTION__, (*it)->Name().c_str()); + CLog::Log(LOGDEBUG, "%s - disabling add-on '%s'", __FUNCTION__, (*it)->Name().c_str()); CAddonMgr::GetInstance().DisableAddon((*it)->ID()); usableClients--; } diff --git a/xbmc/pvr/channels/PVRChannel.cpp b/xbmc/pvr/channels/PVRChannel.cpp index 0a3ecb9..9957537 100644 --- a/xbmc/pvr/channels/PVRChannel.cpp +++ b/xbmc/pvr/channels/PVRChannel.cpp @@ -25,7 +25,6 @@ #include "threads/SingleLock.h" #include "utils/log.h" #include "utils/StringUtils.h" -#include "settings/AdvancedSettings.h" #include "utils/Variant.h" #include "pvr/PVRDatabase.h" @@ -547,9 +546,8 @@ int CPVRChannel::GetEPG(CFileItemList &results) const CEpgPtr epg = GetEPG(); if (!epg) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVR - %s - cannot get EPG for channel '%s'", - __FUNCTION__, m_strChannelName.c_str()); + CLog::Log(LOGDEBUG, "PVR - %s - cannot get EPG for channel '%s'", + __FUNCTION__, m_strChannelName.c_str()); return -1; } diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp index 1a0a006..8a2af48 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.cpp +++ b/xbmc/pvr/channels/PVRChannelGroup.cpp @@ -34,7 +34,6 @@ #include "threads/SingleLock.h" #include "utils/log.h" #include "utils/StringUtils.h" -#include "settings/AdvancedSettings.h" #include "pvr/PVRDatabase.h" #include "pvr/PVRManager.h" @@ -163,8 +162,7 @@ bool CPVRChannelGroup::Load(void) m_bUsingBackendChannelNumbers = CSettings::GetInstance().GetBool(CSettings::SETTING_PVRMANAGER_USEBACKENDCHANNELNUMBERS); int iChannelCount = m_iGroupId > 0 ? LoadFromDb() : 0; - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVRChannelGroup - %s - %d channels loaded from the database for group '%s'", + CLog::Log(LOGDEBUG, "PVRChannelGroup - %s - %d channels loaded from the database for group '%s'", __FUNCTION__, iChannelCount, m_strGroupName.c_str()); if (!Update()) @@ -175,9 +173,8 @@ bool CPVRChannelGroup::Load(void) if (Size() - iChannelCount > 0) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "PVRChannelGroup - %s - %d channels added from clients to group '%s'", - __FUNCTION__, static_cast(Size() - iChannelCount), m_strGroupName.c_str()); + CLog::Log(LOGDEBUG, "PVRChannelGroup - %s - %d channels added from clients to group '%s'", + __FUNCTION__, static_cast(Size() - iChannelCount), m_strGroupName.c_str()); } SortAndRenumber(); @@ -903,9 +900,8 @@ bool CPVRChannelGroup::Persist(void) if (CPVRDatabase *database = GetPVRDatabase()) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRChannelGroup - %s - persisting channel group '%s' with %d channels", - __FUNCTION__, GroupName().c_str(), (int) m_members.size()); + CLog::Log(LOGDEBUG, "CPVRChannelGroup - %s - persisting channel group '%s' with %d channels", + __FUNCTION__, GroupName().c_str(), (int) m_members.size()); m_bChanged = false; lock.Leave(); @@ -1038,9 +1034,8 @@ void CPVRChannelGroup::OnSettingChanged(const CSetting *setting) /* check whether this channel group has to be renumbered */ if (bChannelOrderChanged || bChannelNumbersChanged) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRChannelGroup - %s - renumbering group '%s' to use the backend channel order and/or numbers", - __FUNCTION__, m_strGroupName.c_str()); + CLog::Log(LOGDEBUG, "CPVRChannelGroup - %s - renumbering group '%s' to use the backend channel order and/or numbers", + __FUNCTION__, m_strGroupName.c_str()); SortAndRenumber(); Persist(); } diff --git a/xbmc/pvr/channels/PVRChannelGroups.cpp b/xbmc/pvr/channels/PVRChannelGroups.cpp index 3188ea5..95bf4b5 100644 --- a/xbmc/pvr/channels/PVRChannelGroups.cpp +++ b/xbmc/pvr/channels/PVRChannelGroups.cpp @@ -23,7 +23,6 @@ #include "settings/Settings.h" #include "utils/log.h" #include "utils/StringUtils.h" -#include "settings/AdvancedSettings.h" #include "pvr/PVRDatabase.h" #include "pvr/PVRManager.h" @@ -244,8 +243,7 @@ bool CPVRChannelGroups::UpdateGroupsEntries(const CPVRChannelGroups &groups) // user defined group wasn't found if (existingGroup.GroupType() == PVR_GROUP_TYPE_DEFAULT && !group) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - user defined group %s with id '%u' does not exist on the client anymore; deleting it", __FUNCTION__, existingGroup.GroupName().c_str(), existingGroup.GroupID()); + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - user defined group %s with id '%u' does not exist on the client anymore; deleting it", __FUNCTION__, existingGroup.GroupName().c_str(), existingGroup.GroupID()); DeleteGroup(*m_groups.at(iGroupPtr)); } } @@ -280,12 +278,10 @@ bool CPVRChannelGroups::LoadUserDefinedChannelGroups(void) if (bSyncWithBackends) { GetGroupsFromClients(); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" new user defined %s channel groups fetched from clients", __FUNCTION__, (m_groups.size() - iSize), m_bRadio ? "radio" : "TV"); + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" new user defined %s channel groups fetched from clients", __FUNCTION__, (m_groups.size() - iSize), m_bRadio ? "radio" : "TV"); } else - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - 'synchannelgroups' is disabled; skipping groups from clients", __FUNCTION__); + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - 'synchannelgroups' is disabled; skipping groups from clients", __FUNCTION__); std::vector emptyGroups; @@ -297,8 +293,7 @@ bool CPVRChannelGroups::LoadUserDefinedChannelGroups(void) { if (!(*it)->Load()) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - failed to load channel group '%s'", __FUNCTION__, (*it)->GroupName().c_str()); + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - failed to load channel group '%s'", __FUNCTION__, (*it)->GroupName().c_str()); return false; } @@ -310,8 +305,7 @@ bool CPVRChannelGroups::LoadUserDefinedChannelGroups(void) for (std::vector::iterator it = emptyGroups.begin(); it != emptyGroups.end(); ++it) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - deleting empty group '%s'", __FUNCTION__, (*it)->GroupName().c_str()); + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - deleting empty group '%s'", __FUNCTION__, (*it)->GroupName().c_str()); DeleteGroup(*(*it)); } @@ -330,8 +324,7 @@ bool CPVRChannelGroups::Load(void) // remove previous contents Clear(); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - loading all %s channel groups", __FUNCTION__, m_bRadio ? "radio" : "TV"); + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - loading all %s channel groups", __FUNCTION__, m_bRadio ? "radio" : "TV"); // create the internal channel group CPVRChannelGroupPtr internalGroup = CPVRChannelGroupPtr(new CPVRChannelGroupInternal(m_bRadio)); @@ -339,8 +332,7 @@ bool CPVRChannelGroups::Load(void) // load groups from the database database->Get(*this); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" %s groups fetched from the database", __FUNCTION__, m_groups.size(), m_bRadio ? "radio" : "TV"); + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" %s groups fetched from the database", __FUNCTION__, m_groups.size(), m_bRadio ? "radio" : "TV"); // load channels of internal group if (!internalGroup->Load()) @@ -360,8 +352,7 @@ bool CPVRChannelGroups::Load(void) CPVRChannelGroupPtr lastPlayedGroup = GetLastPlayedGroup(); SetSelectedGroup(lastPlayedGroup ? lastPlayedGroup : internalGroup); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" %s channel groups loaded", __FUNCTION__, m_groups.size(), m_bRadio ? "radio" : "TV"); + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" %s channel groups loaded", __FUNCTION__, m_groups.size(), m_bRadio ? "radio" : "TV"); // need at least 1 group return m_groups.size() > 0; @@ -370,8 +361,7 @@ bool CPVRChannelGroups::Load(void) bool CPVRChannelGroups::PersistAll(void) { bool bReturn(true); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - persisting all changes in channel groups", __FUNCTION__); + CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - persisting all changes in channel groups", __FUNCTION__); CSingleLock lock(m_critSection); for (std::vector::iterator it = m_groups.begin(); it != m_groups.end(); ++it) diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp index 98ba1e9..70883dc 100644 --- a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp +++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp @@ -24,7 +24,6 @@ #include "utils/log.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" -#include "settings/AdvancedSettings.h" #include "pvr/PVRManager.h" @@ -55,8 +54,7 @@ bool CPVRChannelGroupsContainer::Update(bool bChannelsOnly /* = false */) m_bUpdateChannelsOnly = bChannelsOnly; lock.Leave(); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRChannelGroupsContainer - %s - updating %s", __FUNCTION__, bChannelsOnly ? "channels" : "channel groups"); + CLog::Log(LOGDEBUG, "CPVRChannelGroupsContainer - %s - updating %s", __FUNCTION__, bChannelsOnly ? "channels" : "channel groups"); bool bReturn = m_groupsRadio->Update(bChannelsOnly) && m_groupsTV->Update(bChannelsOnly); diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp index 60db40d..5288a34 100644 --- a/xbmc/pvr/recordings/PVRRecordings.cpp +++ b/xbmc/pvr/recordings/PVRRecordings.cpp @@ -19,7 +19,6 @@ */ #include "PVRRecordings.h" -#include "settings/AdvancedSettings.h" #include @@ -180,8 +179,7 @@ void CPVRRecordings::Update(void) m_bIsUpdating = true; lock.Leave(); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - updating recordings", __FUNCTION__); + CLog::Log(LOGDEBUG, "CPVRRecordings - %s - updating recordings", __FUNCTION__); UpdateFromClients(); lock.Enter(); @@ -292,8 +290,7 @@ bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) { bResult = true; - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - item path %s", __FUNCTION__, item->GetPath().c_str()); + CLog::Log(LOGDEBUG, "CPVRRecordings - %s - item path %s", __FUNCTION__, item->GetPath().c_str()); CFileItemList items; if (item->m_bIsFolder) { @@ -302,18 +299,15 @@ bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) else items.Add(item); - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - will set watched for %d items", __FUNCTION__, items.Size()); + CLog::Log(LOGDEBUG, "CPVRRecordings - %s - will set watched for %d items", __FUNCTION__, items.Size()); for (int i=0;im_bIsFolder) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - path %s is a folder, will call recursively", __FUNCTION__, pItem->GetPath().c_str()); + CLog::Log(LOGDEBUG, "CPVRRecordings - %s - path %s is a folder, will call recursively", __FUNCTION__, pItem->GetPath().c_str()); if (pItem->GetLabel() != "..") { SetRecordingsPlayCount(pItem, count); diff --git a/xbmc/pvr/timers/PVRTimers.cpp b/xbmc/pvr/timers/PVRTimers.cpp index da204ff..5c9ed15 100644 --- a/xbmc/pvr/timers/PVRTimers.cpp +++ b/xbmc/pvr/timers/PVRTimers.cpp @@ -36,7 +36,6 @@ #include "utils/log.h" #include "utils/StringUtils.h" #include "utils/Variant.h" -#include "settings/AdvancedSettings.h" using namespace PVR; using namespace EPG; @@ -83,8 +82,7 @@ bool CPVRTimers::Update(void) m_bIsUpdating = true; } - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG, "CPVRTimers - %s - updating timers", __FUNCTION__); + CLog::Log(LOGDEBUG, "CPVRTimers - %s - updating timers", __FUNCTION__); CPVRTimers newTimerList; g_PVRClients->GetTimers(&newTimerList); return UpdateEntries(newTimerList); @@ -133,9 +131,8 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) timerNotifications.push_back(strMessage); } - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG,"PVRTimers - %s - updated timer %d on client %d", - __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); + CLog::Log(LOGDEBUG,"PVRTimers - %s - updated timer %d on client %d", + __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } else @@ -170,9 +167,8 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) timerNotifications.push_back(strMessage); } - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG,"PVRTimers - %s - added timer %d on client %d", - __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); + CLog::Log(LOGDEBUG,"PVRTimers - %s - added timer %d on client %d", + __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } } @@ -189,9 +185,8 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) if (!timers.GetByClient(timer->m_iClientId, timer->m_iClientIndex)) { /* timer was not found */ - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", - __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); + CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", + __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); if (g_PVRManager.IsStarted()) timerNotifications.push_back(timer->GetDeletedNotificationText()); @@ -207,9 +202,8 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) (!timer->m_bStartAnyTime && timer->StartAsUTC() != it->first)) { /* timer start has changed */ - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG,"PVRTimers - %s - changed start time timer %d on client %d", - __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); + CLog::Log(LOGDEBUG,"PVRTimers - %s - changed start time timer %d on client %d", + __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); timer->ClearEpgTag(); @@ -502,8 +496,7 @@ bool CPVRTimers::DeleteTimersOnChannel(const CPVRChannelPtr &channel, bool bDele if (bDeleteActiveItem && bDeleteRepeatingItem && bChannelsMatch) { - if (g_advancedSettings.CanLogComponent(LOGPVR)) - CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); + CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); bReturn = (*timerIt)->DeleteFromClient(true) || bReturn; SetChanged(); } diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index f7d5f7b..e202cf8 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -1333,7 +1333,6 @@ void CAdvancedSettings::SettingOptionsLoggingComponentsFiller(const CSetting *se list.push_back(std::make_pair(g_localizeStrings.Get(672), LOGFFMPEG)); list.push_back(std::make_pair(g_localizeStrings.Get(676), LOGAUDIO)); list.push_back(std::make_pair(g_localizeStrings.Get(680), LOGVIDEO)); - list.push_back(std::make_pair(g_localizeStrings.Get(681), LOGPVR)); #ifdef HAS_LIBRTMP list.push_back(std::make_pair(g_localizeStrings.Get(673), LOGRTMP)); #endif -- 2.7.1 From 83c9f5ac03503b87bcf0034091cb84b7d31e8745 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 12 Feb 2016 06:22:11 +0100 Subject: [PATCH 224/250] modification to allow passing LogLevel with Component# (cherry picked from commit 2e7d7943b284a62ae19847cd2da9d3025bafdecb) --- xbmc/utils/log.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/xbmc/utils/log.cpp b/xbmc/utils/log.cpp index 715006c..ba31766 100644 --- a/xbmc/utils/log.cpp +++ b/xbmc/utils/log.cpp @@ -26,6 +26,7 @@ #include "utils/StringUtils.h" #include "CompileInfo.h" #include "utils/TimeUtils.cpp" +#include "settings/AdvancedSettings.h" static const char* const levelNames[] = {"DEBUG", "INFO", "NOTICE", "WARNING", "ERROR", "SEVERE", "FATAL", "NONE"}; @@ -168,25 +169,24 @@ int CLog::GetLogLevel() void CLog::SetExtraLogLevels(int level) { CSingleLock waitLock(s_globals.critSec); - s_globals.m_extraLogLevels = level; + s_globals.m_extraLogLevels = level & ~LOGMASK; } bool CLog::IsLogLevelLogged(int loglevel) { const int extras = (loglevel & ~LOGMASK); - if (extras != 0 && (s_globals.m_extraLogLevels & extras) == 0) - return false; + const bool canlog = (extras ? g_advancedSettings.CanLogComponent(extras) : true); #if defined(_DEBUG) || defined(PROFILE) return true; #else if (s_globals.m_logLevel >= LOG_LEVEL_DEBUG) - return true; + return canlog; if (s_globals.m_logLevel <= LOG_LEVEL_NONE) return false; // "m_logLevel" is "LOG_LEVEL_NORMAL" - return (loglevel & LOGMASK) >= LOGNOTICE; + return ((loglevel & LOGMASK) >= LOGNOTICE) && canlog; #endif } @@ -226,7 +226,7 @@ bool CLog::WriteLogString(int logLevel, const std::string& logString) Now, #endif (uint64_t)CThread::GetCurrentThreadId(), - levelNames[logLevel]) + strData; + levelNames[logLevel & LOGMASK]) + strData; return s_globals.m_platform.WriteStringToLog(strData); } -- 2.7.1 From 999ca2bb52f0b93d0a995e49e3b99ae4549673dd Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 12 Feb 2016 05:55:53 +0100 Subject: [PATCH 225/250] example to ComponentLog usage (cherry picked from commit c494598b574e6c8171f23f223f943713bd61682f) --- xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index 9d7e493..e1bd1d0 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -1242,8 +1242,7 @@ int CPeripheralCecAdapter::CecLogMessage(void *cbParam, const cec_log_message me break; } - if (iLevel >= CEC_LOG_NOTICE || (iLevel >= 0 && CLog::IsLogLevelLogged(LOGDEBUG) && g_advancedSettings.CanLogComponent(LOGCEC))) - CLog::Log(iLevel, "%s - %s", __FUNCTION__, message.message); + CLog::Log(iLevel | LOGCEC, "%s - %s", __FUNCTION__, message.message); return 1; } -- 2.7.1 From 0fac81b5313a5a3a6beef121763a59c899a576ae Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 5 Aug 2015 01:03:02 +0200 Subject: [PATCH 226/250] debug log now as configurable logging component (cherry picked from commit 0b8a938647d571bc9fc145eed4825bbb70622103) --- addons/resource.language.en_gb/resources/strings.po | 7 ++++++- xbmc/commons/ilog.h | 1 + xbmc/settings/AdvancedSettings.cpp | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 720057a..71927aa 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -4949,7 +4949,12 @@ msgctxt "#10524" msgid "Movie information" msgstr "" -#empty strings from id 10525 to 11999 +#: xbmc/settings/AdvancedSettings.cpp +msgctxt "#10525" +msgid "Verbose logging for the [B]PVR[/B] component" +msgstr "" + +#empty strings from id 10526 to 11999 #: xbmc/guilib/WindowIDs.h msgctxt "#12000" diff --git a/xbmc/commons/ilog.h b/xbmc/commons/ilog.h index de90359..d4ee6cc 100644 --- a/xbmc/commons/ilog.h +++ b/xbmc/commons/ilog.h @@ -53,6 +53,7 @@ #define LOGUPNP (1 << (LOGMASKBIT + 8)) #define LOGCEC (1 << (LOGMASKBIT + 9)) #define LOGVIDEO (1 << (LOGMASKBIT + 10)) +#define LOGPVR (1 << (LOGMASKBIT + 11)) #include "utils/params_check_macros.h" diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index e202cf8..bdfb57d 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -1333,6 +1333,7 @@ void CAdvancedSettings::SettingOptionsLoggingComponentsFiller(const CSetting *se list.push_back(std::make_pair(g_localizeStrings.Get(672), LOGFFMPEG)); list.push_back(std::make_pair(g_localizeStrings.Get(676), LOGAUDIO)); list.push_back(std::make_pair(g_localizeStrings.Get(680), LOGVIDEO)); + list.push_back(std::make_pair(g_localizeStrings.Get(10525), LOGPVR)); #ifdef HAS_LIBRTMP list.push_back(std::make_pair(g_localizeStrings.Get(673), LOGRTMP)); #endif -- 2.7.1 From 808b1c9aa6a9596f202785fb5291a4460b36623c Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Fri, 12 Feb 2016 06:24:15 +0100 Subject: [PATCH 227/250] change loglevel from logdebug to logpvr (cherry picked from commit c28371fec31634e0f07bb9f3e94de9f865edf235) --- xbmc/epg/Epg.cpp | 20 ++++++++++---------- xbmc/epg/EpgContainer.cpp | 8 ++++---- xbmc/epg/EpgDatabase.cpp | 10 +++++----- xbmc/epg/EpgInfoTag.cpp | 2 +- xbmc/epg/GUIEPGGridContainer.cpp | 4 ++-- xbmc/pvr/PVRActionListener.cpp | 2 +- xbmc/pvr/PVRDatabase.cpp | 20 ++++++++++---------- xbmc/pvr/PVRManager.cpp | 18 +++++++++--------- xbmc/pvr/addons/PVRClient.cpp | 16 ++++++++-------- xbmc/pvr/addons/PVRClients.cpp | 6 +++--- xbmc/pvr/channels/PVRChannel.cpp | 2 +- xbmc/pvr/channels/PVRChannelGroup.cpp | 8 ++++---- xbmc/pvr/channels/PVRChannelGroups.cpp | 18 +++++++++--------- xbmc/pvr/channels/PVRChannelGroupsContainer.cpp | 2 +- xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp | 4 ++-- xbmc/pvr/recordings/PVRRecording.cpp | 2 +- xbmc/pvr/recordings/PVRRecordings.cpp | 10 +++++----- xbmc/pvr/timers/PVRTimers.cpp | 12 ++++++------ 18 files changed, 82 insertions(+), 82 deletions(-) diff --git a/xbmc/epg/Epg.cpp b/xbmc/epg/Epg.cpp index 0de86c0..0819b75 100644 --- a/xbmc/epg/Epg.cpp +++ b/xbmc/epg/Epg.cpp @@ -353,13 +353,13 @@ bool CEpg::Load(void) int iEntriesLoaded = database->Get(*this); if (iEntriesLoaded <= 0) { - CLog::Log(LOGDEBUG, "EPG - %s - no database entries found for table '%s'.", __FUNCTION__, m_strName.c_str()); + CLog::Log(LOGPVR, "EPG - %s - no database entries found for table '%s'.", __FUNCTION__, m_strName.c_str()); } else { m_lastScanTime = GetLastScanTime(); #if EPG_DEBUGGING - CLog::Log(LOGDEBUG, "EPG - %s - %d entries loaded for table '%s'.", __FUNCTION__, (int) m_tags.size(), m_strName.c_str()); + CLog::Log(LOGPVR, "EPG - %s - %d entries loaded for table '%s'.", __FUNCTION__, (int) m_tags.size(), m_strName.c_str()); #endif bReturn = true; } @@ -373,19 +373,19 @@ bool CEpg::UpdateEntries(const CEpg &epg, bool bStoreInDb /* = true */) { CSingleLock lock(m_critSection); #if EPG_DEBUGGING - CLog::Log(LOGDEBUG, "EPG - %s - %" PRIuS" entries in memory before merging", __FUNCTION__, m_tags.size()); + CLog::Log(LOGPVR, "EPG - %s - %" PRIuS" entries in memory before merging", __FUNCTION__, m_tags.size()); #endif /* copy over tags */ for (std::map::const_iterator it = epg.m_tags.begin(); it != epg.m_tags.end(); ++it) UpdateEntry(*it->second, bStoreInDb, false); #if EPG_DEBUGGING - CLog::Log(LOGDEBUG, "EPG - %s - %" PRIuS" entries in memory after merging and before fixing", __FUNCTION__, m_tags.size()); + CLog::Log(LOGPVR, "EPG - %s - %" PRIuS" entries in memory after merging and before fixing", __FUNCTION__, m_tags.size()); #endif FixOverlappingEvents(bStoreInDb); #if EPG_DEBUGGING - CLog::Log(LOGDEBUG, "EPG - %s - %" PRIuS" entries in memory after fixing", __FUNCTION__, m_tags.size()); + CLog::Log(LOGPVR, "EPG - %s - %" PRIuS" entries in memory after fixing", __FUNCTION__, m_tags.size()); #endif /* update the last scan time of this table */ m_lastScanTime = CDateTime::GetCurrentDateTime().GetAsUTCDateTime(); @@ -516,7 +516,7 @@ bool CEpg::Persist(void) return true; #if EPG_DEBUGGING - CLog::Log(LOGDEBUG, "persist table '%s' (#%d) changed=%d deleted=%d", Name().c_str(), m_iEpgID, m_changedTags.size(), m_deletedTags.size()); + CLog::Log(LOGPVR, "persist table '%s' (#%d) changed=%d deleted=%d", Name().c_str(), m_iEpgID, m_changedTags.size(), m_deletedTags.size()); #endif CEpgDatabase *database = g_EpgContainer.GetDatabase(); @@ -637,24 +637,24 @@ bool CEpg::UpdateFromScraper(time_t start, time_t end) else if (!channel->EPGEnabled()) { #if EPG_DEBUGGING - CLog::Log(LOGDEBUG, "EPG - %s - EPG updating disabled in the channel configuration", __FUNCTION__); + CLog::Log(LOGPVR, "EPG - %s - EPG updating disabled in the channel configuration", __FUNCTION__); #endif bGrabSuccess = true; } else if (channel->IsHidden()) { #if EPG_DEBUGGING - CLog::Log(LOGDEBUG, "EPG - %s - channel '%s' on client '%i' is hidden", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); + CLog::Log(LOGPVR, "EPG - %s - channel '%s' on client '%i' is hidden", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); #endif bGrabSuccess = true; } else if (!g_PVRClients->SupportsEPG(channel->ClientID())) { - CLog::Log(LOGDEBUG, "EPG - %s - the backend for channel '%s' on client '%i' does not support EPGs", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); + CLog::Log(LOGPVR, "EPG - %s - the backend for channel '%s' on client '%i' does not support EPGs", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); } else { - CLog::Log(LOGDEBUG, "EPG - %s - updating EPG for channel '%s' from client '%i'", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); + CLog::Log(LOGPVR, "EPG - %s - updating EPG for channel '%s' from client '%i'", __FUNCTION__, channel->ChannelName().c_str(), channel->ClientID()); bGrabSuccess = (g_PVRClients->GetEPGForChannel(channel, this, start, end) == PVR_ERROR_NO_ERROR); } } diff --git a/xbmc/epg/EpgContainer.cpp b/xbmc/epg/EpgContainer.cpp index 279d920..77a3c54 100644 --- a/xbmc/epg/EpgContainer.cpp +++ b/xbmc/epg/EpgContainer.cpp @@ -520,7 +520,7 @@ bool CEpgContainer::DeleteEpg(const CEpg &epg, bool bDeleteFromDatabase /* = fal if (epgEntry == m_epgs.end()) return false; - CLog::Log(LOGDEBUG, "deleting EPG table %s (%d)", epg.Name().c_str(), epg.EpgID()); + CLog::Log(LOGPVR, "deleting EPG table %s (%d)", epg.Name().c_str(), epg.EpgID()); if (bDeleteFromDatabase && !m_bIgnoreDbForClient && m_database.IsOpen()) m_database.Delete(*epgEntry->second); @@ -828,7 +828,7 @@ void CEpgContainer::UpdateRequest(int clientID, unsigned int channelID) void CEpgContainer::UpdateEpgEvents() { - CLog::Log(LOGDEBUG, "EPGContainer - %s", __FUNCTION__); + CLog::Log(LOGPVR, "EPGContainer - %s", __FUNCTION__); CSingleLock lock(m_critSection); CDateTime now = CDateTime::GetUTCDateTime(); int count = 0; @@ -848,7 +848,7 @@ void CEpgContainer::UpdateEpgEvents() ++event; } m_lastEpgEventPurge = now; - CLog::Log(LOGDEBUG, "EPGContainer - %s - %d item(s) purged", __FUNCTION__, count); + CLog::Log(LOGPVR, "EPGContainer - %s - %d item(s) purged", __FUNCTION__, count); } // Fill updated entries @@ -877,7 +877,7 @@ void CEpgContainer::UpdateEpgEvents() ++count; } } - CLog::Log(LOGDEBUG, "EPGContainer - %s - %d item(s) updated", __FUNCTION__, count); + CLog::Log(LOGPVR, "EPGContainer - %s - %d item(s) updated", __FUNCTION__, count); } void CEpgContainer::CleanupEpgEvents(const CEpgPtr& epg) diff --git a/xbmc/epg/EpgDatabase.cpp b/xbmc/epg/EpgDatabase.cpp index da1ccf6..d1f0a1e 100644 --- a/xbmc/epg/EpgDatabase.cpp +++ b/xbmc/epg/EpgDatabase.cpp @@ -42,7 +42,7 @@ void CEpgDatabase::CreateTables(void) { CLog::Log(LOGINFO, "EpgDB - %s - creating tables", __FUNCTION__); - CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epg'", __FUNCTION__); + CLog::Log(LOGPVR, "EpgDB - %s - creating table 'epg'", __FUNCTION__); m_pDS->exec( "CREATE TABLE epg (" "idEpg integer primary key, " @@ -51,7 +51,7 @@ void CEpgDatabase::CreateTables(void) ")" ); - CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'epgtags'", __FUNCTION__); + CLog::Log(LOGPVR, "EpgDB - %s - creating table 'epgtags'", __FUNCTION__); m_pDS->exec( "CREATE TABLE epgtags (" "idBroadcast integer primary key, " @@ -83,7 +83,7 @@ void CEpgDatabase::CreateTables(void) "iFlags integer" ")" ); - CLog::Log(LOGDEBUG, "EpgDB - %s - creating table 'lastepgscan'", __FUNCTION__); + CLog::Log(LOGPVR, "EpgDB - %s - creating table 'lastepgscan'", __FUNCTION__); m_pDS->exec("CREATE TABLE lastepgscan (" "idEpg integer primary key, " "sLastScan varchar(20)" @@ -93,7 +93,7 @@ void CEpgDatabase::CreateTables(void) void CEpgDatabase::CreateAnalytics() { - CLog::Log(LOGDEBUG, "%s - creating indices", __FUNCTION__); + CLog::Log(LOGPVR, "%s - creating indices", __FUNCTION__); m_pDS->exec("CREATE UNIQUE INDEX idx_epg_idEpg_iStartTime on epgtags(idEpg, iStartTime desc);"); m_pDS->exec("CREATE INDEX idx_epg_iEndTime on epgtags(iEndTime);"); } @@ -125,7 +125,7 @@ void CEpgDatabase::UpdateTables(int iVersion) bool CEpgDatabase::DeleteEpg(void) { bool bReturn(false); - CLog::Log(LOGDEBUG, "EpgDB - %s - deleting all EPG data from the database", __FUNCTION__); + CLog::Log(LOGPVR, "EpgDB - %s - deleting all EPG data from the database", __FUNCTION__); bReturn = DeleteValues("epg") || bReturn; bReturn = DeleteValues("epgtags") || bReturn; diff --git a/xbmc/epg/EpgInfoTag.cpp b/xbmc/epg/EpgInfoTag.cpp index 18574cf..f9f96ca 100644 --- a/xbmc/epg/EpgInfoTag.cpp +++ b/xbmc/epg/EpgInfoTag.cpp @@ -675,7 +675,7 @@ bool CEpgInfoTag::Persist(bool bSingleUpdate /* = true */) bool bReturn = false; #if EPG_DEBUGGING - CLog::Log(LOGDEBUG, "Epg - %s - Infotag '%s' %s, persisting...", __FUNCTION__, m_strTitle.c_str(), m_iBroadcastId > 0 ? "has changes" : "is new"); + CLog::Log(LOGPVR, "Epg - %s - Infotag '%s' %s, persisting...", __FUNCTION__, m_strTitle.c_str(), m_iBroadcastId > 0 ? "has changes" : "is new"); #endif CEpgDatabase *database = g_EpgContainer.GetDatabase(); diff --git a/xbmc/epg/GUIEPGGridContainer.cpp b/xbmc/epg/GUIEPGGridContainer.cpp index b08bf5c..b6d5ac5 100644 --- a/xbmc/epg/GUIEPGGridContainer.cpp +++ b/xbmc/epg/GUIEPGGridContainer.cpp @@ -1013,7 +1013,7 @@ void CGUIEPGGridContainer::UpdateItems(CFileItemList *items) /******************************************* END ******************************************/ - CLog::Log(LOGDEBUG, "CGUIEPGGridContainer - %s completed successfully in %u ms", __FUNCTION__, (unsigned int)(XbmcThreads::SystemClockMillis()-tick)); + CLog::Log(LOGPVR, "CGUIEPGGridContainer - %s completed successfully in %u ms", __FUNCTION__, (unsigned int)(XbmcThreads::SystemClockMillis()-tick)); m_channels = m_epgItemsPtr.size(); @@ -1983,7 +1983,7 @@ void CGUIEPGGridContainer::SetStartEnd(CDateTime start, CDateTime end) m_gridStart = CDateTime(start.GetYear(), start.GetMonth(), start.GetDay(), start.GetHour(), start.GetMinute() >= 30 ? 30 : 0, 0); m_gridEnd = CDateTime(end.GetYear(), end.GetMonth(), end.GetDay(), end.GetHour(), end.GetMinute() >= 30 ? 30 : 0, 0); - CLog::Log(LOGDEBUG, "CGUIEPGGridContainer - %s - start=%s end=%s", + CLog::Log(LOGPVR, "CGUIEPGGridContainer - %s - start=%s end=%s", __FUNCTION__, m_gridStart.GetAsLocalizedDateTime(false, true).c_str(), m_gridEnd.GetAsLocalizedDateTime(false, true).c_str()); } diff --git a/xbmc/pvr/PVRActionListener.cpp b/xbmc/pvr/PVRActionListener.cpp index d8e29a1..ff5a312 100644 --- a/xbmc/pvr/PVRActionListener.cpp +++ b/xbmc/pvr/PVRActionListener.cpp @@ -111,7 +111,7 @@ bool CPVRActionListener::OnAction(const CAction &action) CFileItemPtr fileItem = group->GetLastPlayedChannel(playingChannel->ChannelID()); if (fileItem && fileItem->HasPVRChannelInfoTag()) { - CLog::Log(LOGDEBUG, "%s - switch to channel number %d", __FUNCTION__, fileItem->GetPVRChannelInfoTag()->ChannelNumber()); + CLog::Log(LOGPVR, "%s - switch to channel number %d", __FUNCTION__, fileItem->GetPVRChannelInfoTag()->ChannelNumber()); CApplicationMessenger::GetInstance().SendMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1,static_cast( new CAction(ACTION_CHANNEL_SWITCH, static_cast(fileItem->GetPVRChannelInfoTag()->ChannelNumber())))); } diff --git a/xbmc/pvr/PVRDatabase.cpp b/xbmc/pvr/PVRDatabase.cpp index 5b19bff..a0d9492 100644 --- a/xbmc/pvr/PVRDatabase.cpp +++ b/xbmc/pvr/PVRDatabase.cpp @@ -47,7 +47,7 @@ void CPVRDatabase::CreateTables() { CLog::Log(LOGINFO, "PVR - %s - creating tables", __FUNCTION__); - CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channels'", __FUNCTION__); + CLog::Log(LOGPVR, "PVR - %s - creating table 'channels'", __FUNCTION__); m_pDS->exec( "CREATE TABLE channels (" "idChannel integer primary key, " @@ -71,7 +71,7 @@ void CPVRDatabase::CreateTables() ")" ); - CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelgroups'", __FUNCTION__); + CLog::Log(LOGPVR, "PVR - %s - creating table 'channelgroups'", __FUNCTION__); m_pDS->exec( "CREATE TABLE channelgroups (" "idGroup integer primary key," @@ -84,7 +84,7 @@ void CPVRDatabase::CreateTables() ")" ); - CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channelgroups_channels'", __FUNCTION__); + CLog::Log(LOGPVR, "PVR - %s - creating table 'map_channelgroups_channels'", __FUNCTION__); m_pDS->exec( "CREATE TABLE map_channelgroups_channels (" "idChannel integer, " @@ -186,7 +186,7 @@ void CPVRDatabase::UpdateTables(int iVersion) bool CPVRDatabase::DeleteChannels(void) { - CLog::Log(LOGDEBUG, "PVR - %s - deleting all channels from the database", __FUNCTION__); + CLog::Log(LOGPVR, "PVR - %s - deleting all channels from the database", __FUNCTION__); return DeleteValues("channels"); } @@ -199,7 +199,7 @@ bool CPVRDatabase::DeleteClientChannels(const CPVRClient &client) return false; } - CLog::Log(LOGDEBUG, "PVR - %s - deleting all channels from client '%i' from the database", __FUNCTION__, client.GetID()); + CLog::Log(LOGPVR, "PVR - %s - deleting all channels from client '%i' from the database", __FUNCTION__, client.GetID()); Filter filter; filter.AppendWhere(PrepareSQL("iClientId = %u", client.GetID())); @@ -213,7 +213,7 @@ bool CPVRDatabase::Delete(const CPVRChannel &channel) if (channel.ChannelID() <= 0) return false; - CLog::Log(LOGDEBUG, "PVR - %s - deleting channel '%s' from the database", __FUNCTION__, channel.ChannelName().c_str()); + CLog::Log(LOGPVR, "PVR - %s - deleting channel '%s' from the database", __FUNCTION__, channel.ChannelName().c_str()); Filter filter; filter.AppendWhere(PrepareSQL("idChannel = %u", channel.ChannelID())); @@ -260,7 +260,7 @@ int CPVRDatabase::Get(CPVRChannelGroupInternal &results) channel->UpdateEncryptionName(); #if PVRDB_DEBUGGING - CLog::Log(LOGDEBUG, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); + CLog::Log(LOGPVR, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); #endif PVRChannelGroupMember newMember = { channel, (unsigned int)m_pDS->fv("iChannelNumber").get_asInt() }; results.m_sortedMembers.push_back(newMember); @@ -439,7 +439,7 @@ bool CPVRDatabase::RemoveStaleChannelsFromGroup(const CPVRChannelGroup &group) bool CPVRDatabase::DeleteChannelGroups(void) { - CLog::Log(LOGDEBUG, "PVR - %s - deleting all channel groups from the database", __FUNCTION__); + CLog::Log(LOGPVR, "PVR - %s - deleting all channel groups from the database", __FUNCTION__); return DeleteValues("channelgroups") && DeleteValues("map_channelgroups_channels"); @@ -480,7 +480,7 @@ bool CPVRDatabase::Get(CPVRChannelGroups &results) data.SetPosition(m_pDS->fv("iPosition").get_asInt()); results.Update(data); - CLog::Log(LOGDEBUG, "PVR - %s - group '%s' loaded from the database", __FUNCTION__, data.GroupName().c_str()); + CLog::Log(LOGPVR, "PVR - %s - group '%s' loaded from the database", __FUNCTION__, data.GroupName().c_str()); m_pDS->next(); } m_pDS->close(); @@ -522,7 +522,7 @@ int CPVRDatabase::Get(CPVRChannelGroup &group) if (channel) { #if PVRDB_DEBUGGING - CLog::Log(LOGDEBUG, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); + CLog::Log(LOGPVR, "PVR - %s - channel '%s' loaded from the database", __FUNCTION__, channel->m_strChannelName.c_str()); #endif PVRChannelGroupMember newMember = { channel, (unsigned int)iChannelNumber }; group.m_sortedMembers.push_back(newMember); diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index 9ceacf6..9faa21a 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -107,7 +107,7 @@ CPVRManager::~CPVRManager(void) { CAnnouncementManager::GetInstance().RemoveAnnouncer(this); Stop(); - CLog::Log(LOGDEBUG,"PVRManager - destroyed"); + CLog::Log(LOGPVR,"PVRManager - destroyed"); } void CPVRManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) @@ -345,7 +345,7 @@ bool CPVRManager::UpgradeOutdatedAddons(void) g_EpgContainer.Start(true); } - CLog::Log(LOGDEBUG, "PVRManager - %s - restarted", __FUNCTION__); + CLog::Log(LOGPVR, "PVRManager - %s - restarted", __FUNCTION__); return true; } @@ -524,7 +524,7 @@ void CPVRManager::Process(void) g_EpgContainer.Start(true); /* main loop */ - CLog::Log(LOGDEBUG, "PVRManager - %s - entering main loop", __FUNCTION__); + CLog::Log(LOGPVR, "PVRManager - %s - entering main loop", __FUNCTION__); bool bRestart(false); while (IsStarted() && m_addons && m_addons->HasConnectedClients() && !bRestart) @@ -635,7 +635,7 @@ bool CPVRManager::Load(void) if (!IsInitialising() || !m_addons || !m_addons->HasConnectedClients()) return false; - CLog::Log(LOGDEBUG, "PVRManager - %s - active clients found. continue to start", __FUNCTION__); + CLog::Log(LOGPVR, "PVRManager - %s - active clients found. continue to start", __FUNCTION__); /* reset observer for pvr windows */ for (std::size_t i = 0; i != ARRAY_SIZE(m_pvrWindowIds); i++) @@ -751,7 +751,7 @@ bool CPVRManager::ContinueLastChannel(void) return true; } - CLog::Log(LOGDEBUG, "PVRManager - %s - no last played channel to continue playback found", __FUNCTION__); + CLog::Log(LOGPVR, "PVRManager - %s - no last played channel to continue playback found", __FUNCTION__); return false; } @@ -877,7 +877,7 @@ int CPVRManager::GetCurrentEpg(CFileItemList &results) const if (channel) iReturn = channel->GetEPG(results); else - CLog::Log(LOGDEBUG,"PVRManager - %s - no current channel set", __FUNCTION__); + CLog::Log(LOGPVR,"PVRManager - %s - no current channel set", __FUNCTION__); return iReturn; } @@ -1058,7 +1058,7 @@ bool CPVRManager::OpenLiveStream(const CFileItem &fileItem) if (!fileItem.HasPVRChannelInfoTag()) return bReturn; - CLog::Log(LOGDEBUG,"PVRManager - %s - opening live stream on channel '%s'", + CLog::Log(LOGPVR,"PVRManager - %s - opening live stream on channel '%s'", __FUNCTION__, fileItem.GetPVRChannelInfoTag()->ChannelName().c_str()); // check if we're allowed to play this file @@ -1335,7 +1335,7 @@ bool CPVRManager::PerformChannelSwitch(const CPVRChannelPtr &channel, bool bPrev CSingleLock lock(m_critSection); if (m_bIsSwitchingChannels) { - CLog::Log(LOGDEBUG, "PVRManager - %s - can't switch to channel '%s'. waiting for the previous switch to complete", + CLog::Log(LOGPVR, "PVRManager - %s - can't switch to channel '%s'. waiting for the previous switch to complete", __FUNCTION__, channel->ChannelName().c_str()); return false; } @@ -1351,7 +1351,7 @@ bool CPVRManager::PerformChannelSwitch(const CPVRChannelPtr &channel, bool bPrev m_bIsSwitchingChannels = true; } - CLog::Log(LOGDEBUG, "PVRManager - %s - switching to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); + CLog::Log(LOGPVR, "PVRManager - %s - switching to channel '%s'", __FUNCTION__, channel->ChannelName().c_str()); // will be deleted by CPVRChannelSwitchJob::DoWork() CFileItem* previousFile = m_currentFile; diff --git a/xbmc/pvr/addons/PVRClient.cpp b/xbmc/pvr/addons/PVRClient.cpp index 395caca..645716d 100644 --- a/xbmc/pvr/addons/PVRClient.cpp +++ b/xbmc/pvr/addons/PVRClient.cpp @@ -174,7 +174,7 @@ ADDON_STATUS CPVRClient::Create(int iClientId) /* initialise the add-on */ bool bReadyToUse(false); - CLog::Log(LOGDEBUG, "PVR - %s - creating PVR add-on instance '%s'", __FUNCTION__, Name().c_str()); + CLog::Log(LOGPVR, "PVR - %s - creating PVR add-on instance '%s'", __FUNCTION__, Name().c_str()); try { if ((status = CAddonDll::Create()) == ADDON_STATUS_OK) @@ -202,7 +202,7 @@ void CPVRClient::Destroy(void) m_bReadyToUse = false; /* reset 'ready to use' to false */ - CLog::Log(LOGDEBUG, "PVR - %s - destroying PVR add-on '%s'", __FUNCTION__, GetFriendlyName().c_str()); + CLog::Log(LOGPVR, "PVR - %s - destroying PVR add-on '%s'", __FUNCTION__, GetFriendlyName().c_str()); /* destroy the add-on */ try { CAddonDll::Destroy(); } @@ -842,7 +842,7 @@ PVR_ERROR CPVRClient::GetChannelGroupMembers(CPVRChannelGroup *group) PVR_CHANNEL_GROUP tag; WriteClientGroupInfo(*group, tag); - CLog::Log(LOGDEBUG, "PVR - %s - get group members for group '%s' from add-on '%s'", + CLog::Log(LOGPVR, "PVR - %s - get group members for group '%s' from add-on '%s'", __FUNCTION__, tag.strGroupName, GetFriendlyName().c_str()); retVal = m_pStruct->GetChannelGroupMembers(&handle, tag); @@ -1702,11 +1702,11 @@ bool CPVRClient::OpenStream(const CPVRChannelPtr &channel, bool bIsSwitchingChan if(!CanPlayChannel(channel)) { - CLog::Log(LOGDEBUG, "add-on '%s' can not play channel '%s'", GetFriendlyName().c_str(), channel->ChannelName().c_str()); + CLog::Log(LOGPVR, "add-on '%s' can not play channel '%s'", GetFriendlyName().c_str(), channel->ChannelName().c_str()); } else if (!channel->StreamURL().empty()) { - CLog::Log(LOGDEBUG, "opening live stream on url '%s'", channel->StreamURL().c_str()); + CLog::Log(LOGPVR, "opening live stream on url '%s'", channel->StreamURL().c_str()); bReturn = true; // the Njoy N7 sometimes doesn't switch channels, but opens a stream to the previous channel @@ -1722,7 +1722,7 @@ bool CPVRClient::OpenStream(const CPVRChannelPtr &channel, bool bIsSwitchingChan } else { - CLog::Log(LOGDEBUG, "opening live stream for channel '%s'", channel->ChannelName().c_str()); + CLog::Log(LOGPVR, "opening live stream for channel '%s'", channel->ChannelName().c_str()); PVR_CHANNEL tag; WriteClientChannelInfo(channel, tag); @@ -1945,14 +1945,14 @@ bool CPVRClient::Autoconfigure(void) { // %s service found at %s std::string strLogLine(StringUtils::Format(g_localizeStrings.Get(19689).c_str(), (*it).GetName().c_str(), (*it).GetIP().c_str())); - CLog::Log(LOGDEBUG, "%s - %s", __FUNCTION__, strLogLine.c_str()); + CLog::Log(LOGPVR, "%s - %s", __FUNCTION__, strLogLine.c_str()); if (DialogResponse::YES != HELPERS::ShowYesNoDialogLines(CVariant{19688}, // Scanning for PVR services CVariant{strLogLine}, CVariant{19690})) // Do you want to use this service? { - CLog::Log(LOGDEBUG, "%s - %s service found but not enabled by the user", __FUNCTION__, (*it).GetName().c_str()); + CLog::Log(LOGPVR, "%s - %s service found but not enabled by the user", __FUNCTION__, (*it).GetName().c_str()); m_rejectedAvahiHosts.push_back(*it); } else diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp index da39071..4c22a9b 100644 --- a/xbmc/pvr/addons/PVRClients.cpp +++ b/xbmc/pvr/addons/PVRClients.cpp @@ -367,7 +367,7 @@ bool CPVRClients::SwitchChannel(const CPVRChannelPtr &channel) CSingleLock lock(m_critSection); if (m_bIsSwitchingChannels) { - CLog::Log(LOGDEBUG, "PVRClients - %s - can't switch to channel '%s'. waiting for the previous switch to complete", __FUNCTION__, channel->ChannelName().c_str()); + CLog::Log(LOGPVR, "PVRClients - %s - can't switch to channel '%s'. waiting for the previous switch to complete", __FUNCTION__, channel->ChannelName().c_str()); return false; } m_bIsSwitchingChannels = true; @@ -1111,7 +1111,7 @@ int CPVRClients::RegisterClient(AddonPtr client) if (!client->Enabled() || !database.Open()) return -1; - CLog::Log(LOGDEBUG, "%s - registering add-on '%s'", __FUNCTION__, client->Name().c_str()); + CLog::Log(LOGPVR, "%s - registering add-on '%s'", __FUNCTION__, client->Name().c_str()); // check whether we already know this client iClientId = database.GetAddonId(client); //database->GetClientId(client->ID()); @@ -1396,7 +1396,7 @@ bool CPVRClients::UpdateAddons(void) if (bDisable) { - CLog::Log(LOGDEBUG, "%s - disabling add-on '%s'", __FUNCTION__, (*it)->Name().c_str()); + CLog::Log(LOGPVR, "%s - disabling add-on '%s'", __FUNCTION__, (*it)->Name().c_str()); CAddonMgr::GetInstance().DisableAddon((*it)->ID()); usableClients--; } diff --git a/xbmc/pvr/channels/PVRChannel.cpp b/xbmc/pvr/channels/PVRChannel.cpp index 9957537..a94deb5 100644 --- a/xbmc/pvr/channels/PVRChannel.cpp +++ b/xbmc/pvr/channels/PVRChannel.cpp @@ -546,7 +546,7 @@ int CPVRChannel::GetEPG(CFileItemList &results) const CEpgPtr epg = GetEPG(); if (!epg) { - CLog::Log(LOGDEBUG, "PVR - %s - cannot get EPG for channel '%s'", + CLog::Log(LOGPVR, "PVR - %s - cannot get EPG for channel '%s'", __FUNCTION__, m_strChannelName.c_str()); return -1; } diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp index 8a2af48..0b1b846 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.cpp +++ b/xbmc/pvr/channels/PVRChannelGroup.cpp @@ -162,7 +162,7 @@ bool CPVRChannelGroup::Load(void) m_bUsingBackendChannelNumbers = CSettings::GetInstance().GetBool(CSettings::SETTING_PVRMANAGER_USEBACKENDCHANNELNUMBERS); int iChannelCount = m_iGroupId > 0 ? LoadFromDb() : 0; - CLog::Log(LOGDEBUG, "PVRChannelGroup - %s - %d channels loaded from the database for group '%s'", + CLog::Log(LOGPVR, "PVRChannelGroup - %s - %d channels loaded from the database for group '%s'", __FUNCTION__, iChannelCount, m_strGroupName.c_str()); if (!Update()) @@ -173,7 +173,7 @@ bool CPVRChannelGroup::Load(void) if (Size() - iChannelCount > 0) { - CLog::Log(LOGDEBUG, "PVRChannelGroup - %s - %d channels added from clients to group '%s'", + CLog::Log(LOGPVR, "PVRChannelGroup - %s - %d channels added from clients to group '%s'", __FUNCTION__, static_cast(Size() - iChannelCount), m_strGroupName.c_str()); } @@ -900,7 +900,7 @@ bool CPVRChannelGroup::Persist(void) if (CPVRDatabase *database = GetPVRDatabase()) { - CLog::Log(LOGDEBUG, "CPVRChannelGroup - %s - persisting channel group '%s' with %d channels", + CLog::Log(LOGPVR, "CPVRChannelGroup - %s - persisting channel group '%s' with %d channels", __FUNCTION__, GroupName().c_str(), (int) m_members.size()); m_bChanged = false; lock.Leave(); @@ -1034,7 +1034,7 @@ void CPVRChannelGroup::OnSettingChanged(const CSetting *setting) /* check whether this channel group has to be renumbered */ if (bChannelOrderChanged || bChannelNumbersChanged) { - CLog::Log(LOGDEBUG, "CPVRChannelGroup - %s - renumbering group '%s' to use the backend channel order and/or numbers", + CLog::Log(LOGPVR, "CPVRChannelGroup - %s - renumbering group '%s' to use the backend channel order and/or numbers", __FUNCTION__, m_strGroupName.c_str()); SortAndRenumber(); Persist(); diff --git a/xbmc/pvr/channels/PVRChannelGroups.cpp b/xbmc/pvr/channels/PVRChannelGroups.cpp index 95bf4b5..e229688 100644 --- a/xbmc/pvr/channels/PVRChannelGroups.cpp +++ b/xbmc/pvr/channels/PVRChannelGroups.cpp @@ -243,7 +243,7 @@ bool CPVRChannelGroups::UpdateGroupsEntries(const CPVRChannelGroups &groups) // user defined group wasn't found if (existingGroup.GroupType() == PVR_GROUP_TYPE_DEFAULT && !group) { - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - user defined group %s with id '%u' does not exist on the client anymore; deleting it", __FUNCTION__, existingGroup.GroupName().c_str(), existingGroup.GroupID()); + CLog::Log(LOGPVR, "CPVRChannelGroups - %s - user defined group %s with id '%u' does not exist on the client anymore; deleting it", __FUNCTION__, existingGroup.GroupName().c_str(), existingGroup.GroupID()); DeleteGroup(*m_groups.at(iGroupPtr)); } } @@ -278,10 +278,10 @@ bool CPVRChannelGroups::LoadUserDefinedChannelGroups(void) if (bSyncWithBackends) { GetGroupsFromClients(); - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" new user defined %s channel groups fetched from clients", __FUNCTION__, (m_groups.size() - iSize), m_bRadio ? "radio" : "TV"); + CLog::Log(LOGPVR, "CPVRChannelGroups - %s - %" PRIuS" new user defined %s channel groups fetched from clients", __FUNCTION__, (m_groups.size() - iSize), m_bRadio ? "radio" : "TV"); } else - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - 'synchannelgroups' is disabled; skipping groups from clients", __FUNCTION__); + CLog::Log(LOGPVR, "CPVRChannelGroups - %s - 'synchannelgroups' is disabled; skipping groups from clients", __FUNCTION__); std::vector emptyGroups; @@ -293,7 +293,7 @@ bool CPVRChannelGroups::LoadUserDefinedChannelGroups(void) { if (!(*it)->Load()) { - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - failed to load channel group '%s'", __FUNCTION__, (*it)->GroupName().c_str()); + CLog::Log(LOGPVR, "CPVRChannelGroups - %s - failed to load channel group '%s'", __FUNCTION__, (*it)->GroupName().c_str()); return false; } @@ -305,7 +305,7 @@ bool CPVRChannelGroups::LoadUserDefinedChannelGroups(void) for (std::vector::iterator it = emptyGroups.begin(); it != emptyGroups.end(); ++it) { - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - deleting empty group '%s'", __FUNCTION__, (*it)->GroupName().c_str()); + CLog::Log(LOGPVR, "CPVRChannelGroups - %s - deleting empty group '%s'", __FUNCTION__, (*it)->GroupName().c_str()); DeleteGroup(*(*it)); } @@ -324,7 +324,7 @@ bool CPVRChannelGroups::Load(void) // remove previous contents Clear(); - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - loading all %s channel groups", __FUNCTION__, m_bRadio ? "radio" : "TV"); + CLog::Log(LOGPVR, "CPVRChannelGroups - %s - loading all %s channel groups", __FUNCTION__, m_bRadio ? "radio" : "TV"); // create the internal channel group CPVRChannelGroupPtr internalGroup = CPVRChannelGroupPtr(new CPVRChannelGroupInternal(m_bRadio)); @@ -332,7 +332,7 @@ bool CPVRChannelGroups::Load(void) // load groups from the database database->Get(*this); - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" %s groups fetched from the database", __FUNCTION__, m_groups.size(), m_bRadio ? "radio" : "TV"); + CLog::Log(LOGPVR, "CPVRChannelGroups - %s - %" PRIuS" %s groups fetched from the database", __FUNCTION__, m_groups.size(), m_bRadio ? "radio" : "TV"); // load channels of internal group if (!internalGroup->Load()) @@ -352,7 +352,7 @@ bool CPVRChannelGroups::Load(void) CPVRChannelGroupPtr lastPlayedGroup = GetLastPlayedGroup(); SetSelectedGroup(lastPlayedGroup ? lastPlayedGroup : internalGroup); - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - %" PRIuS" %s channel groups loaded", __FUNCTION__, m_groups.size(), m_bRadio ? "radio" : "TV"); + CLog::Log(LOGPVR, "CPVRChannelGroups - %s - %" PRIuS" %s channel groups loaded", __FUNCTION__, m_groups.size(), m_bRadio ? "radio" : "TV"); // need at least 1 group return m_groups.size() > 0; @@ -361,7 +361,7 @@ bool CPVRChannelGroups::Load(void) bool CPVRChannelGroups::PersistAll(void) { bool bReturn(true); - CLog::Log(LOGDEBUG, "CPVRChannelGroups - %s - persisting all changes in channel groups", __FUNCTION__); + CLog::Log(LOGPVR, "CPVRChannelGroups - %s - persisting all changes in channel groups", __FUNCTION__); CSingleLock lock(m_critSection); for (std::vector::iterator it = m_groups.begin(); it != m_groups.end(); ++it) diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp index 70883dc..3898459 100644 --- a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp +++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp @@ -54,7 +54,7 @@ bool CPVRChannelGroupsContainer::Update(bool bChannelsOnly /* = false */) m_bUpdateChannelsOnly = bChannelsOnly; lock.Leave(); - CLog::Log(LOGDEBUG, "CPVRChannelGroupsContainer - %s - updating %s", __FUNCTION__, bChannelsOnly ? "channels" : "channel groups"); + CLog::Log(LOGPVR, "CPVRChannelGroupsContainer - %s - updating %s", __FUNCTION__, bChannelsOnly ? "channels" : "channel groups"); bool bReturn = m_groupsRadio->Update(bChannelsOnly) && m_groupsTV->Update(bChannelsOnly); diff --git a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp index e49e8bb..706cbaf 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp +++ b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp @@ -588,7 +588,7 @@ void CGUIDialogPVRTimerSettings::Save() { if (m_endLocalTime < m_startLocalTime) // And the end clock is earlier than the start clock { - CLog::Log(LOGDEBUG, "CGUIDialogPVRTimerSettings::Save - End before start, adding a day."); + CLog::Log(LOGPVR, "CGUIDialogPVRTimerSettings::Save - End before start, adding a day."); m_endLocalTime += CDateTimeSpan(1, 0, 0, 0); if (m_endLocalTime < m_startLocalTime) { @@ -598,7 +598,7 @@ void CGUIDialogPVRTimerSettings::Save() } else if (m_endLocalTime > (m_startLocalTime + CDateTimeSpan(1, 0, 0, 0))) // Or the duration is more than a day { - CLog::Log(LOGDEBUG, "CGUIDialogPVRTimerSettings::Save - End > 1 day after start, removing a day."); + CLog::Log(LOGPVR, "CGUIDialogPVRTimerSettings::Save - End > 1 day after start, removing a day."); m_endLocalTime -= CDateTimeSpan(1, 0, 0, 0); if (m_endLocalTime > (m_startLocalTime + CDateTimeSpan(1, 0, 0, 0))) { diff --git a/xbmc/pvr/recordings/PVRRecording.cpp b/xbmc/pvr/recordings/PVRRecording.cpp index b25da21..2c32307 100644 --- a/xbmc/pvr/recordings/PVRRecording.cpp +++ b/xbmc/pvr/recordings/PVRRecording.cpp @@ -375,7 +375,7 @@ void CPVRRecording::Update(const CPVRRecording &tag) std::string strShow = StringUtils::Format("%s - ", g_localizeStrings.Get(20364).c_str()); if (StringUtils::StartsWithNoCase(m_strPlotOutline, strShow)) { - CLog::Log(LOGDEBUG,"CPVRRecording::Update - PVR addon provides episode name in strPlotOutline which is deprecated"); + CLog::Log(LOGPVR,"CPVRRecording::Update - PVR addon provides episode name in strPlotOutline which is deprecated"); std::string strEpisode = m_strPlotOutline; std::string strTitle = m_strDirectory; diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp index 5288a34..5c2afac 100644 --- a/xbmc/pvr/recordings/PVRRecordings.cpp +++ b/xbmc/pvr/recordings/PVRRecordings.cpp @@ -179,7 +179,7 @@ void CPVRRecordings::Update(void) m_bIsUpdating = true; lock.Leave(); - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - updating recordings", __FUNCTION__); + CLog::Log(LOGPVR, "CPVRRecordings - %s - updating recordings", __FUNCTION__); UpdateFromClients(); lock.Enter(); @@ -290,7 +290,7 @@ bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) { bResult = true; - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - item path %s", __FUNCTION__, item->GetPath().c_str()); + CLog::Log(LOGPVR, "CPVRRecordings - %s - item path %s", __FUNCTION__, item->GetPath().c_str()); CFileItemList items; if (item->m_bIsFolder) { @@ -299,15 +299,15 @@ bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) else items.Add(item); - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - will set watched for %d items", __FUNCTION__, items.Size()); + CLog::Log(LOGPVR, "CPVRRecordings - %s - will set watched for %d items", __FUNCTION__, items.Size()); for (int i=0;im_bIsFolder) { - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - path %s is a folder, will call recursively", __FUNCTION__, pItem->GetPath().c_str()); + CLog::Log(LOGPVR, "CPVRRecordings - %s - path %s is a folder, will call recursively", __FUNCTION__, pItem->GetPath().c_str()); if (pItem->GetLabel() != "..") { SetRecordingsPlayCount(pItem, count); diff --git a/xbmc/pvr/timers/PVRTimers.cpp b/xbmc/pvr/timers/PVRTimers.cpp index 5c9ed15..a9e3ef7 100644 --- a/xbmc/pvr/timers/PVRTimers.cpp +++ b/xbmc/pvr/timers/PVRTimers.cpp @@ -82,7 +82,7 @@ bool CPVRTimers::Update(void) m_bIsUpdating = true; } - CLog::Log(LOGDEBUG, "CPVRTimers - %s - updating timers", __FUNCTION__); + CLog::Log(LOGPVR, "CPVRTimers - %s - updating timers", __FUNCTION__); CPVRTimers newTimerList; g_PVRClients->GetTimers(&newTimerList); return UpdateEntries(newTimerList); @@ -131,7 +131,7 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) timerNotifications.push_back(strMessage); } - CLog::Log(LOGDEBUG,"PVRTimers - %s - updated timer %d on client %d", + CLog::Log(LOGPVR,"PVRTimers - %s - updated timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } @@ -167,7 +167,7 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) timerNotifications.push_back(strMessage); } - CLog::Log(LOGDEBUG,"PVRTimers - %s - added timer %d on client %d", + CLog::Log(LOGPVR,"PVRTimers - %s - added timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); } } @@ -185,7 +185,7 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) if (!timers.GetByClient(timer->m_iClientId, timer->m_iClientIndex)) { /* timer was not found */ - CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", + CLog::Log(LOGPVR,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); if (g_PVRManager.IsStarted()) @@ -202,7 +202,7 @@ bool CPVRTimers::UpdateEntries(const CPVRTimers &timers) (!timer->m_bStartAnyTime && timer->StartAsUTC() != it->first)) { /* timer start has changed */ - CLog::Log(LOGDEBUG,"PVRTimers - %s - changed start time timer %d on client %d", + CLog::Log(LOGPVR,"PVRTimers - %s - changed start time timer %d on client %d", __FUNCTION__, timer->m_iClientIndex, timer->m_iClientId); timer->ClearEpgTag(); @@ -496,7 +496,7 @@ bool CPVRTimers::DeleteTimersOnChannel(const CPVRChannelPtr &channel, bool bDele if (bDeleteActiveItem && bDeleteRepeatingItem && bChannelsMatch) { - CLog::Log(LOGDEBUG,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); + CLog::Log(LOGPVR,"PVRTimers - %s - deleted timer %d on client %d", __FUNCTION__, (*timerIt)->m_iClientIndex, (*timerIt)->m_iClientId); bReturn = (*timerIt)->DeleteFromClient(true) || bReturn; SetChanged(); } -- 2.7.1 From 1c528d8fb063f1f25caeebcebc2f8fe1913afd02 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 15 Feb 2016 03:29:35 +0100 Subject: [PATCH 228/250] add support for EDID provided in binary form from /sys --- xbmc/windowing/egl/EGLEdid.cpp | 1 + xbmc/windowing/egl/EGLEdid.h | 3 +++ xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 15 ++++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/xbmc/windowing/egl/EGLEdid.cpp b/xbmc/windowing/egl/EGLEdid.cpp index 0a82225..1e24c1d 100644 --- a/xbmc/windowing/egl/EGLEdid.cpp +++ b/xbmc/windowing/egl/EGLEdid.cpp @@ -30,6 +30,7 @@ CEGLEdid::CEGLEdid() : m_fSar(0.0f) , m_edidEmpty(true) { + memset(&m_edid, 0, EDID_MAXSIZE); } CEGLEdid::~CEGLEdid() diff --git a/xbmc/windowing/egl/EGLEdid.h b/xbmc/windowing/egl/EGLEdid.h index 0483fb8..46f5b4f 100644 --- a/xbmc/windowing/egl/EGLEdid.h +++ b/xbmc/windowing/egl/EGLEdid.h @@ -29,6 +29,9 @@ #define EDID_DTM_START 0x36 #define EDID_DTM_OFFSET_DIMENSION 0x0c #define EDID_EXTENSION_BLOCK_START 0x7e + +static const char EDID_HEADER[8] = { 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0 }; + #define EDID_MAXSIZE 512 class CEGLEdid diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index aee2956..0c4a36e 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -471,6 +471,19 @@ bool CEGLEdid::ReadEdidData() if(!f_edid) return false; + // first check if EDID is in binary format by reading 512bytes, compare 1st 8bytes + // against EDID 1.4 identificator [0x0,0xff,0xff,0xff,0xff,0xff,0xff,0x0] + // if no match, seek to 0 input file and continue with previous method. + if (((done = fread(&m_edid, 1, EDID_MAXSIZE, f_edid)) % 128) == 0 && done) + if (!memcmp(&m_edid, &EDID_HEADER, 8)) + { + fclose(f_edid); + return true; + } + + done = 0; + memset(&m_edid, 0, EDID_MAXSIZE); + fseek(f_edid, 0L, SEEK_SET); // we need to convert mxc_hdmi output format to binary array // mxc_hdmi provides the EDID as space delimited 1bytes blocks // exported as text with format specifier %x eg: @@ -487,7 +500,7 @@ bool CEGLEdid::ReadEdidData() while(getline(&str, &n, f_edid) > 0) { char *c = str; - while(*c != '\n' && done < 512) + while(*c != '\n' && done < EDID_MAXSIZE) { c += 2; sscanf(c, "%hhx", &p); -- 2.7.1 From b2ae1ad788686938fd5d3d8246dba22619e1e282 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 15 Feb 2016 03:31:27 +0100 Subject: [PATCH 229/250] if fb is blank and we do resolution change, don't ublank after. --- xbmc/windowing/egl/EGLNativeTypeIMX.cpp | 9 ++++++++- xbmc/windowing/egl/EGLNativeTypeIMX.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp index 0c4a36e..9d6a5f5 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.cpp +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.cpp @@ -53,6 +53,7 @@ CEGLNativeTypeIMX::CEGLNativeTypeIMX() : m_display(NULL) , m_window(NULL) , m_ntsc(0) + , m_ignorenext(false) #endif { #ifdef HAS_IMXVPU @@ -440,8 +441,14 @@ bool CEGLNativeTypeIMX::GetPreferredResolution(RESOLUTION_INFO *res) const bool CEGLNativeTypeIMX::ShowWindow(bool show) { #ifdef HAS_IMXVPU - if (m_show == show) + + if (m_ignorenext || (m_show == show)) + { + if (!show) + m_ignorenext ^= 1; + return true; + } CLog::Log(LOGDEBUG, ": %s %s", __FUNCTION__, show?"show":"hide"); SysfsUtils::SetInt("/sys/class/graphics/fb0/blank", show ? 0 : 1 ); diff --git a/xbmc/windowing/egl/EGLNativeTypeIMX.h b/xbmc/windowing/egl/EGLNativeTypeIMX.h index ead9dfe..f7fcca8 100644 --- a/xbmc/windowing/egl/EGLNativeTypeIMX.h +++ b/xbmc/windowing/egl/EGLNativeTypeIMX.h @@ -65,5 +65,6 @@ protected: private: void SetStrMode(RESOLUTION_INFO *res) const; int m_ntsc; + bool m_ignorenext; #endif }; -- 2.7.1 From d45ce7a438cd6b5c847e42654653c96555318147 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 15 Feb 2016 03:32:08 +0100 Subject: [PATCH 230/250] idleSeconds change to 3min in case we play audio with visualisation --- xbmc/Application.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 40ac680..623f97f 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -2858,7 +2858,7 @@ void CApplication::FrameMove(bool processEvents, bool processGUI) if (processGUI && m_renderGUI) { m_skipGuiRender = false; - int idleSeconds = 3; + int idleSeconds = 15 * (m_pPlayer->IsPlayingAudio() && !m_pPlayer->IsPausedPlayback() ? 4*3/*3 min total*/ : 1); int fps = 0; #if defined(TARGET_RASPBERRY_PI) || defined(HAS_IMXVPU) @@ -2868,9 +2868,9 @@ void CApplication::FrameMove(bool processEvents, bool processGUI) #endif if ((idleSeconds && m_screenSaverTimer.GetElapsedSeconds() > idleSeconds) || !idleSeconds) #if defined(TARGET_RASPBERRY_PI) || defined(HAS_IMXVPU) - fps = CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_LIMITGUIUPDATE); + fps = CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_LIMITGUIUPDATE) * 2; #else - fps = 5; + fps = 10; #endif unsigned int now = XbmcThreads::SystemClockMillis(); -- 2.7.1 From 7547c1626f55a4178147e26647ae9a8409ba81b0 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 15 Feb 2016 03:35:07 +0100 Subject: [PATCH 231/250] change order of screen reconfig & with powering on, change delay to 3s. --- xbmc/peripherals/devices/PeripheralVideo.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/xbmc/peripherals/devices/PeripheralVideo.cpp b/xbmc/peripherals/devices/PeripheralVideo.cpp index b9e7331..7179111 100644 --- a/xbmc/peripherals/devices/PeripheralVideo.cpp +++ b/xbmc/peripherals/devices/PeripheralVideo.cpp @@ -61,7 +61,7 @@ void CPeripheralVideo::OnDeviceChanged(int state) if (m_timer.IsRunning()) m_timer.Restart(); else - m_timer.Start(5000); + m_timer.Start(3000); } bool CPeripheralVideo::IsQuantRangeLimited() @@ -101,15 +101,16 @@ void CPeripheralVideo::OnTimeout() switch (m_cableState) { case CABLE_CONNECTED: - g_screen.SetOn(); - CSettings::GetInstance().SetBool("videoscreen.limitedrange", IsQuantRangeLimited()); + if (CSettings::GetInstance().GetBool("videoscreen.updateresolutions")) { CApplicationMessenger::GetInstance().PostMsg(TMSG_DISPLAY_RECONFIGURE); CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, "VIDEO", g_localizeStrings.Get(13288)); } + g_screen.SetOn(); + break; case CABLE_DISCONNECTED: g_screen.SetOff(); -- 2.7.1 From 47f55227872726b468ba30b9ab50a92abea77e8b Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 15 Feb 2016 03:38:12 +0100 Subject: [PATCH 232/250] reset fps, pullup stats and drops on screen reconfiguration --- xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 7 +++++++ xbmc/cores/dvdplayer/DVDPlayerVideo.h | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp index df3d8b5..a1ad0fd 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp @@ -289,6 +289,13 @@ void CDVDPlayerVideo::OnStartup() m_FlipTimePts = 0.0; } +void CDVDPlayerVideo::DropStats() +{ + ResetFrameRateCalc(); + m_droppingStats.Reset(); + m_pullupCorrection.Flush(); +} + void CDVDPlayerVideo::Process() { CLog::Log(LOGNOTICE, "running thread: video_thread"); diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h index 3e0d065..8c296de 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h @@ -31,6 +31,7 @@ #include "cores/VideoRenderers/RenderManager.h" #endif #include "utils/BitstreamStats.h" +#include "guilib/DispResource.h" class CDemuxStreamVideo; @@ -55,7 +56,7 @@ public: unsigned int m_dropRequests; }; -class CDVDPlayerVideo : public CThread, public IDVDStreamPlayerVideo +class CDVDPlayerVideo : public CThread, public IDVDStreamPlayerVideo, IDispResource { public: CDVDPlayerVideo( CDVDClock* pClock @@ -63,6 +64,9 @@ public: , CDVDMessageQueue& parent); virtual ~CDVDPlayerVideo(); + void OnResetDevice() { DropStats(); } + void DropStats(); + bool OpenStream(CDVDStreamInfo &hint); void CloseStream(bool bWaitForBuffers); -- 2.7.1 From 6baa07f2aadc399920b17ad0fb8a5da5b57da4f6 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 15 Feb 2016 03:41:56 +0100 Subject: [PATCH 233/250] don't trigger wakeup if we do pause/stop --- xbmc/PlayListPlayer.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/xbmc/PlayListPlayer.cpp b/xbmc/PlayListPlayer.cpp index 6e5a40b..50e8ed2 100644 --- a/xbmc/PlayListPlayer.cpp +++ b/xbmc/PlayListPlayer.cpp @@ -904,7 +904,6 @@ void PLAYLIST::CPlayListPlayer::OnApplicationMessage(KODI::MESSAGING::ThreadMess g_windowManager.PreviousWindow(); g_application.ResetScreenSaver(); - g_application.WakeUpScreenSaverAndDPMS(); // stop playing file if (g_application.m_pPlayer->IsPlaying()) g_application.StopPlaying(); @@ -915,7 +914,6 @@ void PLAYLIST::CPlayListPlayer::OnApplicationMessage(KODI::MESSAGING::ThreadMess if (g_application.m_pPlayer->HasPlayer()) { g_application.ResetScreenSaver(); - g_application.WakeUpScreenSaverAndDPMS(); g_application.m_pPlayer->Pause(); } break; @@ -933,7 +931,6 @@ void PLAYLIST::CPlayListPlayer::OnApplicationMessage(KODI::MESSAGING::ThreadMess if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused()) { g_application.ResetScreenSaver(); - g_application.WakeUpScreenSaverAndDPMS(); g_application.m_pPlayer->Pause(); } break; -- 2.7.1 From 59f61ec948147b3740a3dcadc28c3343bb476e16 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 17 Feb 2016 12:12:48 +0100 Subject: [PATCH 234/250] unlock adapter sooner in the initialisation --- xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index e1bd1d0..c77ac23 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -1631,16 +1631,18 @@ bool CPeripheralCecAdapterUpdateThread::SetInitialConfiguration(void) bContinue) bContinue = !m_event.WaitMSec(1000); + { + CSingleLock lock(m_critSection); + m_adapter->m_bIsReady = true; + m_bIsUpdating = false; + } + // request the OSD name of the TV cec_osd_name tvName = m_adapter->m_cecAdapter->GetDeviceOSDName(CECDEVICE_TV); strNotification = StringUtils::Format("%s: %s", /*g_localizeStrings.Get(36016).c_str()*/"Connected", tvName.name); // and let the gui know that we're done CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, /*g_localizeStrings.Get(36000)*/"Pulse-Eight CEC adapter", strNotification); - - CSingleLock lock(m_critSection); - m_adapter->m_bIsReady = true; - m_bIsUpdating = false; return true; } -- 2.7.1 From 4c64eb3f1c81602864d45a8053809fd694cd4dff Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 22 Feb 2016 16:00:41 +0100 Subject: [PATCH 235/250] extra lock with DoubleRate deinterlacing. --- xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp index 1472bcf..f4f4f7d 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp @@ -660,6 +660,7 @@ void CLinuxRendererGLES::RenderUpdateVideo(bool clear, DWORD flags, DWORD alpha) if (buffer != NULL && buffer->IsValid()) { uint8_t fieldFmt = flags & RENDER_FLAG_FIELDMASK; + CDVDVideoCodecIMXBuffer *previous = NULL; if (flags & RENDER_FLAG_FIELDS) { fieldFmt |= IPU_DEINTERLACE_RATE_EN; @@ -670,10 +671,12 @@ void CLinuxRendererGLES::RenderUpdateVideo(bool clear, DWORD flags, DWORD alpha) // this makes IPU render same picture as before, just shifted one line // correct this fieldFmt ^= 0x3; + + previous = buffer; } } - g_IMXContext.BlitAsync(NULL, buffer, fieldFmt); + g_IMXContext.BlitAsync(previous, buffer, fieldFmt); } #if 0 -- 2.7.1 From e604690c2ca1b512e6a0cfd000faf672bd0f867c Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 22 Feb 2016 16:01:54 +0100 Subject: [PATCH 236/250] extra logging --- xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp index 39074ff..20e1c00 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp @@ -639,7 +639,8 @@ void CDVDPlayerAudio::SetSyncType(bool passthrough) { const char *synctypes[] = {"clock feedback", "skip/duplicate", "resample", "invalid"}; int synctype = (m_synctype >= 0 && m_synctype <= 2) ? m_synctype : 3; - CLog::Log(LOGDEBUG, "CDVDPlayerAudio:: synctype set to %i: %s", m_synctype, synctypes[synctype]); + CLog::Log(LOGDEBUG, "CDVDPlayerAudio:: synctype set to %i: %s (passthrough %s)", m_synctype, synctypes[synctype], + passthrough ? "yes" : "no"); m_prevsynctype = m_synctype; } } -- 2.7.1 From 64f043e2c019506fe9d173c64ce6fde1432283ca Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 22 Feb 2016 16:03:14 +0100 Subject: [PATCH 237/250] introduce IMX DoubleRate Inverted deinterlacing. --- addons/resource.language.en_gb/resources/strings.po | 10 ++++++++-- xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 3 ++- xbmc/cores/VideoRenderers/RenderManager.cpp | 2 ++ xbmc/settings/VideoSettings.h | 1 + xbmc/video/dialogs/GUIDialogVideoSettings.cpp | 1 + 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 71927aa..1a75878 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -8355,10 +8355,16 @@ msgstr "" #. Description of OSD video settings for deinterlace method with label #16335 #: xbmc/video/dialogs/GUIDialogVideoSettings.cpp msgctxt "#16335" -msgid "IMX - Fast motion (double)" +msgid "IMX - Double rate" msgstr "" -#empty strings from id 16336 to 16399 +#. Description of OSD video settings for deinterlace method with label #16336 +#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp +msgctxt "#16336" +msgid "IMX - Double rate (inverted)" +msgstr "" + +#empty strings from id 16337 to 16399 #: xbmc/video/dialogs/GUIDialogVideoSettings.cpp msgctxt "#16400" diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp index f4f4f7d..8aa6ee2 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp @@ -2955,7 +2955,8 @@ bool CLinuxRendererGLES::Supports(EINTERLACEMETHOD method) if(m_renderMethod & RENDER_IMXMAP) { if(method == VS_INTERLACEMETHOD_IMX_FASTMOTION - || method == VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE) + || method == VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE + || method == VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE_INVERTED) return true; else return false; diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp index ce60bc3..28f0a84 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp @@ -712,6 +712,8 @@ void CXBMCRenderManager::FlipPage(volatile bool& bStop, double timestamp /* = 0L else if (interlacemethod == VS_INTERLACEMETHOD_DXVA_BOB) presentmethod = PRESENT_METHOD_BOB; else if (interlacemethod == VS_INTERLACEMETHOD_DXVA_BEST) presentmethod = PRESENT_METHOD_BOB; else if (interlacemethod == VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE) presentmethod = PRESENT_METHOD_BOB; + else if (interlacemethod == VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE_INVERTED) + { presentmethod = PRESENT_METHOD_BOB; invert = true; } else presentmethod = PRESENT_METHOD_SINGLE; if (presentmethod != PRESENT_METHOD_SINGLE) diff --git a/xbmc/settings/VideoSettings.h b/xbmc/settings/VideoSettings.h index 0305058..ac244e7 100644 --- a/xbmc/settings/VideoSettings.h +++ b/xbmc/settings/VideoSettings.h @@ -74,6 +74,7 @@ enum EINTERLACEMETHOD VS_INTERLACEMETHOD_IMX_FASTMOTION = 29, VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE = 30, + VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE_INVERTED = 31, VS_INTERLACEMETHOD_MAX // do not use and keep as last enum value. }; diff --git a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp index b248566..2b4315b 100644 --- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp @@ -274,6 +274,7 @@ void CGUIDialogVideoSettings::InitializeSettings() entries.push_back(std::make_pair(16333, VS_INTERLACEMETHOD_MMAL_BOB_HALF)); entries.push_back(std::make_pair(16334, VS_INTERLACEMETHOD_IMX_FASTMOTION)); entries.push_back(std::make_pair(16335, VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE)); + entries.push_back(std::make_pair(16336, VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE_INVERTED)); /* remove unsupported methods */ for (StaticIntegerSettingOptions::iterator it = entries.begin(); it != entries.end(); ) -- 2.7.1 From d19ca77bd3549dce8e3e0058a34f8f9dfd41fe9e Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 22 Feb 2016 20:45:52 +0100 Subject: [PATCH 238/250] read interlaced mode info from rendermanager --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 9986ae8..4425d1f 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -29,6 +29,8 @@ #include "guilib/GraphicContext.h" #include "cores/VideoRenderers/BaseRenderer.h" #include "cores/VideoRenderers/RenderFlags.h" +#include "cores/VideoRenderers/RenderManager.h" +#include "settings/DisplaySettings.h" #include #include @@ -1414,7 +1416,11 @@ bool CIMXContext::AdaptScreen() m_fbWidth = fbVar.xres; m_fbHeight = fbVar.yres; - m_fbInterlaced = fbVar.vmode & FB_VMODE_INTERLACED; + + if (g_renderManager.IsStarted()) + m_fbInterlaced = g_graphicsContext.GetResInfo(g_renderManager.GetResolution()).dwFlags & D3DPRESENTFLAG_INTERLACED; + else + m_fbInterlaced = g_graphicsContext.GetResInfo(CDisplaySettings::GetInstance().GetCurrentResolution()).dwFlags & D3DPRESENTFLAG_INTERLACED; if (!GetFBInfo(m_deviceName, &m_fbVar)) goto Err; -- 2.7.1 From fd522bb858be441d52f7718b8d9eeac28333d19f Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 24 Feb 2016 13:57:35 +0100 Subject: [PATCH 239/250] essential part of releasing buffer references --- xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp index 8aa6ee2..b08e5e8 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp @@ -661,6 +661,7 @@ void CLinuxRendererGLES::RenderUpdateVideo(bool clear, DWORD flags, DWORD alpha) { uint8_t fieldFmt = flags & RENDER_FLAG_FIELDMASK; CDVDVideoCodecIMXBuffer *previous = NULL; + if (flags & RENDER_FLAG_FIELDS) { fieldFmt |= IPU_DEINTERLACE_RATE_EN; @@ -958,6 +959,11 @@ void CLinuxRendererGLES::LoadShaders(int field) m_textureDelete = &CLinuxRendererGLES::DeleteYV12Texture; } + if (m_format == RENDER_FMT_IMXMAP && m_renderMethod & RENDER_IMXMAP) + { + m_textureDelete = &CLinuxRendererGLES::DeleteIMXMAPTexture; + } + if (m_oldRenderMethod != m_renderMethod) { CLog::Log(LOGDEBUG, "CLinuxRendererGLES: Reorder drawpoints due to method change from %i to %i", m_oldRenderMethod, m_renderMethod); -- 2.7.1 From 9166432327acc20d8121065a759183f11f24155f Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Tue, 23 Feb 2016 00:39:50 +0100 Subject: [PATCH 240/250] wip --- .../resource.language.en_gb/resources/strings.po | 6 + xbmc/Application.cpp | 9 +- xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 5 +- xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 21 +- xbmc/cores/VideoRenderers/RenderManager.cpp | 10 +- .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 1020 ++++++++------------ .../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 222 ++++- xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 9 +- xbmc/cores/dvdplayer/DVDPlayerVideo.h | 3 - xbmc/settings/VideoSettings.h | 1 + xbmc/video/dialogs/GUIDialogVideoSettings.cpp | 1 + 11 files changed, 591 insertions(+), 716 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 1a75878..a9918e2 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -8364,6 +8364,12 @@ msgctxt "#16336" msgid "IMX - Double rate (inverted)" msgstr "" +#. Description of OSD video settings for deinterlace method with label #16337 +#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp +msgctxt "#16337" +msgid "IMX - Low Motion" +msgstr "" + #empty strings from id 16337 to 16399 #: xbmc/video/dialogs/GUIDialogVideoSettings.cpp diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 623f97f..884f6d2 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -235,6 +235,7 @@ #include "pictures/GUIWindowSlideShow.h" #include "windows/GUIWindowLoginScreen.h" #include "utils/Screen.h" +#include "utils/SysfsUtils.h" using namespace ADDON; using namespace XFILE; @@ -4541,8 +4542,14 @@ void CApplication::ShowAppMigrationMessage() void CApplication::ChangeVT(int newVT) { - std::string cmd = StringUtils::Format("sudo /sbin/start xbian-chvt TTYNR=%d", newVT); + std::string cmd; CLog::Log(LOGINFO,"%s : activating tty%d", __FUNCTION__, newVT); + + if (SysfsUtils::Has("/sbin/start")) + cmd = StringUtils::Format("sudo /sbin/start xbian-chvt TTYNR=%d", newVT); + else + cmd = StringUtils::Format("/bin/busybox openvt -c %d -s", newVT); + system(cmd.c_str()); } diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp index 1bc680a..6910b26 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp @@ -918,7 +918,7 @@ unsigned int CAESinkALSA::AddPackets(uint8_t **data, unsigned int frames, unsign int frames_written = 0; int ret = 0; - snd_pcm_nonblock(m_pcm, 0); + snd_pcm_nonblock(m_pcm, 1); while (data_left > 0 && HandleError(__func__, ret)) { if (m_fragmented) @@ -938,6 +938,7 @@ unsigned int CAESinkALSA::AddPackets(uint8_t **data, unsigned int frames, unsign buffer = data[0]+offset*m_format.m_frameSize + frames_written*m_format.m_frameSize; } + snd_pcm_nonblock(m_pcm, 0); return frames_written; } @@ -1012,7 +1013,7 @@ bool CAESinkALSA::TryDevice(const std::string &name, snd_pcm_t **pcmp, snd_confi int err = snd_pcm_open_lconf(pcmp, name.c_str(), SND_PCM_STREAM_PLAYBACK, ALSA_OPTIONS, lconf); if (err < 0) { - CLog::Log(LOGINFO, "CAESinkALSA - Unable to open device \"%s\" for playback", name.c_str()); + CLog::Log(LOGINFO, "CAESinkALSA - Unable to open device \"%s\" for playback (error: %s)", name.c_str(), snd_strerror(err)); } return err == 0; diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp index b08e5e8..18a80c2 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp @@ -657,10 +657,9 @@ void CLinuxRendererGLES::RenderUpdateVideo(bool clear, DWORD flags, DWORD alpha) previous = current; #endif CDVDVideoCodecIMXBuffer *buffer = m_buffers[m_iYV12RenderBuffer].IMXBuffer; - if (buffer != NULL && buffer->IsValid()) + if (buffer) { uint8_t fieldFmt = flags & RENDER_FLAG_FIELDMASK; - CDVDVideoCodecIMXBuffer *previous = NULL; if (flags & RENDER_FLAG_FIELDS) { @@ -672,12 +671,10 @@ void CLinuxRendererGLES::RenderUpdateVideo(bool clear, DWORD flags, DWORD alpha) // this makes IPU render same picture as before, just shifted one line // correct this fieldFmt ^= 0x3; - - previous = buffer; } } - g_IMXContext.BlitAsync(previous, buffer, fieldFmt); + g_IMXContext.Blit(NULL, buffer, fieldFmt); } #if 0 @@ -2962,7 +2959,8 @@ bool CLinuxRendererGLES::Supports(EINTERLACEMETHOD method) { if(method == VS_INTERLACEMETHOD_IMX_FASTMOTION || method == VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE - || method == VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE_INVERTED) + || method == VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE_INVERTED + || method == VS_INTERLACEMETHOD_IMX_MEDMOTION) return true; else return false; @@ -2991,6 +2989,9 @@ bool CLinuxRendererGLES::Supports(ESCALINGMETHOD method) return itr != m_scalingMethods.end(); } + if(method == VS_SCALINGMETHOD_AUTO) + return true; + if(m_renderMethod & RENDER_IMXMAP) return false; @@ -3031,7 +3032,7 @@ EINTERLACEMETHOD CLinuxRendererGLES::AutoInterlaceMethod() return VS_INTERLACEMETHOD_NONE; if(m_renderMethod & RENDER_IMXMAP) - return VS_INTERLACEMETHOD_IMX_FASTMOTION; + return VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE; #if !defined(TARGET_ANDROID) && (defined(__i386__) || defined(__x86_64__)) return VS_INTERLACEMETHOD_DEINTERLACE_HALF; @@ -3137,12 +3138,10 @@ void CLinuxRendererGLES::AddProcessor(CDVDMediaCodecInfo *mediacodec, int index) void CLinuxRendererGLES::AddProcessor(CDVDVideoCodecIMXBuffer *buffer, int index) { YUVBUFFER &buf = m_buffers[index]; - SAFE_RELEASE(buf.IMXBuffer); - buf.IMXBuffer = buffer; - if (buffer) - buffer->Lock(); + buf.IMXBuffer = buffer; + buffer->Lock(); } #endif diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp index 28f0a84..df94aca 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp @@ -61,6 +61,9 @@ #ifdef HAVE_LIBVA #include "../dvdplayer/DVDCodecs/Video/VAAPI.h" #endif +#ifdef HAS_IMXVPU + #include "../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h" +#endif using namespace KODI::MESSAGING; @@ -926,10 +929,15 @@ void CXBMCRenderManager::Recover() void CXBMCRenderManager::UpdateDisplayLatency() { - float refresh = g_graphicsContext.GetFPS(); + float fps = g_graphicsContext.GetFPS(); + float refresh = fps; if (g_graphicsContext.GetVideoResolution() == RES_WINDOW) refresh = 0; // No idea about refresh rate when windowed, just get the default latency m_displayLatency = (double) g_advancedSettings.GetDisplayLatency(refresh); +#ifdef HAS_IMXVPU + int buffers = g_IMXContext.m_fbPages; + m_displayLatency += buffers / fps; +#endif CLog::Log(LOGDEBUG, "CRenderManager::UpdateDisplayLatency - Latency set to %1.0f msec", m_displayLatency * 1000.0f); } diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 4425d1f..92a226e 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -20,6 +20,7 @@ #include "DVDVideoCodecIMX.h" +#include "Application.h" #include "settings/AdvancedSettings.h" #include "threads/SingleLock.h" #include "threads/Atomics.h" @@ -31,6 +32,9 @@ #include "cores/VideoRenderers/RenderFlags.h" #include "cores/VideoRenderers/RenderManager.h" #include "settings/DisplaySettings.h" +#include "settings/MediaSettings.h" +#include "settings/Settings.h" +#include "utils/SysfsUtils.h" #include #include @@ -41,11 +45,13 @@ #include #include #include +#include #define IMX_VDI_MAX_WIDTH 968 #define FRAME_ALIGN 16 #define MEDIAINFO 1 #define RENDER_QUEUE_SIZE 3 +#define IN_DECODER_SET -1 #define _4CC(c1,c2,c3,c4) (((uint32_t)(c4)<<24)|((uint32_t)(c3)<<16)|((uint32_t)(c2)<<8)|(uint32_t)(c1)) #define Align(ptr,align) (((unsigned int)ptr + (align) - 1)/(align)*(align)) #define Align2(ptr,align) (((unsigned int)ptr)/(align)*(align)) @@ -54,14 +60,13 @@ // Global instance CIMXContext g_IMXContext; +std::forward_list m_recycleBuffers; // Number of fb pages used for paning -const int CIMXContext::m_fbPages = 2; +const int CIMXContext::m_fbPages = 3; // Experiments show that we need at least one more (+1) VPU buffer than the min value returned by the VPU -const int CDVDVideoCodecIMX::m_extraVpuBuffers = 1+RENDER_QUEUE_SIZE+2; -const int CDVDVideoCodecIMX::m_maxVpuDecodeLoops = 5; -CCriticalSection CDVDVideoCodecIMX::m_codecBufferLock; +const int CDVDVideoCodecIMX::m_extraVpuBuffers = 1+RENDER_QUEUE_SIZE+CIMXContext::m_fbPages; bool CDVDVideoCodecIMX::VpuAllocBuffers(VpuMemInfo *pMemBlock) { @@ -115,23 +120,17 @@ AllocFailure: return false; } -int CDVDVideoCodecIMX::VpuFindBuffer(void *frameAddr) -{ - for (int i=0; iRelease(); + + if (m_decMemInfo.virtMem && dispose) { //free virtual mem for(int i=0; i=m_decMemInfo.nPhyNum - freePhyNum; i--) { vpuMem.nPhyAddr = m_decMemInfo.phyMem[i].nPhyAddr; vpuMem.nVirtAddr = m_decMemInfo.phyMem[i].nVirtAddr; @@ -158,11 +158,27 @@ bool CDVDVideoCodecIMX::VpuFreeBuffers() { CLog::Log(LOGERROR, "%s - Error while trying to free physical memory (%d).\n", __FUNCTION__, ret); ret = false; + break; } + else + released++; + } + + m_decMemInfo.nPhyNum -= released; + if (!m_decMemInfo.nPhyNum) + { + free(m_decMemInfo.phyMem); + m_decMemInfo.phyMem = NULL; } - free(m_decMemInfo.phyMem); - m_decMemInfo.phyMem = NULL; - m_decMemInfo.nPhyNum = 0; + } + + m_outputBuffers.clear(); + + m_vpuFrameBufferNum = 0; + if (m_vpuFrameBuffers != NULL) + { + delete m_vpuFrameBuffers; + m_vpuFrameBuffers = NULL; } return ret; @@ -174,8 +190,7 @@ bool CDVDVideoCodecIMX::VpuOpen() VpuDecRetCode ret; VpuVersionInfo vpuVersion; VpuMemInfo memInfo; - VpuDecConfig config; - int param; + int param; memset(&memInfo, 0, sizeof(VpuMemInfo)); ret = VPU_DecLoad(); @@ -224,44 +239,11 @@ bool CDVDVideoCodecIMX::VpuOpen() goto VpuOpenError; } - config = VPU_DEC_CONF_SKIPMODE; - param = VPU_DEC_SKIPNONE; - ret = VPU_DecConfig(m_vpuHandle, config, ¶m); - if (ret != VPU_DEC_RET_SUCCESS) - { - CLog::Log(LOGERROR, "%s - iMX VPU set skip mode failed (%d).\n", __FUNCTION__, ret); - goto VpuOpenError; - } + SetSkipMode(VPU_DEC_SKIPNONE); + SetDrainMode(VPU_DEC_IN_NORMAL); - config = VPU_DEC_CONF_BUFDELAY; param = 0; - ret = VPU_DecConfig(m_vpuHandle, config, ¶m); - if (ret != VPU_DEC_RET_SUCCESS) - { - CLog::Log(LOGERROR, "%s - iMX VPU set buffer delay failed (%d).\n", __FUNCTION__, ret); - goto VpuOpenError; - } - - config = VPU_DEC_CONF_INPUTTYPE; - param = VPU_DEC_IN_NORMAL; - ret = VPU_DecConfig(m_vpuHandle, config, ¶m); - if (ret != VPU_DEC_RET_SUCCESS) - { - CLog::Log(LOGERROR, "%s - iMX VPU configure input type failed (%d).\n", __FUNCTION__, ret); - goto VpuOpenError; - } - - // Note that libvpufsl (file vpu_wrapper.c) associates VPU_DEC_CAP_FRAMESIZE - // capability to the value of nDecFrameRptEnabled which is in fact directly - // related to the ability to generate VPU_DEC_ONE_FRM_CONSUMED even if the - // naming is misleading... - ret = VPU_DecGetCapability(m_vpuHandle, VPU_DEC_CAP_FRAMESIZE, ¶m); - m_frameReported = (param != 0); - if (ret != VPU_DEC_RET_SUCCESS) - { - CLog::Log(LOGERROR, "%s - iMX VPU get framesize capability failed (%d).\n", __FUNCTION__, ret); - m_frameReported = false; - } + SetVPUParams(VPU_DEC_CONF_BUFDELAY, ¶m); return true; @@ -335,8 +317,6 @@ bool CDVDVideoCodecIMX::VpuAllocFrameBuffers() mvSize = Align(mvSize, nAlign); } - m_outputBuffers = new CDVDVideoCodecIMXBuffer*[m_vpuFrameBufferNum]; - for (int i=0 ; i < m_vpuFrameBufferNum; i++) { totalSize = ySize + uSize + vSize + mvSize + nAlign; @@ -398,12 +378,10 @@ bool CDVDVideoCodecIMX::VpuAllocFrameBuffers() m_vpuFrameBuffers[i].pbufVirtCb_tilebot = 0; #ifdef TRACE_FRAMES - m_outputBuffers[i] = new CDVDVideoCodecIMXBuffer(i); + m_outputBuffers[m_vpuFrameBuffers[i].pbufY] = new CDVDVideoCodecIMXBuffer(i); #else - m_outputBuffers[i] = new CDVDVideoCodecIMXBuffer; + m_outputBuffers[m_vpuFrameBuffers[i].pbufY] = new CDVDVideoCodecIMXBuffer(); #endif - // Those buffers are ours so lock them to prevent destruction - m_outputBuffers[i]->Lock(); } return true; @@ -414,27 +392,22 @@ CDVDVideoCodecIMX::CDVDVideoCodecIMX() m_pFormatName = "iMX-xxx"; m_vpuHandle = 0; m_vpuFrameBuffers = NULL; - m_outputBuffers = NULL; - m_lastBuffer = NULL; m_currentBuffer = NULL; m_extraMem = NULL; m_vpuFrameBufferNum = 0; - m_dropRequest = false; - m_dropState = false; - m_convert_bitstream = false; - m_frameCounter = 0; m_usePTS = true; if (getenv("IMX_NOPTS") != NULL) { m_usePTS = false; } m_converter = NULL; - m_convert_bitstream = false; - m_bytesToBeConsumed = 0; - m_previousPts = DVD_NOPTS_VALUE; #ifdef DUMP_STREAM m_dump = NULL; #endif + memset(&m_frameInfo, 0, sizeof(m_frameInfo)); + m_drainMode = (VpuDecInputType)-2; + m_dropRequest = (VpuDecSkipMode)-2; + m_codecControlFlags = 0; } CDVDVideoCodecIMX::~CDVDVideoCodecIMX() @@ -473,24 +446,22 @@ bool CDVDVideoCodecIMX::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) #endif m_hints = hints; - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "Let's decode with iMX VPU\n"); + CLog::Log(LOGDEBUG | LOGVIDEO, "Let's decode with iMX VPU\n"); #ifdef MEDIAINFO - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) { - CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: fpsrate %d / fpsscale %d\n", m_hints.fpsrate, m_hints.fpsscale); - CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: CodecID %d \n", m_hints.codec); - CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: StreamType %d \n", m_hints.type); - CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: Level %d \n", m_hints.level); - CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: Profile %d \n", m_hints.profile); - CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: PTS_invalid %d \n", m_hints.ptsinvalid); - CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: Tag %d \n", m_hints.codec_tag); - CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: %dx%d \n", m_hints.width, m_hints.height); + CLog::Log(LOGDEBUG | LOGVIDEO, "Decode: MEDIAINFO: fpsrate %d / fpsscale %d\n", m_hints.fpsrate, m_hints.fpsscale); + CLog::Log(LOGDEBUG | LOGVIDEO, "Decode: MEDIAINFO: CodecID %d \n", m_hints.codec); + CLog::Log(LOGDEBUG | LOGVIDEO, "Decode: MEDIAINFO: StreamType %d \n", m_hints.type); + CLog::Log(LOGDEBUG | LOGVIDEO, "Decode: MEDIAINFO: Level %d \n", m_hints.level); + CLog::Log(LOGDEBUG | LOGVIDEO, "Decode: MEDIAINFO: Profile %d \n", m_hints.profile); + CLog::Log(LOGDEBUG | LOGVIDEO, "Decode: MEDIAINFO: PTS_invalid %d \n", m_hints.ptsinvalid); + CLog::Log(LOGDEBUG | LOGVIDEO, "Decode: MEDIAINFO: Tag %d \n", m_hints.codec_tag); + CLog::Log(LOGDEBUG | LOGVIDEO, "Decode: MEDIAINFO: %dx%d \n", m_hints.width, m_hints.height); } { uint8_t *pb = (uint8_t*)&m_hints.codec_tag; - if ((isalnum(pb[0]) && isalnum(pb[1]) && isalnum(pb[2]) && isalnum(pb[3])) && g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: Tag fourcc %c%c%c%c\n", pb[0], pb[1], pb[2], pb[3]); + if ((isalnum(pb[0]) && isalnum(pb[1]) && isalnum(pb[2]) && isalnum(pb[3]))) + CLog::Log(LOGDEBUG | LOGVIDEO, "Decode: MEDIAINFO: Tag fourcc %c%c%c%c\n", pb[0], pb[1], pb[2], pb[3]); } if (m_hints.extrasize) { @@ -499,14 +470,10 @@ bool CDVDVideoCodecIMX::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) for (unsigned int i=0; i < m_hints.extrasize; i++) sprintf(buf+i*2, "%02x", ((uint8_t*)m_hints.extradata)[i]); - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: extradata %d %s\n", m_hints.extrasize, buf); - } - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - { - CLog::Log(LOGDEBUG, "Decode: MEDIAINFO: %d / %d \n", m_hints.width, m_hints.height); - CLog::Log(LOGDEBUG, "Decode: aspect %f - forced aspect %d\n", m_hints.aspect, m_hints.forced_aspect); + CLog::Log(LOGDEBUG | LOGVIDEO, "Decode: MEDIAINFO: extradata %d %s\n", m_hints.extrasize, buf); } + CLog::Log(LOGDEBUG | LOGVIDEO, "Decode: MEDIAINFO: %d / %d \n", m_hints.width, m_hints.height); + CLog::Log(LOGDEBUG | LOGVIDEO, "Decode: aspect %f - forced aspect %d\n", m_hints.aspect, m_hints.forced_aspect); #endif m_warnOnce = true; @@ -542,7 +509,11 @@ bool CDVDVideoCodecIMX::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) if ( *(char*)hints.extradata == 1 ) { m_converter = new CBitstreamConverter(); - m_convert_bitstream = m_converter->Open(hints.codec, (uint8_t *)hints.extradata, hints.extrasize, true); + m_convert_bitstream = m_converter->Open(hints.codec, (uint8_t *)m_hints.extradata, m_hints.extrasize, true); + free(m_hints.extradata); + m_hints.extrasize = m_converter->GetExtraSize(); + m_hints.extradata = malloc(m_hints.extrasize); + memcpy(m_hints.extradata, m_converter->GetExtraData(), m_hints.extrasize); } } break; @@ -624,28 +595,10 @@ void CDVDVideoCodecIMX::Dispose() VpuDecRetCode ret; bool VPU_loaded = m_vpuHandle; - // Release last buffer - SAFE_RELEASE(m_lastBuffer); - SAFE_RELEASE(m_currentBuffer); - - Enter(); - - // Invalidate output buffers to prevent the renderer from mapping this memory - for (int i=0; iReleaseFramebuffer(&m_vpuHandle); - SAFE_RELEASE(m_outputBuffers[i]); - } - - Leave(); + reset(true); if (m_vpuHandle) { - ret = VPU_DecFlushAll(m_vpuHandle); - if (ret != VPU_DEC_RET_SUCCESS) - { - CLog::Log(LOGERROR, "%s - VPU flush failed with error code %d.\n", __FUNCTION__, ret); - } ret = VPU_DecClose(m_vpuHandle); if (ret != VPU_DEC_RET_SUCCESS) { @@ -654,23 +607,7 @@ void CDVDVideoCodecIMX::Dispose() m_vpuHandle = 0; } - m_frameCounter = 0; - - // Release memory - if (m_outputBuffers != NULL) - { - delete m_outputBuffers; - m_outputBuffers = NULL; - } - VpuFreeBuffers(); - m_vpuFrameBufferNum = 0; - - if (m_vpuFrameBuffers != NULL) - { - delete m_vpuFrameBuffers; - m_vpuFrameBuffers = NULL; - } if (VPU_loaded) { @@ -686,16 +623,72 @@ void CDVDVideoCodecIMX::Dispose() m_converter->Close(); SAFE_DELETE(m_converter); } +} - return; +inline +void CDVDVideoCodecIMX::SetVPUParams(VpuDecConfig InDecConf, void* pInParam) +{ + if (VPU_DEC_RET_SUCCESS != VPU_DecConfig(m_vpuHandle, InDecConf, pInParam)) + CLog::Log(LOGERROR, "%s - iMX VPU set dec param failed.\n", __FUNCTION__); +} + +void CDVDVideoCodecIMX::SetDrainMode(VpuDecInputType drain) +{ + if (!m_vpuHandle || m_drainMode == drain) + return; + + m_drainMode = drain; + VpuDecInputType config = drain == IN_DECODER_SET ? VPU_DEC_IN_DRAIN : drain; + SetVPUParams(VPU_DEC_CONF_INPUTTYPE, &config); + CLog::Log(LOGDEBUG | LOGVIDEO, ">>>>>>>>>>>>>>>>>>>>> %s - iMX VPU set drain mode %d.\n", __FUNCTION__, config); } inline -void CDVDVideoCodecIMX::SetSkipMode() +void CDVDVideoCodecIMX::SetSkipMode(VpuDecSkipMode skip) { - VpuDecSkipMode skip = m_dropRequest ? VPU_DEC_SKIPB : VPU_DEC_SKIPNONE; - if (VPU_DEC_RET_SUCCESS != VPU_DecConfig(m_vpuHandle, VPU_DEC_CONF_SKIPMODE, &skip)) - CLog::Log(LOGERROR, "%s - iMX VPU set skip mode failed.\n", __FUNCTION__); + if (!m_vpuHandle || m_dropRequest == skip) + return; + + m_dropRequest = skip; + VpuDecSkipMode config = skip == IN_DECODER_SET ? VPU_DEC_SKIPB : skip; + SetVPUParams(VPU_DEC_CONF_SKIPMODE, &config); + CLog::Log(LOGDEBUG | LOGVIDEO, ">>>>>>>>>>>>>>>>>>>>> %s - iMX VPU set skip mode %d.\n", __FUNCTION__, config); +} + +inline +void CDVDVideoCodecIMX::SetCodecParam(VpuBufferNode *bn, unsigned char *data, unsigned int size) +{ + switch (m_drainMode) + { + case VPU_DEC_IN_NORMAL: bn->sCodecData.pData = data; bn->sCodecData.nSize = size; break; + default: bn->sCodecData.pData = NULL; bn->sCodecData.nSize = 0; + bn->pVirAddr = NULL; bn->nSize = 0; + } +} + +bool CDVDVideoCodecIMX::GetCodecStats(double &pts, int &droppedPics) +{ + droppedPics = m_dropped; + m_dropped = 0; + pts = DVD_NOPTS_VALUE; + return true; +} + +void CDVDVideoCodecIMX::SetCodecControl(int flags) +{ + m_codecControlFlags = flags; +#ifdef DVD_CODEC_CTRL_DROP + if (m_drainMode != IN_DECODER_SET) + SetDrainMode(flags & DVD_CODEC_CTRL_DRAIN && m_vpuFrameBufferNum ? VPU_DEC_IN_DRAIN : VPU_DEC_IN_NORMAL); +#endif +} + +bool CDVDVideoCodecIMX::getOutputFrame(VpuDecOutFrameInfo *frm) +{ + VpuDecRetCode ret = VPU_DecGetOutputFrame(m_vpuHandle, frm); + if(VPU_DEC_RET_SUCCESS != ret) + CLog::Log(LOGERROR, "%s - VPU Cannot get output frame(%d).\n", __FUNCTION__, ret); + return ret == VPU_DEC_RET_SUCCESS; } int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) @@ -703,12 +696,10 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) VpuDecFrameLengthInfo frameLengthInfo; VpuBufferNode inData; VpuDecRetCode ret; - int decRet = 0; + static int decRet; int retStatus = 0; int demuxer_bytes = iSize; uint8_t *demuxer_content = pData; - int retries = 0; - int idx; #ifdef IMX_PROFILE static unsigned long long previous, current; @@ -730,8 +721,6 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) } #endif - SAFE_RELEASE(m_currentBuffer); - if (!m_vpuHandle) { VpuOpen(); @@ -739,26 +728,19 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) return VC_ERROR; } - for (int i=0; i < m_vpuFrameBufferNum; i++) + while(!m_recycleBuffers.empty()) { - if (m_outputBuffers[i]->Rendered()) - { - ret = m_outputBuffers[i]->ReleaseFramebuffer(&m_vpuHandle); - if(ret != VPU_DEC_RET_SUCCESS) - { - CLog::Log(LOGERROR, "%s: vpu clear frame display failure: ret=%d \r\n",__FUNCTION__,ret); - } - } + m_recycleBuffers.front()->ReleaseFramebuffer(&m_vpuHandle); + m_recycleBuffers.pop_front(); } #ifdef IMX_PROFILE current = XbmcThreads::SystemClockMillis(); - CLog::Log(LOGDEBUG, "%s - delta time decode : %llu - demux size : %d dts : %f - pts : %f\n", __FUNCTION__, current - previous, iSize, dts, pts); + CLog::Log(LOGDEBUG | LOGVIDEO, "%s - delta time decode : %llu - demux size : %d dts : %f - pts : %f - addr : 0x%x\n", + __FUNCTION__, current - previous, iSize, recalcPts(dts), recalcPts(pts), (uint)pData); previous = current; #endif - if ((pData && iSize) || - (m_bytesToBeConsumed)) { //printf("D %f %d\n", pts, iSize); if ((m_convert_bitstream) && (iSize)) @@ -770,7 +752,11 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) demuxer_bytes = m_converter->GetConvertSize(); } else + { CLog::Log(LOGERROR,"%s - bitstream_convert error", __FUNCTION__); + if (!m_vpuFrameBufferNum) + m_convert_bitstream = false; + } } inData.nSize = demuxer_bytes; @@ -778,16 +764,11 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) inData.pVirAddr = demuxer_content; if ((m_decOpenParam.CodecFormat == VPU_V_MPEG2) || (m_decOpenParam.CodecFormat == VPU_V_VC1_AP)|| - (m_decOpenParam.CodecFormat == VPU_V_XVID)) - { - inData.sCodecData.pData = (unsigned char *)m_hints.extradata; - inData.sCodecData.nSize = m_hints.extrasize; - } + (m_decOpenParam.CodecFormat == VPU_V_XVID) || + (m_convert_bitstream && iSize && !m_vpuFrameBufferNum && decRet & (VPU_DEC_NO_ENOUGH_INBUF | VPU_DEC_OUTPUT_NODIS))) + SetCodecParam(&inData, (unsigned char *)m_hints.extradata, m_hints.extrasize); else - { - inData.sCodecData.pData = NULL; - inData.sCodecData.nSize = 0; - } + SetCodecParam(&inData, NULL, 0); #ifdef IMX_PROFILE_BUFFERS static unsigned long long dec_time = 0; @@ -798,137 +779,91 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) #if defined(IMX_PROFILE) || defined(IMX_PROFILE_BUFFERS) before_dec = XbmcThreads::SystemClockMillis(); #endif - if (m_frameReported) - m_bytesToBeConsumed += inData.nSize; - - SetSkipMode(); - ret = VPU_DecDecodeBuf(m_vpuHandle, &inData, &decRet); #ifdef IMX_PROFILE_BUFFERS unsigned long long dec_single_call = XbmcThreads::SystemClockMillis()-before_dec; dec_time += dec_single_call; #endif #ifdef IMX_PROFILE - CLog::Log(LOGDEBUG, "%s - VPU dec 0x%x decode takes : %lld\n\n", __FUNCTION__, decRet, XbmcThreads::SystemClockMillis() - before_dec); + CLog::Log(LOGDEBUG | LOGVIDEO, "%s - VPU ret %d dec 0x%x decode takes : %lld\n\n", __FUNCTION__, ret, decRet, XbmcThreads::SystemClockMillis() - before_dec); #endif - if (ret == VPU_DEC_RET_WRONG_CALL_SEQUENCE && - decRet & VPU_DEC_RESOLUTION_CHANGED) - { - VpuFreeBuffers(); - } - else if (decRet & VPU_DEC_NO_ENOUGH_INBUF) - { - break; - } - else if (ret != VPU_DEC_RET_SUCCESS) + if (ret != VPU_DEC_RET_SUCCESS && ret != VPU_DEC_RET_FAILURE_TIMEOUT) { CLog::Log(LOGERROR, "%s - VPU decode failed with error code %d (0x%x).\n", __FUNCTION__, ret, decRet); - goto out_error; + retStatus = VC_ERROR; + break; } if (decRet & VPU_DEC_INIT_OK || decRet & VPU_DEC_RESOLUTION_CHANGED) // VPU decoding init OK : We can retrieve stream info { ret = VPU_DecGetInitialInfo(m_vpuHandle, &m_initInfo); - if (ret == VPU_DEC_RET_SUCCESS) + if (ret != VPU_DEC_RET_SUCCESS) { - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - { - CLog::Log(LOGDEBUG, "%s - VPU Init Stream Info : %dx%d (interlaced : %d - Minframe : %d)"\ - " - Align : %d bytes - crop : %d %d %d %d - Q16Ratio : %x\n", __FUNCTION__, - m_initInfo.nPicWidth, m_initInfo.nPicHeight, m_initInfo.nInterlace, m_initInfo.nMinFrameBufferCount, - m_initInfo.nAddressAlignment, m_initInfo.PicCropRect.nLeft, m_initInfo.PicCropRect.nTop, - m_initInfo.PicCropRect.nRight, m_initInfo.PicCropRect.nBottom, m_initInfo.nQ16ShiftWidthDivHeightRatio); - } - if (VpuAllocFrameBuffers()) - { - ret = VPU_DecRegisterFrameBuffer(m_vpuHandle, m_vpuFrameBuffers, m_vpuFrameBufferNum); - if (ret != VPU_DEC_RET_SUCCESS) - { - CLog::Log(LOGERROR, "%s - VPU error while registering frame buffers (%d).\n", __FUNCTION__, ret); - goto out_error; - } - } - else - { - goto out_error; - } - + CLog::Log(LOGERROR, "%s - VPU get initial info failed (%d).\n", __FUNCTION__, ret); + break; } - else + + CLog::Log(LOGDEBUG, "%s - VPU Init Stream Info : %dx%d (interlaced : %d - Minframe : %d)"\ + " - Align : %d bytes - crop : %d %d %d %d - Q16Ratio : %x\n", __FUNCTION__, + m_initInfo.nPicWidth, m_initInfo.nPicHeight, m_initInfo.nInterlace, m_initInfo.nMinFrameBufferCount, + m_initInfo.nAddressAlignment, m_initInfo.PicCropRect.nLeft, m_initInfo.PicCropRect.nTop, + m_initInfo.PicCropRect.nRight, m_initInfo.PicCropRect.nBottom, m_initInfo.nQ16ShiftWidthDivHeightRatio); + + reset(false); + + if (!VpuFreeBuffers(false) || + (!VpuAllocFrameBuffers()) || + (VPU_DEC_RET_SUCCESS != VPU_DecRegisterFrameBuffer(m_vpuHandle, m_vpuFrameBuffers, m_vpuFrameBufferNum))) { - CLog::Log(LOGERROR, "%s - VPU get initial info failed (%d).\n", __FUNCTION__, ret); - goto out_error; + CLog::Log(LOGERROR, "%s - VPU error while registering frame buffers (%d).\n", __FUNCTION__, ret); + return VC_REOPEN; } + + SetDrainMode((VpuDecInputType)IN_DECODER_SET); + return VC_USERDATA; } //VPU_DEC_INIT_OK - if (decRet & VPU_DEC_ONE_FRM_CONSUMED && !(decRet & VPU_DEC_OUTPUT_DROPPED)) + if (decRet & VPU_DEC_ONE_FRM_CONSUMED) { ret = VPU_DecGetConsumedFrameInfo(m_vpuHandle, &frameLengthInfo); if (ret != VPU_DEC_RET_SUCCESS) - { CLog::Log(LOGERROR, "%s - VPU error retireving info about consummed frame (%d).\n", __FUNCTION__, ret); - } - m_bytesToBeConsumed -= (frameLengthInfo.nFrameLength + frameLengthInfo.nStuffLength); - if (frameLengthInfo.pFrame) - { - idx = VpuFindBuffer(frameLengthInfo.pFrame->pbufY); - if (m_bytesToBeConsumed < 50) - m_bytesToBeConsumed = 0; - if (idx != -1) - { - if (m_previousPts != DVD_NOPTS_VALUE) - { - m_outputBuffers[idx]->SetPts(m_previousPts); - m_previousPts = DVD_NOPTS_VALUE; - } - else - m_outputBuffers[idx]->SetPts(pts); - } - else - CLog::Log(LOGERROR, "%s - could not find frame buffer\n", __FUNCTION__); - } + + if (frameLengthInfo.pFrame && !(decRet & VPU_DEC_OUTPUT_DROPPED)) + m_outputBuffers[frameLengthInfo.pFrame->pbufY]->SetPts(pts); + if (m_dropRequest > 0) + SetSkipMode(VPU_DEC_SKIPNONE); } //VPU_DEC_ONE_FRM_CONSUMED - if (decRet & VPU_DEC_OUTPUT_DIS) + // VPU_DEC_OUTPUT_MOSAIC_DIS - According to libfslvpuwrap: If this flag + // is set then the frame should be dropped. It is just returned to gather + // decoder information but not for display + if (decRet & (VPU_DEC_OUTPUT_DIS | VPU_DEC_OUTPUT_MOSAIC_DIS) && getOutputFrame(&m_frameInfo)) // Frame ready to be displayed { - if (retStatus & VC_PICTURE) - CLog::Log(LOGERROR, "%s - Second picture in the same decode call !\n", __FUNCTION__); - - ret = VPU_DecGetOutputFrame(m_vpuHandle, &m_frameInfo); - if(ret != VPU_DEC_RET_SUCCESS) - { - CLog::Log(LOGERROR, "%s - VPU Cannot get output frame(%d).\n", __FUNCTION__, ret); - goto out_error; - } - // Some codecs (VC1?) lie about their frame size (mod 16). Adjust... m_frameInfo.pExtInfo->nFrmWidth = (((m_frameInfo.pExtInfo->nFrmWidth) + 15) & ~15); m_frameInfo.pExtInfo->nFrmHeight = (((m_frameInfo.pExtInfo->nFrmHeight) + 15) & ~15); - idx = VpuFindBuffer(m_frameInfo.pDisplayFrameBuf->pbufY); - if (idx != -1) + CDVDVideoCodecIMXBuffer *buffer = m_outputBuffers[m_frameInfo.pDisplayFrameBuf->pbufY]; { - CDVDVideoCodecIMXBuffer *buffer = m_outputBuffers[idx]; - /* quick & dirty fix to get proper timestamping for VP8 codec */ if (m_decOpenParam.CodecFormat == VPU_V_VP8) buffer->SetPts(pts); buffer->Lock(); buffer->SetDts(dts); - buffer->Queue(&m_frameInfo, m_lastBuffer); + buffer->Queue(&m_frameInfo); #ifdef IMX_PROFILE_BUFFERS - CLog::Log(LOGNOTICE, "+D %f %lld\n", buffer->GetPts(), dec_time); + CLog::Log(LOGDEBUG | LOGVIDEO, "+D %f %lld\n", recalcPts(buffer->GetPts()), dec_time); dec_time = 0; #endif #ifdef TRACE_FRAMES - CLog::Log(LOGDEBUG, "+ %02d dts %f pts %f (VPU)\n", idx, dts, pts); - CLog::Log(LOGDEBUG, "+ %02d dts %f pts %f (VPU)\n", idx, buffer->GetDts(), buffer->GetPts()); + CLog::Log(LOGDEBUG | LOGVIDEO, "+ %02d dts %f pts %f (VPU)\n", buffer->m_idx, recalcPts(buffer->GetDts()), recalcPts(buffer->GetPts())); #endif if (!m_usePTS) @@ -937,153 +872,86 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts) buffer->SetDts(DVD_NOPTS_VALUE); } - // Save last buffer - SAFE_RELEASE(m_lastBuffer); - m_lastBuffer = buffer; - m_lastBuffer->Lock(); - #ifdef IMX_PROFILE_BUFFERS static unsigned long long lastD = 0; unsigned long long current = XbmcThreads::SystemClockMillis(), tmp; - CLog::Log(LOGNOTICE, "+V %f %lld\n", buffer->GetPts(), current-lastD); + CLog::Log(LOGDEBUG | LOGVIDEO, "+V %f %lld\n", recalcPts(buffer->GetPts()), current-lastD); lastD = current; #endif + if (decRet & VPU_DEC_OUTPUT_DIS) + buffer->iFlags = DVP_FLAG_ALLOCATED; m_currentBuffer = buffer; - - if (m_currentBuffer) - { - retStatus |= VC_PICTURE; - } + retStatus |= VC_PICTURE; } } //VPU_DEC_OUTPUT_DIS - - // According to libfslvpuwrap: If this flag is set then the frame should - // be dropped. It is just returned to gather decoder information but not - // for display. - else if (decRet & VPU_DEC_OUTPUT_MOSAIC_DIS) + else if (decRet & (VPU_DEC_OUTPUT_REPEAT | + VPU_DEC_OUTPUT_DROPPED | + VPU_DEC_SKIP)) { - ret = VPU_DecGetOutputFrame(m_vpuHandle, &m_frameInfo); - if(ret != VPU_DEC_RET_SUCCESS) - { - CLog::Log(LOGERROR, "%s - VPU Cannot get output frame(%d).\n", __FUNCTION__, ret); - goto out_error; - } - - // Display frame - ret = VPU_DecOutFrameDisplayed(m_vpuHandle, m_frameInfo.pDisplayFrameBuf); - if(ret != VPU_DEC_RET_SUCCESS) - { - CLog::Log(LOGERROR, "%s: VPU Clear frame display failure(%d)\n",__FUNCTION__,ret); - goto out_error; - } - } //VPU_DEC_OUTPUT_MOSAIC_DIS - - else if (decRet & VPU_DEC_OUTPUT_REPEAT) - { - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "%s - Frame repeat.\n", __FUNCTION__); - m_dropState = true; - retStatus |= VC_DROPPED; - } - else if (decRet & VPU_DEC_OUTPUT_DROPPED) - { - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "%s - Frame dropped.\n", __FUNCTION__); - m_dropState = true; - retStatus |= VC_DROPPED; - } - else if (decRet & VPU_DEC_NO_ENOUGH_BUF) - { - CLog::Log(LOGERROR, "%s - No frame buffer available.\n", __FUNCTION__); - } - else if (decRet & VPU_DEC_SKIP) - { - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "%s - Frame skipped.\n", __FUNCTION__); - } - else if (decRet & VPU_DEC_FLUSH) - { - CLog::Log(LOGNOTICE, "%s - VPU requires a flush.\n", __FUNCTION__); - Reset(); - retStatus = VC_FLUSHED; - } - else if (decRet & VPU_DEC_OUTPUT_EOS) - { - CLog::Log(LOGNOTICE, "%s - EOS encountered.\n", __FUNCTION__); - } - if (decRet & (VPU_DEC_OUTPUT_DROPPED| VPU_DEC_OUTPUT_NODIS | - VPU_DEC_OUTPUT_REPEAT | VPU_DEC_OUTPUT_DIS)) - { - // We are done with VPU decoder that time - break; +#ifdef TRACE_FRAMES + CLog::Log(LOGDEBUG | LOGVIDEO, "%s - Frame drop/repeat/skip (0x%x).\n", __FUNCTION__, decRet); +#endif + m_dropped++; + if (decRet & VPU_DEC_SKIP) + m_dropped++; + retStatus |= VC_USERDATA; } - retries++; - if (retries >= m_maxVpuDecodeLoops) + if (decRet & VPU_DEC_NO_ENOUGH_INBUF) { - CLog::Log(LOGERROR, "%s - Leaving VPU decoding loop after %d iterations\n", __FUNCTION__, m_maxVpuDecodeLoops); + if (iSize) + SetSkipMode(VPU_DEC_SKIPNONE); break; } - if (!(decRet & VPU_DEC_INPUT_USED)) + if (decRet & VPU_DEC_FLUSH) + retStatus |= VC_FLUSHED; + + if (decRet & VPU_DEC_NO_ENOUGH_BUF) { - CLog::Log(LOGERROR, "%s - input not used : addr %p size :%d!\n", __FUNCTION__, inData.pVirAddr, inData.nSize); + retStatus |= VC_USERDATA; + Sleep(5); } - // Let's process again as VPU_DEC_NO_ENOUGH_INBUF was not set - // and we don't have an image ready if we reach that point - inData.pVirAddr = NULL; - inData.nSize = 0; + break; } // Decode loop } //(pData && iSize) - if (!retStatus) + if (!(retStatus & VC_USERDATA) && m_drainMode != VPU_DEC_IN_DRAIN) retStatus |= VC_BUFFER; - if (m_bytesToBeConsumed > 0) - { - // Remember the current pts because the data which has just - // been sent to the VPU has not yet been consumed. - // This pts is related to the frame that will be consumed - // at next call... - m_previousPts = pts; - } - + if (m_drainMode == IN_DECODER_SET) + SetDrainMode(VPU_DEC_IN_NORMAL); #ifdef IMX_PROFILE - CLog::Log(LOGDEBUG, "%s - returns %x - duration %lld\n", __FUNCTION__, retStatus, XbmcThreads::SystemClockMillis() - previous); + CLog::Log(LOGDEBUG | LOGVIDEO, "%s - returns %x - duration %lld extinf %d\n", __FUNCTION__, retStatus, XbmcThreads::SystemClockMillis() - previous, (int)m_frameInfo.pExtInfo); #endif return retStatus; - -out_error: - return VC_ERROR; } -void CDVDVideoCodecIMX::Reset() +void CDVDVideoCodecIMX::reset(bool dispose) { - int ret; - - if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG, "%s - called\n", __FUNCTION__); + if (m_vpuFrameBufferNum && dispose) + SetSkipMode(VPU_DEC_ISEARCH); - // Release last buffer - SAFE_RELEASE(m_lastBuffer); - SAFE_RELEASE(m_currentBuffer); + if (dispose) + CLog::Log(LOGDEBUG | LOGVIDEO, "%s - called\n", __FUNCTION__); // Invalidate all buffers - for(int i=0; i < m_vpuFrameBufferNum; i++) - m_outputBuffers[i]->ReleaseFramebuffer(&m_vpuHandle); + for(auto buf : m_outputBuffers) + buf.second->ReleaseFramebuffer(&m_vpuHandle); + m_recycleBuffers.clear(); - m_frameCounter = 0; - m_bytesToBeConsumed = 0; - m_previousPts = DVD_NOPTS_VALUE; + if (!dispose) + return; + + if (!m_vpuHandle || !m_vpuFrameBufferNum) + return; // Flush VPU - ret = VPU_DecFlushAll(m_vpuHandle); + int ret = VPU_DecFlushAll(m_vpuHandle); if (ret != VPU_DEC_RET_SUCCESS) - { CLog::Log(LOGERROR, "%s - VPU flush failed with error code %d.\n", __FUNCTION__, ret); - } } unsigned CDVDVideoCodecIMX::GetAllowedReferences() @@ -1094,9 +962,7 @@ unsigned CDVDVideoCodecIMX::GetAllowedReferences() bool CDVDVideoCodecIMX::ClearPicture(DVDVideoPicture* pDvdVideoPicture) { if (pDvdVideoPicture) - { SAFE_RELEASE(pDvdVideoPicture->IMXBuffer); - } return true; } @@ -1108,27 +974,15 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) unsigned int current; current = XbmcThreads::SystemClockMillis(); - CLog::Log(LOGDEBUG, "%s tm:%03d\n", __FUNCTION__, current - previous); + CLog::Log(LOGDEBUG | LOGVIDEO, "%s tm:%03d : Interlaced %d\n", __FUNCTION__, current - previous, m_initInfo.nInterlace); previous = current; #endif - if (m_dropState) - { - pDvdVideoPicture->iFlags = DVP_FLAG_DROPPED; - m_dropState = false; - } - - if (m_frameCounter++ && pDvdVideoPicture->iFlags == DVP_FLAG_DROPPED) - { - SAFE_RELEASE(m_currentBuffer); - return true; - } - - pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED; + pDvdVideoPicture->iFlags = m_currentBuffer->iFlags; if (m_initInfo.nInterlace) { - if (m_currentBuffer->GetFieldType() == VPU_FIELD_NONE && m_warnOnce) + if (m_currentBuffer->GetFieldType() == VPU_FIELD_NONE && m_warnOnce && m_currentBuffer->iFlags & DVP_FLAG_ALLOCATED) { m_warnOnce = false; CLog::Log(LOGWARNING, "Interlaced content reported by VPU, but full frames detected - Please turn off deinterlacing manually."); @@ -1150,36 +1004,26 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture) pDvdVideoPicture->pts = m_currentBuffer->GetPts(); pDvdVideoPicture->dts = m_currentBuffer->GetDts(); - pDvdVideoPicture->IMXBuffer = m_currentBuffer; - m_currentBuffer = NULL; +#ifdef DVD_CODEC_CTRL_DROP + if (m_codecControlFlags & DVD_CODEC_CTRL_DROP) + m_currentBuffer->Release(); + else +#endif + if (m_currentBuffer->iFlags & DVP_FLAG_ALLOCATED) + pDvdVideoPicture->IMXBuffer = m_currentBuffer; + else if (m_currentBuffer->iFlags & DVP_FLAG_DROPPED) + SAFE_RELEASE(m_currentBuffer); return true; } void CDVDVideoCodecIMX::SetDropState(bool bDrop) { - // We are fast enough to continue to really decode every frames // and avoid artefacts... // (Of course these frames won't be rendered but only decoded) - - if (m_dropRequest != bDrop) - { - m_dropRequest = bDrop && !!m_frameCounter; -#ifdef TRACE_FRAMES - CLog::Log(LOGDEBUG, "%s : %d\n", __FUNCTION__, bDrop); -#endif - } -} - -void CDVDVideoCodecIMX::Enter() -{ - m_codecBufferLock.lock(); -} - -void CDVDVideoCodecIMX::Leave() -{ - m_codecBufferLock.unlock(); + if (m_dropRequest < 1 && m_vpuFrameBufferNum && m_speed != DVD_PLAYSPEED_PAUSE) + SetSkipMode((VpuDecSkipMode)(-1*bDrop)); } /*******************************************/ @@ -1193,27 +1037,18 @@ CDVDVideoCodecIMXBuffer::CDVDVideoCodecIMXBuffer() #endif m_pts(DVD_NOPTS_VALUE) , m_dts(DVD_NOPTS_VALUE) + , m_fieldType(VPU_FIELD_NONE) , m_frameBuffer(NULL) - , m_rendered(false) - , m_previousBuffer(NULL) -{ -} - -void CDVDVideoCodecIMXBuffer::SetPts(double pts) -{ - m_pts = pts; -} - -void CDVDVideoCodecIMXBuffer::SetDts(double dts) + , iFlags(DVP_FLAG_DROPPED) { - m_dts = dts; + Lock(); } void CDVDVideoCodecIMXBuffer::Lock() { #ifdef TRACE_FRAMES long count = AtomicIncrement(&m_iRefs); - CLog::Log(LOGDEBUG, "R+ %02d - ref : %d (VPU)\n", m_idx, count); + CLog::Log(LOGDEBUG | LOGVIDEO, "R+ %02d - ref : %ld (VPU)\n", m_idx, count); #else AtomicIncrement(&m_iRefs); #endif @@ -1223,25 +1058,16 @@ long CDVDVideoCodecIMXBuffer::Release() { long count = AtomicDecrement(&m_iRefs); #ifdef TRACE_FRAMES - CLog::Log(LOGDEBUG, "R- %02d - ref : %d (VPU)\n", m_idx, count); + CLog::Log(LOGDEBUG | LOGVIDEO, "R- %02d - ref : %ld (VPU)\n", m_idx, count); #endif - if (count == 2) - { - // Only referenced by the codec and its next frame, release the previous - SAFE_RELEASE(m_previousBuffer); - } - else if (count == 1) + if (count == 1) { // If count drops to 1 then the only reference is being held by the codec // that it can be released in the next Decode call. - if(m_frameBuffer != NULL) - { - m_rendered = true; - SAFE_RELEASE(m_previousBuffer); + m_recycleBuffers.insert_after(m_recycleBuffers.before_begin(), this); #ifdef TRACE_FRAMES - CLog::Log(LOGDEBUG, "R %02d (VPU)\n", m_idx); + CLog::Log(LOGDEBUG | LOGVIDEO, "R %02d (VPU)\n", m_idx); #endif - } } else if (count == 0) { @@ -1251,36 +1077,11 @@ long CDVDVideoCodecIMXBuffer::Release() return count; } -bool CDVDVideoCodecIMXBuffer::IsValid() -{ - return m_frameBuffer != NULL; -} - -void CDVDVideoCodecIMXBuffer::BeginRender() -{ - CDVDVideoCodecIMX::Enter(); -} - -void CDVDVideoCodecIMXBuffer::EndRender() -{ - CDVDVideoCodecIMX::Leave(); -} - -bool CDVDVideoCodecIMXBuffer::Rendered() const -{ - return m_rendered; -} - -void CDVDVideoCodecIMXBuffer::Queue(VpuDecOutFrameInfo *frameInfo, - CDVDVideoCodecIMXBuffer *previous) +void CDVDVideoCodecIMXBuffer::Queue(VpuDecOutFrameInfo *frameInfo) { // No lock necessary because at this time there is definitely no // thread still holding a reference m_frameBuffer = frameInfo->pDisplayFrameBuf; - m_rendered = false; - m_previousBuffer = previous; - if (m_previousBuffer) - m_previousBuffer->Lock(); #ifdef IMX_INPUT_FORMAT_I420 iFormat = _4CC('I', '4', '2', '0'); @@ -1298,22 +1099,24 @@ VpuDecRetCode CDVDVideoCodecIMXBuffer::ReleaseFramebuffer(VpuDecHandle *handle) { // Again no lock required because this is only issued after the last // external reference was released - VpuDecRetCode ret = VPU_DEC_RET_FAILURE; + VpuDecRetCode ret = VPU_DEC_RET_SUCCESS; - if((m_frameBuffer != NULL) && *handle) + m_renderLock.lock(); + if(m_frameBuffer) { ret = VPU_DecOutFrameDisplayed(*handle, m_frameBuffer); if(ret != VPU_DEC_RET_SUCCESS) CLog::Log(LOGERROR, "%s: vpu clear frame display failure: ret=%d \r\n",__FUNCTION__,ret); + else + m_frameBuffer = NULL; } + m_renderLock.unlock(); + #ifdef TRACE_FRAMES - CLog::Log(LOGDEBUG, "- %02d (VPU)\n", m_idx); + CLog::Log(LOGDEBUG | LOGVIDEO, "- %02d (VPU) | ret: %d\n", m_idx, ret); #endif - m_rendered = false; - m_frameBuffer = NULL; SetPts(DVD_NOPTS_VALUE); - SAFE_RELEASE(m_previousBuffer); - + iFlags = DVP_FLAG_DROPPED; return ret; } @@ -1321,7 +1124,7 @@ CDVDVideoCodecIMXBuffer::~CDVDVideoCodecIMXBuffer() { assert(m_iRefs == 0); #ifdef TRACE_FRAMES - CLog::Log(LOGDEBUG, "~ %02d (VPU)\n", m_idx); + CLog::Log(LOGDEBUG | LOGVIDEO, "~ %02d (VPU)\n", m_idx); #endif } @@ -1339,23 +1142,22 @@ CIMXContext::CIMXContext() , m_bufferCapture(NULL) , m_deviceName("/dev/fb1") { - // Limit queue to 2 - m_input.resize(2); - m_beginInput = m_endInput = m_bufferedInput = 0; m_pageCrops = new CRectInt[m_fbPages]; - CLog::Log(LOGDEBUG, "iMX : Allocated %d render buffers\n", m_fbPages); + CLog::Log(LOGDEBUG | LOGVIDEO, "iMX : Allocated %d render buffers\n", m_fbPages); SetBlitRects(CRectInt(), CRectInt()); + g2dOpenDevices(); // Start the ipu thread Create(); } CIMXContext::~CIMXContext() { - StopThread(false); + Stop(false); Dispose(); CloseDevices(); + g2dCloseDevices(); } bool CIMXContext::GetFBInfo(const std::string &fbdev, struct fb_var_screeninfo *fbVar) @@ -1398,14 +1200,15 @@ void CIMXContext::MemMap(struct fb_fix_screeninfo *fb_fix) bool CIMXContext::AdaptScreen() { - if(m_ipuHandle) { + if(m_ipuHandle) + { close(m_ipuHandle); m_ipuHandle = 0; } MemMap(); - if(!m_fbHandle) + if(!m_fbHandle && !OpenDevices()) goto Err; struct fb_var_screeninfo fbVar; @@ -1414,13 +1217,17 @@ bool CIMXContext::AdaptScreen() CLog::Log(LOGNOTICE, "iMX : Changing framebuffer parameters\n"); + if (SysfsUtils::Has("/sys/class/graphics/fb1/ntsc_mode")) + { + std::string ntsc; + SysfsUtils::GetString("/sys/class/graphics/fb0/ntsc_mode", ntsc); + SysfsUtils::SetInt("/sys/class/graphics/fb1/ntsc_mode", ntsc.find("active") != std::string::npos ? 1 : 0); + } + m_fbWidth = fbVar.xres; m_fbHeight = fbVar.yres; - if (g_renderManager.IsStarted()) - m_fbInterlaced = g_graphicsContext.GetResInfo(g_renderManager.GetResolution()).dwFlags & D3DPRESENTFLAG_INTERLACED; - else - m_fbInterlaced = g_graphicsContext.GetResInfo(CDisplaySettings::GetInstance().GetCurrentResolution()).dwFlags & D3DPRESENTFLAG_INTERLACED; + m_fbInterlaced = g_graphicsContext.GetResInfo().dwFlags & D3DPRESENTFLAG_INTERLACED; if (!GetFBInfo(m_deviceName, &m_fbVar)) goto Err; @@ -1479,12 +1286,6 @@ Err: return false; } -void CIMXContext::OnLostDevice() -{ - CSingleLock lk(m_pageSwapLock); - m_bFbIsConfigured = false; -} - void CIMXContext::OnResetDevice() { CSingleLock lk(m_pageSwapLock); @@ -1498,7 +1299,7 @@ bool CIMXContext::TaskRestart() { CLog::Log(LOGINFO, "iMX : %s - restarting IMX rendererer\n", __FUNCTION__); // Stop the ipu thread - StopThread(); + Stop(); MemMap(); CloseDevices(); @@ -1527,7 +1328,21 @@ bool CIMXContext::OpenDevices() return m_fbHandle > 0; } -bool CIMXContext::CloseDevices() +inline +void CIMXContext::g2dOpenDevices() +{ + // open g2d here to ensure all g2d fucntions are called from the same thread + if (unlikely(!m_g2dHandle)) + { + if (g2d_open(&m_g2dHandle) != 0) + { + m_g2dHandle = NULL; + CLog::Log(LOGERROR, "%s - Error while trying open G2D\n", __FUNCTION__); + } + } +} + +void CIMXContext::CloseDevices() { CLog::Log(LOGINFO, "iMX : Closing devices\n"); @@ -1542,8 +1357,16 @@ bool CIMXContext::CloseDevices() close(m_ipuHandle); m_ipuHandle = 0; } +} - return true; +void CIMXContext::g2dCloseDevices() +{ + // close g2d here to ensure all g2d fucntions are called from the same thread + if (m_bufferCapture && !g2d_free(m_bufferCapture)) + m_bufferCapture = NULL; + + if (m_g2dHandle && !g2d_close(m_g2dHandle)) + m_g2dHandle = NULL; } bool CIMXContext::GetPageInfo(CIMXBuffer *info, int page) @@ -1565,6 +1388,8 @@ bool CIMXContext::Blank() if (!m_fbHandle) return false; CSingleLock lk(m_pageSwapLock); + if (CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_ADJUSTREFRESHRATE) == ADJUST_REFRESHRATE_OFF) + SysfsUtils::SetInt("/sys/class/graphics/fb0/blank", 1); m_bFbIsConfigured = false; return ioctl(m_fbHandle, FBIOBLANK, FB_BLANK_NORMAL) == 0; } @@ -1574,6 +1399,8 @@ bool CIMXContext::Unblank() if (!m_fbHandle) return false; CSingleLock lk(m_pageSwapLock); + if (CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_ADJUSTREFRESHRATE) == ADJUST_REFRESHRATE_OFF) + SysfsUtils::SetInt("/sys/class/graphics/fb0/blank", 0); m_bFbIsConfigured = true; return ioctl(m_fbHandle, FBIOBLANK, FB_BLANK_UNBLANK) == 0; } @@ -1598,10 +1425,6 @@ void CIMXContext::SetFieldData(uint8_t fieldFmt) fieldFmt &= -!m_fbInterlaced; - // disable deinterlacing when not rendering fullscreen - if (!g_graphicsContext.IsFullScreenVideo()) - fieldFmt = 0; - bool dr = IsDoubleRate(); bool deint = !!m_currentFieldFmt; m_currentFieldFmt = fieldFmt; @@ -1617,38 +1440,65 @@ void CIMXContext::SetFieldData(uint8_t fieldFmt) AdaptScreen(); } -bool CIMXContext::Blit(int page, CIMXBuffer *source_p, CIMXBuffer *source, uint8_t fieldFmt) -{ - if (page < 0 || page >= m_fbPages) - return false; - - IPUTask ipu; +#define MASK1 (IPU_DEINTERLACE_RATE_FRAME1 | RENDER_FLAG_TOP) +#define MASK2 (IPU_DEINTERLACE_RATE_FRAME1 | RENDER_FLAG_BOT) +#define VAL1 MASK1 +#define VAL2 RENDER_FLAG_BOT - SetFieldData(fieldFmt); - PrepareTask(ipu, source_p, source); - return DoTask(ipu, page); +inline +bool checkIPUStrideOffset(struct ipu_deinterlace *d) +{ + return ((d->field_fmt & MASK1) == VAL1) || + ((d->field_fmt & MASK2) == VAL2); } -bool CIMXContext::BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, uint8_t fieldFmt, CRect *dest) +void CIMXContext::Blit(CIMXBuffer *source_p, CIMXBuffer *source, uint8_t fieldFmt, int page, CRect *dest) { + static int pg; + + if (likely(page == RENDER_TASK_AUTOPAGE)) + page = pg; + else if (page == RENDER_TASK_CAPTURE) + m_CaptureDone = false; + else if (page < 0 && page >= m_fbPages) + return; +#ifdef IMX_PROFILE_BUFFERS + unsigned long long after = XbmcThreads::SystemClockMillis(); + CLog::Log(LOGDEBUG | LOGVIDEO, "+B(%d) %f\n", page, recalcPts(((CDVDVideoCodecIMXBuffer*)source)->GetPts())); +#endif + + pg = ++pg % m_fbPages; + IPUTask ipu; SetFieldData(fieldFmt); PrepareTask(ipu, source_p, source, dest); - return PushTask(ipu); + + ipu.page = page; + ipu.shift = ipu.task.input.deinterlace.field_fmt ? checkIPUStrideOffset(&ipu.task.input.deinterlace) : 0; + + DoTask(ipu); + + if (unlikely(m_speed == DVD_PLAYSPEED_PAUSE)) + return; + + CSingleLock lk(m_pageSwapLock); + if (ipu.task.output.width) + m_input.push(ipu); } bool CIMXContext::PushCaptureTask(CIMXBuffer *source, CRect *dest) { - IPUTask ipu; - - m_CaptureDone = false; - PrepareTask(ipu, NULL, source, dest); - return PushTask(ipu); + Blit(NULL, source, RENDER_TASK_CAPTURE, 0, dest); + return true; } bool CIMXContext::ShowPage(int page, bool shift) { +#ifdef IMX_PROFILE_BUFFERS + unsigned long long pgstart = XbmcThreads::SystemClockMillis(); + unsigned long long pgflip; +#endif if (!m_fbHandle) return false; if (page < 0 || page >= m_fbPages) return false; if (!m_bFbIsConfigured) return false; @@ -1658,25 +1508,27 @@ bool CIMXContext::ShowPage(int page, bool shift) // does not hurt. CSingleLock lk(m_pageSwapLock); + m_fbCurrentPage = page; m_fbVar.activate = FB_ACTIVATE_VBL; - m_fbVar.yoffset = (m_fbVar.yres + 1) * page + !shift; if (ioctl(m_fbHandle, FBIOPAN_DISPLAY, &m_fbVar) < 0) { CLog::Log(LOGWARNING, "Panning failed: %s\n", strerror(errno)); return false; } - m_fbCurrentPage = page; - - if (!m_vsync) - return true; - +#ifdef IMX_PROFILE_BUFFERS + pgflip = XbmcThreads::SystemClockMillis(); +#endif // Wait for flip - if (ioctl(m_fbHandle, FBIO_WAITFORVSYNC, 0) < 0) + if (m_vsync && ioctl(m_fbHandle, FBIO_WAITFORVSYNC, 0) < 0) { CLog::Log(LOGWARNING, "Vsync failed: %s\n", strerror(errno)); return false; } +#ifdef IMX_PROFILE_BUFFERS + unsigned long long pgend = XbmcThreads::SystemClockMillis(); + CLog::Log(LOGDEBUG | LOGVIDEO, "NP(%d) - tot: %d - sync: %d - jflp: %d\n", m_fbCurrentPage, (int)(pgend - pgstart), (int)(pgend - pgflip), (int)(pgflip - pgstart)); +#endif return true; } @@ -1717,8 +1569,6 @@ void CIMXContext::Clear(int page) CLog::Log(LOGERROR, "iMX Clear fb error : Unexpected format"); } -#define clamp_byte(x) (x<0?0:(x>255?255:x)) - void CIMXContext::CaptureDisplay(unsigned char *buffer, int iWidth, int iHeight) { if ((m_fbVar.nonstd != _4CC('R', 'G', 'B', '4')) && @@ -1749,7 +1599,7 @@ void CIMXContext::CaptureDisplay(unsigned char *buffer, int iWidth, int iHeight) } else //_4CC('U', 'Y', 'V', 'Y'))) { - int r,g,b,a; + uint8_t r,g,b,a; int u, y0, v, y1; int iStride = m_fbWidth*2; int oStride = iWidth*4; @@ -1767,8 +1617,8 @@ void CIMXContext::CaptureDisplay(unsigned char *buffer, int iWidth, int iHeight) for (int y = 0; y < iHeight; ++y, display += iStride, buffer += oStride) { - unsigned char *iLine = display; - unsigned char *oLine = buffer; + uint8_t *iLine = display; + uint8_t *oLine = buffer; for (int x = 0; x < iWidth; ++x, iLine += 4, oLine += 8 ) { @@ -1782,9 +1632,9 @@ void CIMXContext::CaptureDisplay(unsigned char *buffer, int iWidth, int iHeight) g = (cy*y0 + cb2*u + cr2*v) >> 16; b = (cy*y0 + cb3*u + cr3*v) >> 16; - oLine[0] = (clamp_byte(b)*a + oLine[0]*oLine[3])/255; - oLine[1] = (clamp_byte(g)*a + oLine[1]*oLine[3])/255; - oLine[2] = (clamp_byte(r)*a + oLine[2]*oLine[3])/255; + oLine[0] = (b*a + oLine[0]*oLine[3])/255; + oLine[1] = (g*a + oLine[1]*oLine[3])/255; + oLine[2] = (r*a + oLine[2]*oLine[3])/255; oLine[3] = 255; a = 255-oLine[7]; @@ -1792,59 +1642,17 @@ void CIMXContext::CaptureDisplay(unsigned char *buffer, int iWidth, int iHeight) g = (cy*y0 + cb2*u + cr2*v) >> 16; b = (cy*y0 + cb3*u + cr3*v) >> 16; - oLine[4] = (clamp_byte(b)*a + oLine[4]*oLine[7])/255; - oLine[5] = (clamp_byte(g)*a + oLine[5]*oLine[7])/255; - oLine[6] = (clamp_byte(r)*a + oLine[6]*oLine[7])/255; + oLine[4] = (b*a + oLine[4]*oLine[7])/255; + oLine[5] = (g*a + oLine[5]*oLine[7])/255; + oLine[6] = (r*a + oLine[6]*oLine[7])/255; oLine[7] = 255; } } } } -bool CIMXContext::PushTask(const IPUTask &task) -{ - if (!task.current) - return false; - - if (m_bStop) - { - m_inputNotEmpty.notifyAll(); - return false; - } - - { - CSingleLock lk(m_monitor); - // If the input queue is full, wait for a free slot - while ((m_bufferedInput == m_input.size()) && !m_bStop) - m_inputNotFull.wait(lk); - } - - if (m_bStop) - { - m_inputNotEmpty.notifyAll(); - return false; - } - - // Store the value - if (task.previous) task.previous->Lock(); - task.current->Lock(); - - { - CSingleLock lk(m_monitor); - memcpy(&m_input[m_endInput], &task, sizeof(IPUTask)); - m_endInput = (m_endInput+1) % m_input.size(); - ++m_bufferedInput; - m_inputNotEmpty.notifyAll(); - } - - return true; -} - void CIMXContext::WaitCapture() { - CSingleLock lk(m_monitor); - while (!m_CaptureDone) - m_inputNotFull.wait(lk); } void CIMXContext::PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *source, @@ -1948,7 +1756,7 @@ void CIMXContext::PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *so } } -bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) +bool CIMXContext::DoTask(IPUTask &ipu) { bool swapColors = false; @@ -1969,12 +1777,12 @@ bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) ipu.task.output.width = m_fbWidth; ipu.task.output.height = m_fbHeight; ipu.task.output.format = m_fbVar.nonstd; - ipu.task.output.paddr = m_fbPhysAddr + targetPage*m_fbPageSize; + ipu.task.output.paddr = m_fbPhysAddr + ipu.page*m_fbPageSize; - if (m_pageCrops[targetPage] != dstRect) + if (m_pageCrops[ipu.page] != dstRect) { - m_pageCrops[targetPage] = dstRect; - Clear(targetPage); + m_pageCrops[ipu.page] = dstRect; + Clear(ipu.page); } } else @@ -2048,20 +1856,16 @@ bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) ret = ioctl(m_ipuHandle, IPU_QUEUE_TASK, &ipu.task); else ret = 0; +#ifdef IMX_PROFILE_BUFFERS + unsigned long long after = XbmcThreads::SystemClockMillis(); + CLog::Log(LOGDEBUG | LOGVIDEO, "+P(%d) %f %d\n", ipu.page, recalcPts(((CDVDVideoCodecIMXBuffer*)ipu.current)->GetPts()), (int)(after-before)); +#endif ipu.current->EndRender(); - if (ret < 0) { CLog::Log(LOGERROR, "IPU task failed: %s\n", strerror(errno)); return false; } - - // Duplicate 2nd scandline if double rate is active - if (IsDoubleRate()) - { - uint8_t *pageAddr = m_fbVirtAddr + targetPage*m_fbPageSize; - memcpy(pageAddr, pageAddr+m_fbLineLength, m_fbLineLength); - } } else { @@ -2121,13 +1925,12 @@ bool CIMXContext::DoTask(IPUTask &ipu, int targetPage) if ((m_bufferCapture) && (ipu.task.output.paddr == m_bufferCapture->buf_paddr)) m_CaptureDone = true; } - ipu.current->EndRender(); - } - #ifdef IMX_PROFILE_BUFFERS unsigned long long after = XbmcThreads::SystemClockMillis(); - CLog::Log(LOGNOTICE, "+P %f %d\n", ((CDVDVideoCodecIMXBuffer*)ipu.current)->GetPts(), (int)(after-before)); + CLog::Log(LOGDEBUG | LOGVIDEO, "+P(%d) %f %d\n", ipu.page, recalcPts(((CDVDVideoCodecIMXBuffer*)ipu.current)->GetPts()), (int)(after-before)); #endif + ipu.current->EndRender(); + } return true; } @@ -2147,98 +1950,31 @@ void CIMXContext::OnExit() CLog::Log(LOGNOTICE, "iMX : IPU thread terminated"); } -void CIMXContext::StopThread(bool bWait /*= true*/) +void CIMXContext::Stop(bool bWait /*= true*/) { if (!IsRunning()) return; - Blank(); CThread::StopThread(false); - m_inputNotFull.notifyAll(); - m_inputNotEmpty.notifyAll(); + m_input.signal_stop(); + Blank(); if (bWait && IsRunning()) CThread::StopThread(true); } -#define MASK1 (IPU_DEINTERLACE_RATE_FRAME1 | RENDER_FLAG_TOP) -#define MASK2 (IPU_DEINTERLACE_RATE_FRAME1 | RENDER_FLAG_BOT) -#define VAL1 MASK1 -#define VAL2 RENDER_FLAG_BOT - -inline -bool checkIPUStrideOffset(struct ipu_deinterlace *d) -{ - return ((d->field_fmt & MASK1) == VAL1) || - ((d->field_fmt & MASK2) == VAL2); -} - void CIMXContext::Process() { - bool ret; - - // open g2d here to ensure all g2d fucntions are called from the same thread - if (m_g2dHandle == NULL) - { - if (g2d_open(&m_g2dHandle) != 0) - { - m_g2dHandle = NULL; - CLog::Log(LOGERROR, "%s - Error while trying open G2D\n", __FUNCTION__); - } - } - while (!m_bStop) { - IPUTask *task; - { - CSingleLock lk(m_monitor); - while (!m_bufferedInput && !m_bStop) - m_inputNotEmpty.wait(lk); + IPUTask task = m_input.pop(); - task = &m_input[m_beginInput]; - } if (m_bStop) break; - ret = DoTask(*task, (1-m_fbCurrentPage) & m_vsync); - bool shift = checkIPUStrideOffset(&task->task.input.deinterlace); - - // Free resources - task->Done(); - - { - CSingleLock lk(m_monitor); - m_beginInput = (m_beginInput+1) % m_input.size(); - --m_bufferedInput; - m_inputNotFull.notifyAll(); - } - // Show back buffer - if (task->task.output.width && ret) - ShowPage(1-m_fbCurrentPage, shift); - } - - // Mark all pending jobs as done - CSingleLock lk(m_monitor); - while (m_bufferedInput > 0) - { - m_input[m_beginInput].Done(); - m_beginInput = (m_beginInput+1) % m_input.size(); - --m_bufferedInput; - } - - // close g2d here to ensure all g2d fucntions are called from the same thread - if (m_bufferCapture) - { - if (g2d_free(m_bufferCapture)) - CLog::Log(LOGERROR, "iMX : Failed to free capture buffers\n"); - m_bufferCapture = NULL; - } - if (m_g2dHandle) - { - if (g2d_close(m_g2dHandle)) - CLog::Log(LOGERROR, "iMX : Error while closing G2D\n"); - m_g2dHandle = NULL; + ShowPage(task.page, task.shift); } + m_input.for_each(callDone); return; } diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h index c53460e..77e59a4 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h @@ -24,9 +24,14 @@ #include "threads/Thread.h" #include "utils/BitstreamConverter.h" #include "guilib/Geometry.h" +#include "system_gl.h" #include "DVDVideoCodec.h" #include "DVDStreamInfo.h" #include "guilib/DispResource.h" +#include "cores/dvdplayer/DVDCodecs/DVDCodecs.h" +#include "DVDClock.h" +#include "utils/log.h" +#include "utils/StringUtils.h" #include #include @@ -34,6 +39,15 @@ #include #include +#include +#include +#include +#include +#include +#include + +#define likely(x) __builtin_expect(!!(x),1) +#define unlikely(x) __builtin_expect(!!(x),0) // The decoding format of the VPU buffer. Comment this to decode // as NV12. The VPU works faster with NV12 in combination with @@ -59,6 +73,108 @@ // and performance tests. This define must never be active in distributions. //#define DUMP_STREAM +inline +double recalcPts(double pts) +{ + return (double)(pts == DVD_NOPTS_VALUE ? 0.0 : pts*1e-6); +} + +template +class lkFIFO +{ +public: + lkFIFO() { size_ = queue_.max_size(); abort_ = &no; } + +public: + T pop() + { + std::unique_lock mlock(mutex_); + while (queue_.empty() && !*abort_) + read_.wait(mlock); + + T val; + if (likely(!*abort_)) + { + val = queue_.front(); + queue_.pop_front(); + } + + mlock.unlock(); + write_.notify_one(); + return val; + } + + bool push(const T& item) + { + std::unique_lock mlock(mutex_); + while (queue_.size() == size_ && !*abort_) + write_.wait(mlock); + + queue_.push_back(item); + mlock.unlock(); + read_.notify_all(); + return true; + } + + void signal_stop() + { + abort_ = &yes; + write_.notify_all(); + read_.notify_all(); + } + + void shrink(std::deque shrinkTo) + { + std::unique_lock mlock(mutex_); + queue_.swap(shrinkTo); + write_.notify_all(); + } + + // will expire unused data + // and resize to empty + void clear() + { + std::deque tmp; + shrink(tmp); + } + + // will expire unused data + // and resize to just fit + void shrink_to_fit() + { + std::deque tmp(queue_); + shrink(tmp); + } + + void set_quota_size(int newsize) + { + size_ = newsize; + if (queue_.size() > size_) + { + queue_.resize(size_); + shrink_to_fit(); + } + } + + void for_each(void (*fn)(T &t)) + { + std::unique_lock mlock(mutex_); + std::for_each(queue_.begin(), queue_.end(), fn); + write_.notify_all(); + } + + int empty() { return queue_.empty(); } + int size() { return queue_.size(); } +private: + std::deque queue_; + std::mutex mutex_; + std::condition_variable read_, write_; + + unsigned int size_; + volatile bool *abort_; + bool no = false; + bool yes = true; +}; /*>> TO BE MOVED TO A MORE CENTRAL PLACE IN THE SOURCE DIR >>>>>>>>>>>>>>>>>>>*/ // Generell description of a buffer used by @@ -86,6 +202,8 @@ protected: long m_iRefs; }; +#define RENDER_TASK_AUTOPAGE -1 +#define RENDER_TASK_CAPTURE -2 // iMX context class that handles all iMX hardware // related stuff @@ -97,8 +215,10 @@ public: bool AdaptScreen(); bool TaskRestart(); - bool CloseDevices(); + void CloseDevices(); + void g2dCloseDevices(); bool OpenDevices(); + void g2dOpenDevices(); bool Blank(); bool Unblank(); @@ -114,17 +234,12 @@ public: void SetBlitRects(const CRect &srcRect, const CRect &dstRect); - // Blits a buffer to a particular page. + // Blits a buffer to a particular page (-1 for auto page) // source_p (previous buffer) is required for de-interlacing // modes LOW_MOTION and MED_MOTION. - bool Blit(int targetPage, CIMXBuffer *source_p, - CIMXBuffer *source, uint8_t fieldFmt = 0); - - // Same as blit but runs in another thread and returns after the task has - // been queued. BlitAsync renders always to the current backbuffer and - // swaps the pages. - bool BlitAsync(CIMXBuffer *source_p, CIMXBuffer *source, - uint8_t fieldFmt = 0, CRect *dest = NULL); + void Blit(CIMXBuffer *source_p, CIMXBuffer *source, + uint8_t fieldFmt = 0, int targetPage = RENDER_TASK_AUTOPAGE, + CRect *dest = NULL); // Shows a page vsynced bool ShowPage(int page, bool shift = false); @@ -142,9 +257,13 @@ public: void *GetCaptureBuffer() const { if (m_bufferCapture) return m_bufferCapture->buf_vaddr; else return NULL; } void WaitCapture(); - void OnLostDevice(); + void RendererAllowed(bool yes); void OnResetDevice(); + void SetSpeed(int iSpeed) { m_speed = iSpeed; } + + static const int m_fbPages; + private: struct IPUTask { @@ -166,14 +285,19 @@ private: // The actual task struct ipu_task task; + + int page; + int shift; }; + static void callDone(IPUTask &t) { t.Done(); } + bool GetFBInfo(const std::string &fbdev, struct fb_var_screeninfo *fbVar); bool PushTask(const IPUTask &); void PrepareTask(IPUTask &ipu, CIMXBuffer *source_p, CIMXBuffer *source, CRect *dest = NULL); - bool DoTask(IPUTask &ipu, int targetPage); + bool DoTask(IPUTask &ipu); void SetFieldData(uint8_t fieldFmt); @@ -182,11 +306,11 @@ private: virtual void OnStartup(); virtual void OnExit(); - virtual void StopThread(bool bWait = true); virtual void Process(); + void Stop(bool bWait = true); private: - typedef std::vector TaskQueue; + lkFIFO m_input; int m_fbHandle; int m_fbCurrentPage; @@ -210,23 +334,18 @@ private: bool m_bFbIsConfigured; CCriticalSection m_pageSwapLock; - TaskQueue m_input; - volatile int m_beginInput, m_endInput; - volatile size_t m_bufferedInput; - XbmcThreads::ConditionVariable m_inputNotEmpty; - XbmcThreads::ConditionVariable m_inputNotFull; - mutable CCriticalSection m_monitor; void *m_g2dHandle; struct g2d_buf *m_bufferCapture; bool m_CaptureDone; - static const int m_fbPages; std::string m_deviceName; + int m_speed; }; extern CIMXContext g_IMXContext; + /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ @@ -251,7 +370,9 @@ public: // Base class of IMXVPU and IMXIPU buffer -class CDVDVideoCodecIMXBuffer : public CIMXBuffer { +class CDVDVideoCodecIMXBuffer : public CIMXBuffer +{ +friend class CDVDVideoCodecIMX; public: #ifdef TRACE_FRAMES CDVDVideoCodecIMXBuffer(int idx); @@ -262,22 +383,19 @@ public: // reference counting virtual void Lock(); virtual long Release(); - virtual bool IsValid(); + virtual bool IsValid() { return m_frameBuffer; } - virtual void BeginRender(); - virtual void EndRender(); + virtual void BeginRender() { m_renderLock.lock(); } + virtual void EndRender() { m_renderLock.unlock(); } - void SetPts(double pts); + void SetPts(double pts) { m_pts = pts; }; double GetPts() const { return m_pts; } - void SetDts(double dts); + void SetDts(double dts) { m_dts = dts; }; double GetDts() const { return m_dts; } - bool Rendered() const; - void Queue(VpuDecOutFrameInfo *frameInfo, - CDVDVideoCodecIMXBuffer *previous); + void Queue(VpuDecOutFrameInfo *frameInfo); VpuDecRetCode ReleaseFramebuffer(VpuDecHandle *handle); - CDVDVideoCodecIMXBuffer *GetPreviousBuffer() const { return m_previousBuffer; } VpuFieldType GetFieldType() const { return m_fieldType; } private: @@ -294,8 +412,8 @@ private: double m_dts; VpuFieldType m_fieldType; VpuFrameBuffer *m_frameBuffer; - bool m_rendered; - CDVDVideoCodecIMXBuffer *m_previousBuffer; // Holds the reference counted previous buffer + CCriticalSection m_renderLock; // Lock to protect buffers being rendered + unsigned int iFlags; }; @@ -309,8 +427,8 @@ public: virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options); virtual void Dispose(); virtual int Decode(BYTE *pData, int iSize, double dts, double pts); - virtual void SetSkipMode(); - virtual void Reset(); + virtual void SetSkipMode(VpuDecSkipMode skip); + virtual void Reset() { reset(); } virtual bool ClearPicture(DVDVideoPicture *pDvdVideoPicture); virtual bool GetPicture(DVDVideoPicture *pDvdVideoPicture); virtual void SetDropState(bool bDrop); @@ -318,45 +436,53 @@ public: virtual unsigned GetAllowedReferences(); virtual bool GetInterlaced() { return m_initInfo.nInterlace; } - static void Enter(); - static void Leave(); + + virtual bool GetCodecStats(double &pts, int &droppedPics); + virtual void SetCodecControl(int flags); + virtual void SetSpeed(int iSpeed) { g_IMXContext.SetSpeed(iSpeed); m_speed = iSpeed; } protected: bool VpuOpen(); bool VpuAllocBuffers(VpuMemInfo *); - bool VpuFreeBuffers(); + bool VpuFreeBuffers(bool dispose = true); bool VpuAllocFrameBuffers(); - int VpuFindBuffer(void *frameAddr); + + void SetVPUParams(VpuDecConfig InDecConf, void* pInParam); + void SetDrainMode(VpuDecInputType drop); + void SetCodecParam(VpuBufferNode *bn, unsigned char * data, unsigned int size); + + void reset(bool dispose = true); + bool getOutputFrame(VpuDecOutFrameInfo *frm); static const int m_extraVpuBuffers; // Number of additional buffers for VPU - static const int m_maxVpuDecodeLoops; // Maximum iterations in VPU decoding loop // by both decoding and rendering threads - static CCriticalSection m_codecBufferLock; // Lock to protect buffers handled + VpuMemInfo m_memInfo; CDVDStreamInfo m_hints; // Hints from demuxer at stream opening + CDVDCodecOptions m_options; const char *m_pFormatName; // Current decoder format name VpuDecOpenParam m_decOpenParam; // Parameters required to call VPU_DecOpen CDecMemInfo m_decMemInfo; // VPU dedicated memory description VpuDecHandle m_vpuHandle; // Handle for VPU library calls VpuDecInitInfo m_initInfo; // Initial info returned from VPU at decoding start - bool m_dropRequest; // Current drop state - bool m_dropState; // Current drop state + VpuDecSkipMode m_dropRequest; // Current drop state + int m_dropped; + VpuDecInputType m_drainMode; int m_vpuFrameBufferNum; // Total number of allocated frame buffers VpuFrameBuffer *m_vpuFrameBuffers; // Table of VPU frame buffers description - CDVDVideoCodecIMXBuffer **m_outputBuffers; // Table of VPU output buffers - CDVDVideoCodecIMXBuffer *m_lastBuffer; // Keep track of previous VPU output buffer (needed by deinterlacing motion engin) + std::unordered_map + m_outputBuffers; // Table of VPU output buffers CDVDVideoCodecIMXBuffer *m_currentBuffer; VpuMemDesc *m_extraMem; // Table of allocated extra Memory - int m_frameCounter; // Decoded frames counter bool m_usePTS; // State whether pts out of decoding process should be used VpuDecOutFrameInfo m_frameInfo; // Store last VPU output frame info CBitstreamConverter *m_converter; // H264 annex B converter bool m_convert_bitstream; // State whether bitstream conversion is required int m_bytesToBeConsumed; // Remaining bytes in VPU - double m_previousPts; // Enable to keep pts when needed bool m_frameReported; // State whether the frame consumed event will be reported by libfslvpu bool m_warnOnce; // Track warning messages to only warn once + int m_codecControlFlags; + int m_speed; #ifdef DUMP_STREAM FILE *m_dump; #endif }; - diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp index a1ad0fd..27458df 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp @@ -289,13 +289,6 @@ void CDVDPlayerVideo::OnStartup() m_FlipTimePts = 0.0; } -void CDVDPlayerVideo::DropStats() -{ - ResetFrameRateCalc(); - m_droppingStats.Reset(); - m_pullupCorrection.Flush(); -} - void CDVDPlayerVideo::Process() { CLog::Log(LOGNOTICE, "running thread: video_thread"); @@ -1417,7 +1410,7 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts, bool updateOnly) result |= EOS_DROPPED; m_droppingStats.m_dropRequests = 0; if (g_advancedSettings.CanLogComponent(LOGVIDEO)) - CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - dropped pictures, Sleeptime: %f, Bufferlevel: %d, Gain: %f", iSleepTime, iBufferLevel, iGain); + CLog::Log(LOGDEBUG,"CDVDPlayerVideo::CalcDropRequirement - dropped pictures, Sleeptime: %f, Bufferlevel: %d, Gain: %f", iSleepTime, iBufferLevel, gain.gain); } else if (iDroppedPics < 0 && iGain > (1/m_fFrameRate + 0.001)) { diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h index 8c296de..cf74b2c 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h @@ -64,9 +64,6 @@ public: , CDVDMessageQueue& parent); virtual ~CDVDPlayerVideo(); - void OnResetDevice() { DropStats(); } - void DropStats(); - bool OpenStream(CDVDStreamInfo &hint); void CloseStream(bool bWaitForBuffers); diff --git a/xbmc/settings/VideoSettings.h b/xbmc/settings/VideoSettings.h index ac244e7..fe9fe2a 100644 --- a/xbmc/settings/VideoSettings.h +++ b/xbmc/settings/VideoSettings.h @@ -75,6 +75,7 @@ enum EINTERLACEMETHOD VS_INTERLACEMETHOD_IMX_FASTMOTION = 29, VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE = 30, VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE_INVERTED = 31, + VS_INTERLACEMETHOD_IMX_MEDMOTION = 32, VS_INTERLACEMETHOD_MAX // do not use and keep as last enum value. }; diff --git a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp index 2b4315b..6474df9 100644 --- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoSettings.cpp @@ -275,6 +275,7 @@ void CGUIDialogVideoSettings::InitializeSettings() entries.push_back(std::make_pair(16334, VS_INTERLACEMETHOD_IMX_FASTMOTION)); entries.push_back(std::make_pair(16335, VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE)); entries.push_back(std::make_pair(16336, VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE_INVERTED)); + entries.push_back(std::make_pair(16337, VS_INTERLACEMETHOD_IMX_MEDMOTION)); /* remove unsupported methods */ for (StaticIntegerSettingOptions::iterator it = entries.begin(); it != entries.end(); ) -- 2.7.1 From ead2278be7825d2178634807d554cd910c29254d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 22 Mar 2016 22:28:13 +0000 Subject: [PATCH 241/250] Move hotplug checking into its own thread Currently checking for new linux input devices is called from the rendering thread. We've been getting reports of skipped frames on raspberry pi. Specifically if eventlirc is active and you have an LIRC capable device connected the hotplug check is slow and you get a frame skip every ten seconds. So move this code into its own thread (cherry picked from commit b4423b184e08dbb35ce74b019128982436ed2400) Signed-off-by: Matus Kral Conflicts: xbmc/input/linux/LinuxInputDevices.cpp --- xbmc/input/linux/LinuxInputDevices.cpp | 54 +++++++++++++++++++++------------- xbmc/input/linux/LinuxInputDevices.h | 14 ++++++++- xbmc/windowing/WinEventsLinux.cpp | 1 + xbmc/windowing/WinEventsLinux.h | 2 ++ 4 files changed, 49 insertions(+), 22 deletions(-) diff --git a/xbmc/input/linux/LinuxInputDevices.cpp b/xbmc/input/linux/LinuxInputDevices.cpp index 0cbfa83..d848726 100644 --- a/xbmc/input/linux/LinuxInputDevices.cpp +++ b/xbmc/input/linux/LinuxInputDevices.cpp @@ -1081,6 +1081,30 @@ bool CLinuxInputDevice::IsUnplugged() return m_bUnplugged; } +CLinuxInputDevicesCheckHotplugged::CLinuxInputDevicesCheckHotplugged(CLinuxInputDevices &parent) : + CThread("CLinuxInputDevicesCheckHotplugged"), m_parent(parent) +{ + Create(); + SetPriority(THREAD_PRIORITY_BELOW_NORMAL); +} + +CLinuxInputDevicesCheckHotplugged::~CLinuxInputDevicesCheckHotplugged() +{ + m_bStop = true; + m_quitEvent.Set(); + StopThread(true); +} + +void CLinuxInputDevicesCheckHotplugged::Process() +{ + while (!m_bStop) + { + m_parent.CheckHotplugged(); + // every ten seconds + m_quitEvent.WaitMSec(10000); + } +} + bool CLinuxInputDevices::CheckDevice(const char *device) { int fd; @@ -1158,10 +1182,6 @@ void CLinuxInputDevices::Close() */ void CLinuxInputDevices::CheckHotplugged() { - CSingleLock lock(m_devicesListLock); - - int deviceId = m_devices.size(); - /* No devices specified. Try to guess some. */ for (int i = 0; i < MAX_LINUX_INPUT_DEVICES; i++) { @@ -1169,18 +1189,22 @@ void CLinuxInputDevices::CheckHotplugged() bool ispresent = false; snprintf(buf, 32, "/dev/input/event%d", i); - - for (size_t j = 0; j < m_devices.size(); j++) { - if (m_devices[j]->GetFileName().compare(buf) == 0) + CSingleLock lock(m_devicesListLock); + for (size_t j = 0; j < m_devices.size(); j++) { - ispresent = true; - break; + if (m_devices[j]->GetFileName().compare(buf) == 0) + { + ispresent = true; + break; + } } } if (!ispresent && CheckDevice(buf)) { + CSingleLock lock(m_devicesListLock); + int deviceId = m_devices.size(); CLog::Log(LOGINFO, "Found input device %s", buf); m_devices.push_back(new CLinuxInputDevice(buf, deviceId)); ++deviceId; @@ -1371,18 +1395,6 @@ XBMC_Event CLinuxInputDevices::ReadEvent() InitAvailable(); m_bReInitialize = false; } - else - { - time_t now; - time(&now); - - if ((now - m_lastHotplugCheck) >= 10) - { - CheckHotplugged(); - m_lastHotplugCheck = now; - } - } - CSingleLock lock(m_devicesListLock); XBMC_Event event; diff --git a/xbmc/input/linux/LinuxInputDevices.h b/xbmc/input/linux/LinuxInputDevices.h index d957956..cb13988 100644 --- a/xbmc/input/linux/LinuxInputDevices.h +++ b/xbmc/input/linux/LinuxInputDevices.h @@ -28,6 +28,7 @@ #include "threads/SingleLock.h" #include "input/touch/ITouchInputHandler.h" #include "input/touch/generic/IGenericTouchGestureDetector.h" +#include "threads/Thread.h" struct KeymapEntry { @@ -106,7 +107,18 @@ private: bool CheckDevice(const char *device); std::vector m_devices; bool m_bReInitialize; - time_t m_lastHotplugCheck; +}; + +class CLinuxInputDevicesCheckHotplugged : protected CThread +{ +public: + CLinuxInputDevicesCheckHotplugged(CLinuxInputDevices &parent); + ~CLinuxInputDevicesCheckHotplugged(); +private: + CLinuxInputDevices &m_parent; + CEvent m_quitEvent; +protected: + virtual void Process(); }; #endif /* LINUXINPUTDEVICES_H_ */ diff --git a/xbmc/windowing/WinEventsLinux.cpp b/xbmc/windowing/WinEventsLinux.cpp index 2c0bad2..156348d 100644 --- a/xbmc/windowing/WinEventsLinux.cpp +++ b/xbmc/windowing/WinEventsLinux.cpp @@ -58,6 +58,7 @@ bool CWinEventsLinux::MessagePump() if (!m_initialized) { m_devices.InitAvailable(); + m_checkHotplug = std::unique_ptr(new CLinuxInputDevicesCheckHotplugged(m_devices)); m_initialized = true; } diff --git a/xbmc/windowing/WinEventsLinux.h b/xbmc/windowing/WinEventsLinux.h index 012342e..edc5ba6 100644 --- a/xbmc/windowing/WinEventsLinux.h +++ b/xbmc/windowing/WinEventsLinux.h @@ -22,6 +22,7 @@ #define WINDOW_EVENTS_LINUX_H #pragma once +#include #include "windowing/WinEvents.h" #include "input/linux/LinuxInputDevices.h" @@ -44,6 +45,7 @@ public: private: static bool m_initialized; static CLinuxInputDevices m_devices; + std::unique_ptr m_checkHotplug; }; #endif -- 2.7.1 From d7b469cf8822f61578bba3f69ae35f703794d616 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 27 Mar 2016 16:57:56 +0200 Subject: [PATCH 242/250] Update to master - remove announcer use from CDNSNameCache - flush name cache from Network on services start/restart (cherry picked from commit 36666d3173633f125f7d3494a8e3c90f365a9d54) --- xbmc/network/DNSNameCache.cpp | 10 ---------- xbmc/network/DNSNameCache.h | 11 ++++++----- xbmc/network/Network.cpp | 2 ++ 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/xbmc/network/DNSNameCache.cpp b/xbmc/network/DNSNameCache.cpp index f9881b0..e1a8ec4 100644 --- a/xbmc/network/DNSNameCache.cpp +++ b/xbmc/network/DNSNameCache.cpp @@ -29,20 +29,16 @@ #include #include -using namespace ANNOUNCEMENT; - CDNSNameCache g_DNSCache; CCriticalSection CDNSNameCache::m_critical; CDNSNameCache::CDNSNameCache(void) { - CAnnouncementManager::GetInstance().AddAnnouncer(this); } CDNSNameCache::~CDNSNameCache(void) { - CAnnouncementManager::GetInstance().RemoveAnnouncer(this); } void CDNSNameCache::Flush() @@ -52,12 +48,6 @@ void CDNSNameCache::Flush() g_DNSCache.m_vecDNSNames.clear(); } -void CDNSNameCache::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) -{ - if (!strcmp(sender, "network") && !strcmp(message, "OnInterfacesChange")) - Flush(); -} - bool CDNSNameCache::Lookup(const std::string& strHostName, std::string& strIpAddress) { if (strHostName.empty() && strIpAddress.empty()) diff --git a/xbmc/network/DNSNameCache.h b/xbmc/network/DNSNameCache.h index 18c7afa..126a980 100644 --- a/xbmc/network/DNSNameCache.h +++ b/xbmc/network/DNSNameCache.h @@ -22,12 +22,13 @@ #include #include -#include "interfaces/AnnouncementManager.h" class CCriticalSection; -class CDNSNameCache : public ANNOUNCEMENT::IAnnouncer +class CDNSNameCache { +friend class CNetwork; + public: class CDNSName { @@ -41,11 +42,11 @@ public: static std::string Lookup(const std::string& strHostName); static void Add(const std::string& strHostName, const std::string& strIpAddress); - void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data); - protected: + static void Flush(); + +private: static bool GetCached(const std::string& strHostName, std::string& strIpAddress); - void Flush(); static CCriticalSection m_critical; std::vector m_vecDNSNames; }; diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp index aae3131..c15d998 100644 --- a/xbmc/network/Network.cpp +++ b/xbmc/network/Network.cpp @@ -27,6 +27,7 @@ #include "settings/Settings.h" #include "Network.h" +#include "DNSNameCache.h" #include "messaging/ApplicationMessenger.h" #include "network/NetworkServices.h" #include "utils/log.h" @@ -441,6 +442,7 @@ void CNetwork::NetworkMessage(EMESSAGE message, int param) } CLog::Log(LOGDEBUG, "%s - Starting network services",__FUNCTION__); + CDNSNameCache::Flush(); CNetworkServices::GetInstance().Start(); break; -- 2.7.1 From c075da0a14a6442e2f8121ff39be760c78ee9908 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sat, 2 Apr 2016 15:16:58 +0200 Subject: [PATCH 243/250] DVDVideoCodecIMX - new pan --- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 13 ++++++++++--- xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp index 92a226e..d8a708f 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp @@ -1141,6 +1141,7 @@ CIMXContext::CIMXContext() , m_g2dHandle(NULL) , m_bufferCapture(NULL) , m_deviceName("/dev/fb1") + , m_ioctlPan(0x46ff) { m_pageCrops = new CRectInt[m_fbPages]; CLog::Log(LOGDEBUG | LOGVIDEO, "iMX : Allocated %d render buffers\n", m_fbPages); @@ -1511,10 +1512,16 @@ bool CIMXContext::ShowPage(int page, bool shift) m_fbCurrentPage = page; m_fbVar.activate = FB_ACTIVATE_VBL; m_fbVar.yoffset = (m_fbVar.yres + 1) * page + !shift; - if (ioctl(m_fbHandle, FBIOPAN_DISPLAY, &m_fbVar) < 0) + if (ioctl(m_fbHandle, m_ioctlPan, &m_fbVar) < 0) { - CLog::Log(LOGWARNING, "Panning failed: %s\n", strerror(errno)); - return false; + if (m_ioctlPan != FBIOPAN_DISPLAY) + m_ioctlPan = FBIOPAN_DISPLAY; + else + { + CLog::Log(LOGWARNING, "Panning failed: %s\n", strerror(errno)); + return false; + } + ioctl(m_fbHandle, m_ioctlPan, &m_fbVar); } #ifdef IMX_PROFILE_BUFFERS pgflip = XbmcThreads::SystemClockMillis(); diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h index 77e59a4..269bdb9 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h @@ -341,6 +341,8 @@ private: std::string m_deviceName; int m_speed; + + int m_ioctlPan; }; -- 2.7.1 From 5624f59a56d1d7720957c4b24e754fe2ff13cd7f Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Mon, 4 Apr 2016 04:50:57 +0200 Subject: [PATCH 244/250] AE: fix losing sink --- xbmc/cores/dvdplayer/DVDAudio.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/xbmc/cores/dvdplayer/DVDAudio.cpp b/xbmc/cores/dvdplayer/DVDAudio.cpp index f420300..4d22e1b 100644 --- a/xbmc/cores/dvdplayer/DVDAudio.cpp +++ b/xbmc/cores/dvdplayer/DVDAudio.cpp @@ -154,7 +154,6 @@ void CDVDAudio::Finish() void CDVDAudio::Drain() { - Finish(); CSingleLock lock (m_critSection); if (m_pAudioStream) m_pAudioStream->Drain(true); -- 2.7.1 From 2039b3d83c00f2f724bed261936ca9e23d42a160 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Sun, 3 Apr 2016 01:34:39 +0200 Subject: [PATCH 245/250] add missing registration after f0ac2a8a015100e2472501c560d26f073b9a33c7 (cherry picked from commit 9087fe9583fe5035b4dea1d0e97ee6b0d493da74) Signed-off-by: Matus Kral --- xbmc/interfaces/builtins/Builtins.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xbmc/interfaces/builtins/Builtins.cpp b/xbmc/interfaces/builtins/Builtins.cpp index 5d8bbbe..260d81e 100644 --- a/xbmc/interfaces/builtins/Builtins.cpp +++ b/xbmc/interfaces/builtins/Builtins.cpp @@ -67,6 +67,10 @@ CBuiltins::CBuiltins() RegisterCommands(); RegisterCommands(); +#if defined(HAVE_LIBCEC) + RegisterCommands(); +#endif + #if defined(TARGET_ANDROID) RegisterCommands(); #endif -- 2.7.1 From 1a1346891cba6002be6a23709b0a42b1361b6ded Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 6 Apr 2016 18:40:34 +0200 Subject: [PATCH 246/250] emit xbmc-loaded also on DB upgrade1 --- xbmc/dbwrappers/Database.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xbmc/dbwrappers/Database.cpp b/xbmc/dbwrappers/Database.cpp index 8787a63..c2314ef 100644 --- a/xbmc/dbwrappers/Database.cpp +++ b/xbmc/dbwrappers/Database.cpp @@ -518,6 +518,7 @@ int CDatabase::GetDBVersion() bool CDatabase::UpdateVersion(const std::string &dbName) { int version = GetDBVersion(); + if (version < GetMinSchemaVersion()) { CLog::Log(LOGERROR, "Can't update database %s from version %i - it's too old", dbName.c_str(), version); @@ -525,6 +526,9 @@ bool CDatabase::UpdateVersion(const std::string &dbName) } else if (version < GetSchemaVersion()) { + CLog::Log(LOGNOTICE, "XBian: notifying Upstart (doing DB upgrades)"); + system("sudo /sbin/start -n -q xbmc-loaded"); + CLog::Log(LOGNOTICE, "Attempting to update the database %s from version %i to %i", dbName.c_str(), version, GetSchemaVersion()); bool success = true; BeginTransaction(); -- 2.7.1 From 8e5a1313a2eaa25eb8ebff2382acff1518967382 Mon Sep 17 00:00:00 2001 From: Matus Kral Date: Wed, 6 Apr 2016 19:04:59 +0200 Subject: [PATCH 247/250] remove obsolete Finish() method --- xbmc/cores/dvdplayer/DVDAudio.cpp | 7 ------- xbmc/cores/dvdplayer/DVDAudio.h | 1 - xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 1 - 3 files changed, 9 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDAudio.cpp b/xbmc/cores/dvdplayer/DVDAudio.cpp index 4d22e1b..7d3a833 100644 --- a/xbmc/cores/dvdplayer/DVDAudio.cpp +++ b/xbmc/cores/dvdplayer/DVDAudio.cpp @@ -145,13 +145,6 @@ unsigned int CDVDAudio::AddPackets(const DVDAudioFrame &audioframe) return total - frames; } -void CDVDAudio::Finish() -{ - CSingleLock lock (m_critSection); - if (!m_pAudioStream) - return; -} - void CDVDAudio::Drain() { CSingleLock lock (m_critSection); diff --git a/xbmc/cores/dvdplayer/DVDAudio.h b/xbmc/cores/dvdplayer/DVDAudio.h index 16c26b2..b5feb31 100644 --- a/xbmc/cores/dvdplayer/DVDAudio.h +++ b/xbmc/cores/dvdplayer/DVDAudio.h @@ -58,7 +58,6 @@ public: double GetCacheTime(); // returns total amount of data cached in audio output at this time double GetCacheTotal(); // returns total amount the audio device can buffer void Flush(); - void Finish(); void Drain(); void SetSpeed(int iSpeed); diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp index 20e1c00..e6d556d 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp @@ -409,7 +409,6 @@ int CDVDPlayerAudio::DecodeFrame(DVDAudioFrame &audioframe) else if (pMsg->IsType(CDVDMsg::GENERAL_EOF)) { CLog::Log(LOGDEBUG, "CDVDPlayerAudio - CDVDMsg::GENERAL_EOF"); - m_dvdAudio.Finish(); } else if (pMsg->IsType(CDVDMsg::GENERAL_DELAY)) { -- 2.7.1 From 9aacdda3dbb7fcdbaf07d806af94365bcd976090 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 8 Mar 2014 15:36:06 +0000 Subject: [PATCH 248/250] Hack: force it to be recognised as IEC958 capable to enable passthrough options --- xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp index 6910b26..23ca7db 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp @@ -1338,6 +1338,10 @@ void CAESinkALSA::EnumerateDevice(AEDeviceInfoList &list, const std::string &dev if (snd_card_get_name(cardNr, &cardName) == 0) info.m_displayName = cardName; + // hack: hifiberry digi doesn't correctly report as iec958 device. Needs fixing in kernel driver + if (info.m_displayName == "snd_rpi_hifiberry_digi") + info.m_deviceType = AE_DEVTYPE_IEC958; + if (info.m_deviceType == AE_DEVTYPE_HDMI && info.m_displayName.size() > 5 && info.m_displayName.substr(info.m_displayName.size()-5) == " HDMI") { -- 2.7.1 From 4bc9aad1fb4154112e8d887fa405bde472960390 Mon Sep 17 00:00:00 2001 From: mkreisl Date: Wed, 9 Mar 2016 16:41:55 +0100 Subject: [PATCH 249/250] Speex audio support added --- tools/depends/target/ffmpeg/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile index 823f9c5..1a22085 100644 --- a/tools/depends/target/ffmpeg/Makefile +++ b/tools/depends/target/ffmpeg/Makefile @@ -26,7 +26,7 @@ ffmpg_config += --enable-muxer=asf --enable-muxer=ipod ffmpg_config += --enable-encoder=ac3 --enable-encoder=aac ffmpg_config += --enable-encoder=wmav2 --enable-protocol=http ffmpg_config += --pkg-config=/usr/bin/pkg-config -ffmpg_config += --enable-gnutls +ffmpg_config += --enable-gnutls --enable-libspeex ifeq ($(CROSS_COMPILING), yes) ffmpg_config += --arch=$(CPU) --enable-cross-compile -- 2.7.1 From 4bc43b5c1c2e3583e0bda242970b7b94bd757cfd Mon Sep 17 00:00:00 2001 From: mkreisl Date: Fri, 11 Mar 2016 23:32:57 +0100 Subject: [PATCH 250/250] Revert "DVDPlayer: also don't force ffmpeg as decoder for .iso when compiled for IMX" This reverts commit 3628b47f46b03fd99f42b6a23f3db9316a1fc5c9. Kodi crash for RPi and IMX when playing DVD --- xbmc/cores/dvdplayer/DVDPlayer.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp index 2093f46..4ffe33a 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -3501,9 +3501,7 @@ bool CDVDPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset) hint.aspect = aspect; hint.forced_aspect = true; } -#if !defined(TARGET_RASPBERRY_PI) && !defined(HAS_IMXVPU) hint.software = true; -#endif } else if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER)) { -- 2.7.1