mirror of
https://github.com/morgan9e/UxPlay
synced 2026-04-14 00:04:13 +09:00
add the -f videoflip option, modeled on flip and rotate in RPiPlay
This commit is contained in:
@@ -4,13 +4,16 @@ project(uxplay)
|
||||
|
||||
set (CMAKE_CXX_STANDARD 11)
|
||||
|
||||
add_definitions(-DAVAHI_COMPAT_NOWARN)
|
||||
|
||||
if (ZOOMFIX)
|
||||
add_definitions(-DX_DISPLAY_FIX)
|
||||
find_package(X11 REQUIRED)
|
||||
link_libraries(${X11_LIBRARIES})
|
||||
include_directories(${X11_INCLUDE_DIR})
|
||||
# link_directories(${X11_LIBRARIES})
|
||||
endif (ZOOMFIX)
|
||||
|
||||
add_definitions(-DAVAHI_COMPAT_NOWARN)
|
||||
|
||||
add_subdirectory(lib/llhttp)
|
||||
add_subdirectory(lib/playfair)
|
||||
@@ -20,5 +23,5 @@ add_subdirectory(renderers)
|
||||
add_executable( uxplay uxplay.cpp)
|
||||
target_link_libraries ( uxplay renderers airplay ${X11_LIBRARIES})
|
||||
|
||||
install(PROGRAMS uxplay DESTINATION bin)
|
||||
install(TARGETS uxplay RUNTIME DESTINATION bin)
|
||||
|
||||
|
||||
@@ -33,10 +33,18 @@ extern "C" {
|
||||
#include "../lib/logger.h"
|
||||
#include "../lib/raop_ntp.h"
|
||||
|
||||
typedef enum videoflip_e {
|
||||
NONE,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
INVERT,
|
||||
VFLIP,
|
||||
HFLIP,
|
||||
} videoflip_t;
|
||||
|
||||
typedef struct video_renderer_s video_renderer_t;
|
||||
|
||||
video_renderer_t *video_renderer_init(logger_t *logger, const char *server_name);
|
||||
video_renderer_t *video_renderer_init(logger_t *logger, const char *server_name, videoflip_t videoflip);
|
||||
void video_renderer_start(video_renderer_t *renderer);
|
||||
void video_renderer_render_buffer(video_renderer_t *renderer, raop_ntp_t *ntp, unsigned char* data, int data_len, uint64_t pts, int type);
|
||||
void video_renderer_flush(video_renderer_t *renderer);
|
||||
|
||||
@@ -53,7 +53,7 @@ static gboolean check_plugins (void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
video_renderer_t *video_renderer_init(logger_t *logger, const char *server_name) {
|
||||
video_renderer_t *video_renderer_init(logger_t *logger, const char *server_name, videoflip_t videoflip) {
|
||||
video_renderer_t *renderer;
|
||||
GError *error = NULL;
|
||||
|
||||
@@ -71,8 +71,29 @@ video_renderer_t *video_renderer_init(logger_t *logger, const char *server_name)
|
||||
|
||||
assert(check_plugins ());
|
||||
|
||||
renderer->pipeline = gst_parse_launch("appsrc name=video_source stream-type=0 format=GST_FORMAT_TIME is-live=true !"
|
||||
"queue ! decodebin ! videoconvert ! autovideosink name=video_sink sync=false", &error);
|
||||
GString *launch = g_string_new("appsrc name=video_source stream-type=0 format=GST_FORMAT_TIME is-live=true !"
|
||||
"queue ! decodebin ! videoconvert ! ");
|
||||
|
||||
/* image transform */
|
||||
switch (videoflip) {
|
||||
case LEFT:
|
||||
g_string_append(launch, "videoflip method=counterclockwise ! ");
|
||||
break;
|
||||
case RIGHT:
|
||||
g_string_append(launch, "videoflip method=clockwise ! ");
|
||||
break;
|
||||
case INVERT:
|
||||
g_string_append(launch, "videoflip method=rotate-180 ! ");
|
||||
break;
|
||||
case HFLIP:
|
||||
g_string_append(launch, "videoflip method=horizontal-flip ! ");
|
||||
break;
|
||||
case VFLIP:
|
||||
g_string_append(launch, "videoflip method=vertical-flip ! ");
|
||||
}
|
||||
|
||||
g_string_append(launch, "autovideosink name=video_sink sync=false");
|
||||
renderer->pipeline = gst_parse_launch(launch->str, &error);
|
||||
g_assert (renderer->pipeline);
|
||||
|
||||
renderer->appsrc = gst_bin_get_by_name (GST_BIN (renderer->pipeline), "video_source");
|
||||
|
||||
59
uxplay.cpp
59
uxplay.cpp
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
int start_server(std::vector<char> hw_addr, std::string name, unsigned short display_size[2],
|
||||
unsigned short tcp[2], unsigned short udp[3],
|
||||
unsigned short tcp[2], unsigned short udp[3], videoflip_t videoflip,
|
||||
bool use_audio, bool debug_log);
|
||||
|
||||
int stop_server();
|
||||
@@ -120,8 +120,9 @@ void print_info(char *name) {
|
||||
printf("UxPlay %s: An open-source AirPlay mirroring server based on RPiPlay\n", VERSION);
|
||||
printf("Usage: %s [-n name] [-s wxh] [-p [n]]\n", name);
|
||||
printf("Options:\n");
|
||||
printf("-n name Specify the network name of the AirPlay server\n");
|
||||
printf("-s wxh Set display size: width w height h default 1920x1080\n");
|
||||
printf("-n name Specify the network name of the AirPlay server\n");
|
||||
printf("-s wxh Set display size: width w height h default 1920x1080\n");
|
||||
printf("-f {H|V|R|L|I} horizontal/vertical flip; rotate 90R/90L/180 deg\n");
|
||||
printf("-p n Use fixed UDP+TCP network ports n:n+1:n+2 > 1023\n");
|
||||
printf("-p Use legacy UDP 6000:6001:7011 TCP 7000:7001:7100\n");
|
||||
printf("-r use random MAC address (use for concurrent UxPlay's)\n");
|
||||
@@ -159,6 +160,33 @@ bool get_lowest_port(char *str, unsigned short *n) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_videoflip(char *str, videoflip_t *videoflip) {
|
||||
char c = str[0];
|
||||
printf(" %c |%s| %d\n",c, str, strlen(str));
|
||||
|
||||
if(strlen(str) > 1) return false;
|
||||
printf(" %c |%s| %d\n",c, str, strlen(str));
|
||||
switch (c) {
|
||||
case 'L':
|
||||
*videoflip = LEFT;
|
||||
break;
|
||||
case 'R':
|
||||
*videoflip = RIGHT;
|
||||
break;
|
||||
case 'I':
|
||||
*videoflip = INVERT;
|
||||
break;
|
||||
case 'H':
|
||||
*videoflip = HFLIP;
|
||||
break;
|
||||
case 'V':
|
||||
*videoflip = VFLIP;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
int main(int argc, char *argv[]) {
|
||||
init_signals();
|
||||
|
||||
@@ -169,7 +197,8 @@ int main(int argc, char *argv[]) {
|
||||
bool debug_log = DEFAULT_DEBUG_LOG;
|
||||
unsigned short display_size[2] = { (unsigned short) DEFAULT_DISPLAY_WIDTH, (unsigned short) DEFAULT_DISPLAY_HEIGHT };
|
||||
unsigned short tcp[2] = {0}, udp[3] = {0};
|
||||
|
||||
videoflip_t videoflip = NONE;
|
||||
|
||||
#ifdef AVAHI_COMPAT_NOWARN
|
||||
//suppress avahi_compat nag message
|
||||
char avahi_compat_nowarn[] = "AVAHI_COMPAT_NOWARN==1";
|
||||
@@ -187,12 +216,21 @@ int main(int argc, char *argv[]) {
|
||||
fprintf(stderr,"invalid \"-s\" had no argument\n");
|
||||
exit(1);
|
||||
}
|
||||
std::string value(argv[++i]);
|
||||
std::string value(argv[++i]);
|
||||
if (!get_display_size(argv[i], &display_size[0], &display_size[1])) {
|
||||
fprintf(stderr, "invalid \"-s %s\"; default is \"-s 1920x1080\" (< 5 digits)\n",
|
||||
value.c_str());
|
||||
exit(1);
|
||||
}
|
||||
} else if (arg == "-f") {
|
||||
if (i == argc - 1 || argv[i + 1][0] == '-') {
|
||||
fprintf(stderr,"invalid \"f\" had no argument\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!get_videoflip(argv[++i], &videoflip)) {
|
||||
fprintf(stderr,"invalid \"-f %s\" , unknown videoflip type\n",argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
} else if (arg == "-p") {
|
||||
if (i == argc - 1 || argv[i + 1][0] == '-') {
|
||||
tcp[0] = 7100; tcp[1] = 7000;
|
||||
@@ -220,7 +258,7 @@ int main(int argc, char *argv[]) {
|
||||
print_info(argv[0]);
|
||||
exit(0);
|
||||
} else {
|
||||
LOGI("unknown option %s, skipping\n",argv[i]);
|
||||
LOGI("unknown option %s, skipping\n",argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +275,8 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
parse_hw_addr(mac_address, server_hw_addr);
|
||||
|
||||
if (start_server(server_hw_addr, server_name, display_size, tcp, udp, use_audio, debug_log) != 0) {
|
||||
if (start_server(server_hw_addr, server_name, display_size, tcp, udp, videoflip,
|
||||
use_audio, debug_log) != 0) {
|
||||
return 1;
|
||||
}
|
||||
running = true;
|
||||
@@ -307,7 +346,7 @@ extern "C" void log_callback(void *cls, int level, const char *msg) {
|
||||
}
|
||||
|
||||
int start_server(std::vector<char> hw_addr, std::string name, unsigned short display_size[2],
|
||||
unsigned short tcp[2], unsigned short udp[3],
|
||||
unsigned short tcp[2], unsigned short udp[3], videoflip_t videoflip,
|
||||
bool use_audio, bool debug_log) {
|
||||
raop_callbacks_t raop_cbs;
|
||||
memset(&raop_cbs, 0, sizeof(raop_cbs));
|
||||
@@ -332,7 +371,7 @@ int start_server(std::vector<char> hw_addr, std::string name, unsigned short dis
|
||||
logger_set_callback(render_logger, log_callback, NULL);
|
||||
logger_set_level(render_logger, debug_log ? LOGGER_DEBUG : LOGGER_INFO);
|
||||
|
||||
if ((video_renderer = video_renderer_init(render_logger, name.c_str())) == NULL) {
|
||||
if ((video_renderer = video_renderer_init(render_logger, name.c_str(), videoflip)) == NULL) {
|
||||
LOGE("Could not init video renderer");
|
||||
return -1;
|
||||
}
|
||||
@@ -351,7 +390,7 @@ int start_server(std::vector<char> hw_addr, std::string name, unsigned short dis
|
||||
/* write desired display pixel width, pixel height to raop (use 0 for default values) */
|
||||
raop_set_display_size(raop, display_size[0], display_size[1]);
|
||||
|
||||
/* network port selection (use value 0 for dynamic assignment) */
|
||||
/* network port selection (ports listed as "0" will dynamically assigned) */
|
||||
raop_set_tcp_ports(raop, tcp);
|
||||
raop_set_udp_ports(raop, udp);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user