Compare commits

..
Author SHA1 Message Date
Romain Vimont d500550212 Update audio recording documentation
Document how to record audio-only to .opus and .aac files.

PR #3978 <https://github.com/Genymobile/scrcpy/pull/3978>
2023-05-15 14:28:55 +02:00
Romain Vimont a166eee909 Upgrade FFmpeg build to 6.0-scrcpy-3
Use a build which includes the opus muxer, to support recording to .opus
files.

Refs <https://github.com/rom1v/scrcpy-deps/commits/6.0-scrcpy-3>
PR #3978 <https://github.com/Genymobile/scrcpy/pull/3978>
2023-05-15 14:28:53 +02:00
4 changed files with 26 additions and 158 deletions
+10 -108
View File
@@ -62,17 +62,11 @@ sc_display_init(struct sc_display *display, SDL_Window *window, bool mipmaps) {
LOGD("Trilinear filtering disabled (not an OpenGL renderer"); LOGD("Trilinear filtering disabled (not an OpenGL renderer");
} }
display->pending.flags = 0;
display->pending.frame = NULL;
return true; return true;
} }
void void
sc_display_destroy(struct sc_display *display) { sc_display_destroy(struct sc_display *display) {
if (display->pending.frame) {
av_frame_free(&display->pending.frame);
}
#ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE #ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE
SDL_GL_DeleteContext(display->gl_context); SDL_GL_DeleteContext(display->gl_context);
#endif #endif
@@ -90,7 +84,7 @@ sc_display_create_texture(struct sc_display *display,
SDL_TEXTUREACCESS_STREAMING, SDL_TEXTUREACCESS_STREAMING,
size.width, size.height); size.width, size.height);
if (!texture) { if (!texture) {
LOGD("Could not create texture: %s", SDL_GetError()); LOGE("Could not create texture: %s", SDL_GetError());
return NULL; return NULL;
} }
@@ -110,66 +104,8 @@ sc_display_create_texture(struct sc_display *display,
return texture; return texture;
} }
static inline void bool
sc_display_set_pending_size(struct sc_display *display, struct sc_size size) { sc_display_set_texture_size(struct sc_display *display, struct sc_size size) {
assert(!display->texture);
display->pending.size = size;
display->pending.flags |= SC_DISPLAY_PENDING_FLAG_SIZE;
}
static bool
sc_display_set_pending_frame(struct sc_display *display, const AVFrame *frame) {
if (!display->pending.frame) {
display->pending.frame = av_frame_alloc();
if (!display->pending.frame) {
LOG_OOM();
return false;
}
}
int r = av_frame_ref(display->pending.frame, frame);
if (r) {
LOGE("Could not ref frame: %d", r);
return false;
}
display->pending.flags |= SC_DISPLAY_PENDING_FLAG_FRAME;
return true;
}
static bool
sc_display_apply_pending(struct sc_display *display) {
if (display->pending.flags & SC_DISPLAY_PENDING_FLAG_SIZE) {
assert(!display->texture);
display->texture =
sc_display_create_texture(display, display->pending.size);
if (!display->texture) {
return false;
}
display->pending.flags &= ~SC_DISPLAY_PENDING_FLAG_SIZE;
}
if (display->pending.flags & SC_DISPLAY_PENDING_FLAG_FRAME) {
assert(display->pending.frame);
bool ok = sc_display_update_texture(display, display->pending.frame);
if (!ok) {
return false;
}
av_frame_unref(display->pending.frame);
display->pending.flags &= ~SC_DISPLAY_PENDING_FLAG_FRAME;
}
return true;
}
static bool
sc_display_set_texture_size_internal(struct sc_display *display,
struct sc_size size) {
assert(size.width && size.height);
if (display->texture) { if (display->texture) {
SDL_DestroyTexture(display->texture); SDL_DestroyTexture(display->texture);
} }
@@ -183,27 +119,14 @@ sc_display_set_texture_size_internal(struct sc_display *display,
return true; return true;
} }
enum sc_display_result bool
sc_display_set_texture_size(struct sc_display *display, struct sc_size size) { sc_display_update_texture(struct sc_display *display, const AVFrame *frame) {
bool ok = sc_display_set_texture_size_internal(display, size);
if (!ok) {
sc_display_set_pending_size(display, size);
return SC_DISPLAY_RESULT_PENDING;
}
return SC_DISPLAY_RESULT_OK;
}
static bool
sc_display_update_texture_internal(struct sc_display *display,
const AVFrame *frame) {
int ret = SDL_UpdateYUVTexture(display->texture, NULL, int ret = SDL_UpdateYUVTexture(display->texture, NULL,
frame->data[0], frame->linesize[0], frame->data[0], frame->linesize[0],
frame->data[1], frame->linesize[1], frame->data[1], frame->linesize[1],
frame->data[2], frame->linesize[2]); frame->data[2], frame->linesize[2]);
if (ret) { if (ret) {
LOGD("Could not update texture: %s", SDL_GetError()); LOGE("Could not update texture: %s", SDL_GetError());
return false; return false;
} }
@@ -216,32 +139,11 @@ sc_display_update_texture_internal(struct sc_display *display,
return true; return true;
} }
enum sc_display_result bool
sc_display_update_texture(struct sc_display *display, const AVFrame *frame) {
bool ok = sc_display_update_texture_internal(display, frame);
if (!ok) {
ok = sc_display_set_pending_frame(display, frame);
if (!ok) {
LOGE("Could not set pending frame");
return SC_DISPLAY_RESULT_ERROR;
}
return SC_DISPLAY_RESULT_PENDING;
}
return SC_DISPLAY_RESULT_OK;
}
enum sc_display_result
sc_display_render(struct sc_display *display, const SDL_Rect *geometry, sc_display_render(struct sc_display *display, const SDL_Rect *geometry,
unsigned rotation) { unsigned rotation) {
SDL_RenderClear(display->renderer); SDL_RenderClear(display->renderer);
bool ok = sc_display_apply_pending(display);
if (!ok) {
return SC_DISPLAY_RESULT_PENDING;
}
SDL_Renderer *renderer = display->renderer; SDL_Renderer *renderer = display->renderer;
SDL_Texture *texture = display->texture; SDL_Texture *texture = display->texture;
@@ -249,7 +151,7 @@ sc_display_render(struct sc_display *display, const SDL_Rect *geometry,
int ret = SDL_RenderCopy(renderer, texture, NULL, geometry); int ret = SDL_RenderCopy(renderer, texture, NULL, geometry);
if (ret) { if (ret) {
LOGE("Could not render texture: %s", SDL_GetError()); LOGE("Could not render texture: %s", SDL_GetError());
return SC_DISPLAY_RESULT_ERROR; return false;
} }
} else { } else {
// rotation in RenderCopyEx() is clockwise, while screen->rotation is // rotation in RenderCopyEx() is clockwise, while screen->rotation is
@@ -274,10 +176,10 @@ sc_display_render(struct sc_display *display, const SDL_Rect *geometry,
NULL, 0); NULL, 0);
if (ret) { if (ret) {
LOGE("Could not render texture: %s", SDL_GetError()); LOGE("Could not render texture: %s", SDL_GetError());
return SC_DISPLAY_RESULT_ERROR; return false;
} }
} }
SDL_RenderPresent(display->renderer); SDL_RenderPresent(display->renderer);
return SC_DISPLAY_RESULT_OK; return true;
} }
+3 -17
View File
@@ -24,20 +24,6 @@ struct sc_display {
#endif #endif
bool mipmaps; bool mipmaps;
struct {
#define SC_DISPLAY_PENDING_FLAG_SIZE 1
#define SC_DISPLAY_PENDING_FLAG_FRAME 2
int8_t flags;
struct sc_size size;
AVFrame *frame;
} pending;
};
enum sc_display_result {
SC_DISPLAY_RESULT_OK,
SC_DISPLAY_RESULT_PENDING,
SC_DISPLAY_RESULT_ERROR,
}; };
bool bool
@@ -46,13 +32,13 @@ sc_display_init(struct sc_display *display, SDL_Window *window, bool mipmaps);
void void
sc_display_destroy(struct sc_display *display); sc_display_destroy(struct sc_display *display);
enum sc_display_result bool
sc_display_set_texture_size(struct sc_display *display, struct sc_size size); sc_display_set_texture_size(struct sc_display *display, struct sc_size size);
enum sc_display_result bool
sc_display_update_texture(struct sc_display *display, const AVFrame *frame); sc_display_update_texture(struct sc_display *display, const AVFrame *frame);
enum sc_display_result bool
sc_display_render(struct sc_display *display, const SDL_Rect *geometry, sc_display_render(struct sc_display *display, const SDL_Rect *geometry,
unsigned rotation); unsigned rotation);
+13 -32
View File
@@ -56,7 +56,6 @@ static void
set_window_size(struct sc_screen *screen, struct sc_size new_size) { set_window_size(struct sc_screen *screen, struct sc_size new_size) {
assert(!screen->fullscreen); assert(!screen->fullscreen);
assert(!screen->maximized); assert(!screen->maximized);
assert(!screen->minimized);
SDL_SetWindowSize(screen->window, new_size.width, new_size.height); SDL_SetWindowSize(screen->window, new_size.width, new_size.height);
} }
@@ -250,9 +249,9 @@ sc_screen_render(struct sc_screen *screen, bool update_content_rect) {
sc_screen_update_content_rect(screen); sc_screen_update_content_rect(screen);
} }
enum sc_display_result res = bool ok = sc_display_render(&screen->display, &screen->rect,
sc_display_render(&screen->display, &screen->rect, screen->rotation); screen->rotation);
(void) res; // any error already logged (void) ok; // error already logged
} }
#if defined(__APPLE__) || defined(__WINDOWS__) #if defined(__APPLE__) || defined(__WINDOWS__)
@@ -360,7 +359,6 @@ sc_screen_init(struct sc_screen *screen,
screen->has_frame = false; screen->has_frame = false;
screen->fullscreen = false; screen->fullscreen = false;
screen->maximized = false; screen->maximized = false;
screen->minimized = false;
screen->mouse_capture_key_pressed = 0; screen->mouse_capture_key_pressed = 0;
screen->req.x = params->window_x; screen->req.x = params->window_x;
@@ -533,11 +531,11 @@ resize_for_content(struct sc_screen *screen, struct sc_size old_content_size,
static void static void
set_content_size(struct sc_screen *screen, struct sc_size new_content_size) { set_content_size(struct sc_screen *screen, struct sc_size new_content_size) {
if (!screen->fullscreen && !screen->maximized && !screen->minimized) { if (!screen->fullscreen && !screen->maximized) {
resize_for_content(screen, screen->content_size, new_content_size); resize_for_content(screen, screen->content_size, new_content_size);
} else if (!screen->resize_pending) { } else if (!screen->resize_pending) {
// Store the windowed size to be able to compute the optimal size once // Store the windowed size to be able to compute the optimal size once
// fullscreen/maximized/minimized are disabled // fullscreen and maximized are disabled
screen->windowed_content_size = screen->content_size; screen->windowed_content_size = screen->content_size;
screen->resize_pending = true; screen->resize_pending = true;
} }
@@ -549,7 +547,6 @@ static void
apply_pending_resize(struct sc_screen *screen) { apply_pending_resize(struct sc_screen *screen) {
assert(!screen->fullscreen); assert(!screen->fullscreen);
assert(!screen->maximized); assert(!screen->maximized);
assert(!screen->minimized);
if (screen->resize_pending) { if (screen->resize_pending) {
resize_for_content(screen, screen->windowed_content_size, resize_for_content(screen, screen->windowed_content_size,
screen->content_size); screen->content_size);
@@ -586,17 +583,15 @@ sc_screen_init_size(struct sc_screen *screen) {
get_rotated_size(screen->frame_size, screen->rotation); get_rotated_size(screen->frame_size, screen->rotation);
screen->content_size = content_size; screen->content_size = content_size;
enum sc_display_result res = return sc_display_set_texture_size(&screen->display, screen->frame_size);
sc_display_set_texture_size(&screen->display, screen->frame_size);
return res != SC_DISPLAY_RESULT_ERROR;
} }
// recreate the texture and resize the window if the frame size has changed // recreate the texture and resize the window if the frame size has changed
static enum sc_display_result static bool
prepare_for_frame(struct sc_screen *screen, struct sc_size new_frame_size) { prepare_for_frame(struct sc_screen *screen, struct sc_size new_frame_size) {
if (screen->frame_size.width == new_frame_size.width if (screen->frame_size.width == new_frame_size.width
&& screen->frame_size.height == new_frame_size.height) { && screen->frame_size.height == new_frame_size.height) {
return SC_DISPLAY_RESULT_OK; return true;
} }
// frame dimension changed // frame dimension changed
@@ -620,23 +615,13 @@ sc_screen_update_frame(struct sc_screen *screen) {
sc_fps_counter_add_rendered_frame(&screen->fps_counter); sc_fps_counter_add_rendered_frame(&screen->fps_counter);
struct sc_size new_frame_size = {frame->width, frame->height}; struct sc_size new_frame_size = {frame->width, frame->height};
enum sc_display_result res = prepare_for_frame(screen, new_frame_size); if (!prepare_for_frame(screen, new_frame_size)) {
if (res == SC_DISPLAY_RESULT_ERROR) {
return false; return false;
} }
if (res == SC_DISPLAY_RESULT_PENDING) {
// Not an error, but do not continue
return true;
}
res = sc_display_update_texture(&screen->display, frame); if (!sc_display_update_texture(&screen->display, frame)) {
if (res == SC_DISPLAY_RESULT_ERROR) {
return false; return false;
} }
if (res == SC_DISPLAY_RESULT_PENDING) {
// Not an error, but do not continue
return true;
}
if (!screen->has_frame) { if (!screen->has_frame) {
screen->has_frame = true; screen->has_frame = true;
@@ -662,7 +647,7 @@ sc_screen_switch_fullscreen(struct sc_screen *screen) {
} }
screen->fullscreen = !screen->fullscreen; screen->fullscreen = !screen->fullscreen;
if (!screen->fullscreen && !screen->maximized && !screen->minimized) { if (!screen->fullscreen && !screen->maximized) {
apply_pending_resize(screen); apply_pending_resize(screen);
} }
@@ -672,7 +657,7 @@ sc_screen_switch_fullscreen(struct sc_screen *screen) {
void void
sc_screen_resize_to_fit(struct sc_screen *screen) { sc_screen_resize_to_fit(struct sc_screen *screen) {
if (screen->fullscreen || screen->maximized || screen->minimized) { if (screen->fullscreen || screen->maximized) {
return; return;
} }
@@ -696,7 +681,7 @@ sc_screen_resize_to_fit(struct sc_screen *screen) {
void void
sc_screen_resize_to_pixel_perfect(struct sc_screen *screen) { sc_screen_resize_to_pixel_perfect(struct sc_screen *screen) {
if (screen->fullscreen || screen->minimized) { if (screen->fullscreen) {
return; return;
} }
@@ -753,9 +738,6 @@ sc_screen_handle_event(struct sc_screen *screen, const SDL_Event *event) {
case SDL_WINDOWEVENT_MAXIMIZED: case SDL_WINDOWEVENT_MAXIMIZED:
screen->maximized = true; screen->maximized = true;
break; break;
case SDL_WINDOWEVENT_MINIMIZED:
screen->minimized = true;
break;
case SDL_WINDOWEVENT_RESTORED: case SDL_WINDOWEVENT_RESTORED:
if (screen->fullscreen) { if (screen->fullscreen) {
// On Windows, in maximized+fullscreen, disabling // On Windows, in maximized+fullscreen, disabling
@@ -766,7 +748,6 @@ sc_screen_handle_event(struct sc_screen *screen, const SDL_Event *event) {
break; break;
} }
screen->maximized = false; screen->maximized = false;
screen->minimized = false;
apply_pending_resize(screen); apply_pending_resize(screen);
sc_screen_render(screen, true); sc_screen_render(screen, true);
break; break;
-1
View File
@@ -56,7 +56,6 @@ struct sc_screen {
bool has_frame; bool has_frame;
bool fullscreen; bool fullscreen;
bool maximized; bool maximized;
bool minimized;
// To enable/disable mouse capture, a mouse capture key (LALT, LGUI or // To enable/disable mouse capture, a mouse capture key (LALT, LGUI or
// RGUI) must be pressed. This variable tracks the pressed capture key. // RGUI) must be pressed. This variable tracks the pressed capture key.