Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
github_28344065
scrcpy
提交
4aa4f8de
S
scrcpy
项目概览
github_28344065
/
scrcpy
与 Fork 源项目一致
从无法访问的项目Fork
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
scrcpy
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4aa4f8de
编写于
12月 20, 2020
作者:
R
Romain Vimont
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[WIP] icon
上级
3514d372
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
275 addition
and
180 deletion
+275
-180
app/meson.build
app/meson.build
+4
-1
app/src/icon.c
app/src/icon.c
+247
-0
app/src/icon.h
app/src/icon.h
+16
-0
app/src/icon.xpm
app/src/icon.xpm
+0
-53
app/src/scrcpy.c
app/src/scrcpy.c
+0
-1
app/src/screen.c
app/src/screen.c
+3
-4
app/src/tiny_xpm.c
app/src/tiny_xpm.c
+0
-120
data/icon.png
data/icon.png
+0
-0
release.make
release.make
+2
-0
run
run
+3
-1
未找到文件。
app/meson.build
浏览文件 @
4aa4f8de
...
...
@@ -8,6 +8,7 @@ src = [
'src/device.c',
'src/device_msg.c',
'src/event_converter.c',
'src/icon.c',
'src/file_handler.c',
'src/fps_counter.c',
'src/input_manager.c',
...
...
@@ -18,7 +19,6 @@ src = [
'src/screen.c',
'src/server.c',
'src/stream.c',
'src/tiny_xpm.c',
'src/video_buffer.c',
'src/util/net.c',
'src/util/str_util.c'
...
...
@@ -136,6 +136,9 @@ executable('scrcpy', src,
c_args: [])
install_man('scrcpy.1')
install_data('../data/icon.png',
rename: 'scrcpy.png',
install_dir: 'share/icons/hicolor/512x512/apps')
### TESTS
...
...
app/src/icon.c
0 → 100644
浏览文件 @
4aa4f8de
#include "icon.h"
#include <assert.h>
#include <stdbool.h>
#include <libavformat/avformat.h>
#include <libavutil/pixdesc.h>
#include <libavutil/pixfmt.h>
#include "config.h"
#include "command.h"
#include "compat.h"
#include "util/log.h"
#include "util/str_util.h"
#define SCRCPY_PORTABLE_ICON_FILENAME "icon.png"
#define SCRCPY_DEFAULT_ICON_PATH PREFIX \
"/share/icons/hicolor/512x512/apps/scrcpy.png"
static
char
*
get_icon_path
(
void
)
{
#ifdef __WINDOWS__
const
wchar_t
*
icon_path_env
=
_wgetenv
(
L"SCRCPY_ICON_PATH"
);
#else
const
char
*
icon_path_env
=
getenv
(
"SCRCPY_ICON_PATH"
);
#endif
if
(
icon_path_env
)
{
// if the envvar is set, use it
#ifdef __WINDOWS__
char
*
icon_path
=
utf8_from_wide_char
(
icon_path_env
);
#else
char
*
icon_path
=
SDL_strdup
(
icon_path_env
);
#endif
if
(
!
icon_path
)
{
LOGE
(
"Could not allocate memory"
);
return
NULL
;
}
LOGD
(
"Using SCRCPY_ICON_PATH: %s"
,
icon_path
);
return
icon_path
;
}
#ifndef PORTABLE
char
*
icon_path
=
SDL_strdup
(
SCRCPY_DEFAULT_ICON_PATH
);
if
(
!
icon_path
)
{
LOGE
(
"Could not allocate memory"
);
return
NULL
;
}
#else
char
*
icon_path
=
get_local_file_path
(
SCRCPY_PORTABLE_ICON_FILENAME
);
if
(
!
icon_path
)
{
LOGE
(
"Could not get icon path"
);
return
NULL
;
}
#endif
return
icon_path
;
}
static
AVFrame
*
decode_image
(
const
char
*
path
)
{
AVFrame
*
result
=
NULL
;
AVFormatContext
*
ctx
=
avformat_alloc_context
();
if
(
!
ctx
)
{
LOGE
(
"Could not allocate image decoder context"
);
return
NULL
;
}
if
(
avformat_open_input
(
&
ctx
,
path
,
NULL
,
NULL
)
<
0
)
{
LOGE
(
"Could not open image codec"
);
goto
free_ctx
;
}
if
(
avformat_find_stream_info
(
ctx
,
NULL
)
<
0
)
{
LOGE
(
"Could not find image stream info"
);
goto
close_input
;
}
int
stream
=
av_find_best_stream
(
ctx
,
AVMEDIA_TYPE_VIDEO
,
-
1
,
-
1
,
NULL
,
0
);
if
(
stream
<
0
)
{
LOGE
(
"Could not find best image stream"
);
goto
close_input
;
}
#ifdef SCRCPY_LAVF_HAS_NEW_CODEC_PARAMS_API
AVCodecParameters
*
params
=
ctx
->
streams
[
stream
]
->
codecpar
;
AVCodec
*
codec
=
avcodec_find_decoder
(
params
->
codec_id
);
if
(
!
codec
)
{
LOGE
(
"Could not find image decoder"
);
goto
close_input
;
}
AVCodecContext
*
codec_ctx
=
avcodec_alloc_context3
(
codec
);
if
(
avcodec_parameters_to_context
(
codec_ctx
,
params
)
<
0
)
{
LOGE
(
"Could not fill codec context"
);
goto
free_codec_ctx
;
}
#else
AVCodecContext
*
codec_ctx
=
ctx
->
streams
[
stream
]
->
codec
;
AVCodec
*
codec
=
avcodec_find_decoder
(
codec_ctx
->
codec_id
);
if
(
!
codec
)
{
LOGE
(
"Could not find image decoder"
);
goto
close_input
;
}
#endif
if
(
avcodec_open2
(
codec_ctx
,
codec
,
NULL
)
<
0
)
{
LOGE
(
"Could not open image codec"
);
goto
free_codec_ctx
;
}
AVFrame
*
frame
=
av_frame_alloc
();
if
(
!
frame
)
{
LOGE
(
"Could not allocate frame"
);
goto
close_codec
;
}
AVPacket
packet
;
av_init_packet
(
&
packet
);
if
(
av_read_frame
(
ctx
,
&
packet
)
<
0
)
{
LOGE
(
"Could not read frame"
);
av_frame_free
(
&
frame
);
goto
close_input
;
}
#ifdef SCRCPY_LAVF_HAS_NEW_ENCODING_DECODING_API
int
ret
;
if
((
ret
=
avcodec_send_packet
(
codec_ctx
,
&
packet
))
<
0
)
{
LOGE
(
"Could not send icon packet: %d"
,
ret
);
av_frame_free
(
&
frame
);
goto
close_input
;
}
if
((
ret
=
avcodec_receive_frame
(
codec_ctx
,
frame
))
!=
0
)
{
LOGE
(
"Could not receive icon frame: %d"
,
ret
);
av_frame_free
(
&
frame
);
goto
close_input
;
}
#else
int
got_picture
;
int
len
=
avcodec_decode_video2
(
codec_ctx
,
frame
,
&
got_picture
,
&
packet
);
if
(
len
<
0
||
!
got_picture
)
{
LOGE
(
"Could not decode icon: %d"
,
len
);
av_frame_free
(
&
frame
);
goto
close_input
;
}
#endif
av_packet_unref
(
&
packet
);
result
=
frame
;
close_codec:
avcodec_close
(
codec_ctx
);
free_codec_ctx:
#ifdef SCRCPY_LAVF_HAS_NEW_CODEC_PARAMS_API
avcodec_free_context
(
&
codec_ctx
);
#endif
close_input:
avformat_close_input
(
&
ctx
);
free_ctx:
avformat_free_context
(
ctx
);
return
result
;
}
static
SDL_PixelFormatEnum
to_sdl_pixel_format
(
enum
AVPixelFormat
fmt
)
{
switch
(
fmt
)
{
case
AV_PIX_FMT_RGB24
:
return
SDL_PIXELFORMAT_RGB24
;
case
AV_PIX_FMT_BGR24
:
return
SDL_PIXELFORMAT_BGR24
;
case
AV_PIX_FMT_ARGB
:
return
SDL_PIXELFORMAT_ARGB32
;
case
AV_PIX_FMT_RGBA
:
return
SDL_PIXELFORMAT_RGBA32
;
case
AV_PIX_FMT_ABGR
:
return
SDL_PIXELFORMAT_ABGR32
;
case
AV_PIX_FMT_BGRA
:
return
SDL_PIXELFORMAT_BGRA32
;
case
AV_PIX_FMT_RGB565BE
:
return
SDL_PIXELFORMAT_RGB565
;
case
AV_PIX_FMT_RGB555BE
:
return
SDL_PIXELFORMAT_RGB555
;
case
AV_PIX_FMT_BGR565BE
:
return
SDL_PIXELFORMAT_BGR565
;
case
AV_PIX_FMT_BGR555BE
:
return
SDL_PIXELFORMAT_BGR555
;
case
AV_PIX_FMT_RGB444BE
:
return
SDL_PIXELFORMAT_RGB444
;
case
AV_PIX_FMT_BGR444BE
:
return
SDL_PIXELFORMAT_BGR444
;
default:
return
SDL_PIXELFORMAT_UNKNOWN
;
}
}
SDL_Surface
*
scrcpy_icon_load
()
{
char
*
icon_path
=
get_icon_path
();
assert
(
icon_path
);
AVFrame
*
frame
=
decode_image
(
icon_path
);
SDL_free
(
icon_path
);
if
(
!
frame
)
{
return
NULL
;
}
const
AVPixFmtDescriptor
*
desc
=
av_pix_fmt_desc_get
(
frame
->
format
);
if
(
!
desc
)
{
LOGE
(
"Could not get icon format descriptor"
);
goto
error
;
}
bool
is_packed_rgb
=
desc
->
flags
&
AV_PIX_FMT_FLAG_RGB
&&
!
(
desc
->
flags
&
AV_PIX_FMT_FLAG_PLANAR
);
if
(
!
is_packed_rgb
)
{
LOGE
(
"Could not load non-RGB icon"
);
goto
error
;
}
SDL_PixelFormatEnum
format
=
to_sdl_pixel_format
(
frame
->
format
);
if
(
format
==
SDL_PIXELFORMAT_UNKNOWN
)
{
LOGE
(
"Unsupported icon pixel format: %d"
,
frame
->
format
);
goto
error
;
}
int
bits_per_pixel
=
av_get_bits_per_pixel
(
desc
);
SDL_Surface
*
surface
=
SDL_CreateRGBSurfaceWithFormatFrom
(
frame
->
data
[
0
],
frame
->
width
,
frame
->
height
,
bits_per_pixel
,
frame
->
linesize
[
0
],
format
);
if
(
!
surface
)
{
LOGE
(
"Could not create icon surface"
);
goto
error
;
}
surface
->
userdata
=
frame
;
// frame owns the data
return
surface
;
error:
av_frame_free
(
&
frame
);
return
NULL
;
}
void
scrcpy_icon_destroy
(
SDL_Surface
*
icon
)
{
AVFrame
*
frame
=
icon
->
userdata
;
assert
(
frame
);
av_frame_free
(
&
frame
);
SDL_FreeSurface
(
icon
);
}
app/src/
tiny_xpm
.h
→
app/src/
icon
.h
浏览文件 @
4aa4f8de
#ifndef
TINYXPM
_H
#define
TINYXPM
_H
#ifndef
ICON
_H
#define
ICON
_H
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <libavformat/avformat.h>
#include "config.h"
SDL_Surface
*
read_xpm
(
char
*
xpm
[]);
scrcpy_icon_load
(
void
);
void
scrcpy_icon_destroy
(
SDL_Surface
*
icon
);
#endif
app/src/icon.xpm
已删除
100644 → 0
浏览文件 @
3514d372
/* XPM */
static char * icon_xpm[] = {
"48 48 2 1",
" c None",
". c #96C13E",
" .. .. ",
" ... ... ",
" ... ...... ... ",
" ................ ",
" .............. ",
" ................ ",
" .................. ",
" .................... ",
" ..... ........ ..... ",
" ..... ........ ..... ",
" ...................... ",
" ........................ ",
" ........................ ",
" ........................ ",
" ",
" ",
" .... ........................ .... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" ...... ........................ ...... ",
" .... ........................ .... ",
" ........................ ",
" ...................... ",
" ...... ...... ",
" ...... ...... ",
" ...... ...... ",
" ...... ...... ",
" ...... ...... ",
" ...... ...... ",
" ...... ...... ",
" ...... ...... ",
" ...... ...... ",
" .... .... "};
app/src/scrcpy.c
浏览文件 @
4aa4f8de
...
...
@@ -28,7 +28,6 @@
#include "screen.h"
#include "server.h"
#include "stream.h"
#include "tiny_xpm.h"
#include "video_buffer.h"
#include "util/lock.h"
#include "util/log.h"
...
...
app/src/screen.c
浏览文件 @
4aa4f8de
...
...
@@ -7,9 +7,8 @@
#include "config.h"
#include "common.h"
#include "compat.h"
#include "icon.
xpm
"
#include "icon.
h
"
#include "scrcpy.h"
#include "tiny_xpm.h"
#include "video_buffer.h"
#include "util/lock.h"
#include "util/log.h"
...
...
@@ -309,10 +308,10 @@ screen_init_rendering(struct screen *screen, const char *window_title,
LOGD
(
"Trilinear filtering disabled (not an OpenGL renderer)"
);
}
SDL_Surface
*
icon
=
read_xpm
(
icon_xpm
);
SDL_Surface
*
icon
=
scrcpy_icon_load
(
);
if
(
icon
)
{
SDL_SetWindowIcon
(
screen
->
window
,
icon
);
SDL_FreeSurface
(
icon
);
scrcpy_icon_destroy
(
icon
);
}
else
{
LOGW
(
"Could not load icon"
);
}
...
...
app/src/tiny_xpm.c
已删除
100644 → 0
浏览文件 @
3514d372
#include "tiny_xpm.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "util/log.h"
struct
index
{
char
c
;
uint32_t
color
;
};
static
bool
find_color
(
struct
index
*
index
,
int
len
,
char
c
,
uint32_t
*
color
)
{
// there are typically very few color, so it's ok to iterate over the array
for
(
int
i
=
0
;
i
<
len
;
++
i
)
{
if
(
index
[
i
].
c
==
c
)
{
*
color
=
index
[
i
].
color
;
return
true
;
}
}
*
color
=
0
;
return
false
;
}
// We encounter some problems with SDL2_image on MSYS2 (Windows),
// so here is our own XPM parsing not to depend on SDL_image.
//
// We do not hardcode the binary image to keep some flexibility to replace the
// icon easily (just by replacing icon.xpm).
//
// Parameter is not "const char *" because XPM formats are generally stored in a
// (non-const) "char *"
SDL_Surface
*
read_xpm
(
char
*
xpm
[])
{
#ifndef NDEBUG
// patch the XPM to change the icon color in debug mode
xpm
[
2
]
=
". c #CC00CC"
;
#endif
char
*
endptr
;
// *** No error handling, assume the XPM source is valid ***
// (it's in our source repo)
// Assertions are only checked in debug
int
width
=
strtol
(
xpm
[
0
],
&
endptr
,
10
);
int
height
=
strtol
(
endptr
+
1
,
&
endptr
,
10
);
int
colors
=
strtol
(
endptr
+
1
,
&
endptr
,
10
);
int
chars
=
strtol
(
endptr
+
1
,
&
endptr
,
10
);
// sanity checks
assert
(
0
<=
width
&&
width
<
256
);
assert
(
0
<=
height
&&
height
<
256
);
assert
(
0
<=
colors
&&
colors
<
256
);
assert
(
chars
==
1
);
// this implementation does not support more
(
void
)
chars
;
// init index
struct
index
index
[
colors
];
for
(
int
i
=
0
;
i
<
colors
;
++
i
)
{
const
char
*
line
=
xpm
[
1
+
i
];
index
[
i
].
c
=
line
[
0
];
assert
(
line
[
1
]
==
'\t'
);
assert
(
line
[
2
]
==
'c'
);
assert
(
line
[
3
]
==
' '
);
if
(
line
[
4
]
==
'#'
)
{
index
[
i
].
color
=
0xff000000
|
strtol
(
&
line
[
5
],
&
endptr
,
0x10
);
assert
(
*
endptr
==
'\0'
);
}
else
{
assert
(
!
strcmp
(
"None"
,
&
line
[
4
]));
index
[
i
].
color
=
0
;
}
}
// parse image
uint32_t
*
pixels
=
SDL_malloc
(
4
*
width
*
height
);
if
(
!
pixels
)
{
LOGE
(
"Could not allocate icon memory"
);
return
NULL
;
}
for
(
int
y
=
0
;
y
<
height
;
++
y
)
{
const
char
*
line
=
xpm
[
1
+
colors
+
y
];
for
(
int
x
=
0
;
x
<
width
;
++
x
)
{
char
c
=
line
[
x
];
uint32_t
color
;
bool
color_found
=
find_color
(
index
,
colors
,
c
,
&
color
);
assert
(
color_found
);
(
void
)
color_found
;
pixels
[
y
*
width
+
x
]
=
color
;
}
}
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
uint32_t
amask
=
0x000000ff
;
uint32_t
rmask
=
0x0000ff00
;
uint32_t
gmask
=
0x00ff0000
;
uint32_t
bmask
=
0xff000000
;
#else // little endian, like x86
uint32_t
amask
=
0xff000000
;
uint32_t
rmask
=
0x00ff0000
;
uint32_t
gmask
=
0x0000ff00
;
uint32_t
bmask
=
0x000000ff
;
#endif
SDL_Surface
*
surface
=
SDL_CreateRGBSurfaceFrom
(
pixels
,
width
,
height
,
32
,
4
*
width
,
rmask
,
gmask
,
bmask
,
amask
);
if
(
!
surface
)
{
LOGE
(
"Could not create icon surface"
);
return
NULL
;
}
// make the surface own the raw pixels
surface
->
flags
&=
~
SDL_PREALLOC
;
return
surface
;
}
data/icon.png
0 → 100644
浏览文件 @
4aa4f8de
6.4 KB
release.make
浏览文件 @
4aa4f8de
...
...
@@ -94,6 +94,7 @@ dist-win32: build-server build-win32
cp
"
$(WIN32_BUILD_DIR)
"
/app/scrcpy.exe
"
$(DIST)
/
$(WIN32_TARGET_DIR)
/"
cp
data/scrcpy-console.bat
"
$(DIST)
/
$(WIN32_TARGET_DIR)
"
cp
data/scrcpy-noconsole.vbs
"
$(DIST)
/
$(WIN32_TARGET_DIR)
"
cp
data/icon.png
"
$(DIST)
/
$(WIN32_TARGET_DIR)
"
cp
prebuilt-deps/ffmpeg-4.3.1-win32-shared/bin/avutil-56.dll
"
$(DIST)
/
$(WIN32_TARGET_DIR)
/"
cp
prebuilt-deps/ffmpeg-4.3.1-win32-shared/bin/avcodec-58.dll
"
$(DIST)
/
$(WIN32_TARGET_DIR)
/"
cp
prebuilt-deps/ffmpeg-4.3.1-win32-shared/bin/avformat-58.dll
"
$(DIST)
/
$(WIN32_TARGET_DIR)
/"
...
...
@@ -110,6 +111,7 @@ dist-win64: build-server build-win64
cp
"
$(WIN64_BUILD_DIR)
"
/app/scrcpy.exe
"
$(DIST)
/
$(WIN64_TARGET_DIR)
/"
cp
data/scrcpy-console.bat
"
$(DIST)
/
$(WIN64_TARGET_DIR)
"
cp
data/scrcpy-noconsole.vbs
"
$(DIST)
/
$(WIN64_TARGET_DIR)
"
cp
data/icon.png
"
$(DIST)
/
$(WIN64_TARGET_DIR)
"
cp
prebuilt-deps/ffmpeg-4.3.1-win64-shared/bin/avutil-56.dll
"
$(DIST)
/
$(WIN64_TARGET_DIR)
/"
cp
prebuilt-deps/ffmpeg-4.3.1-win64-shared/bin/avcodec-58.dll
"
$(DIST)
/
$(WIN64_TARGET_DIR)
/"
cp
prebuilt-deps/ffmpeg-4.3.1-win64-shared/bin/avformat-58.dll
"
$(DIST)
/
$(WIN64_TARGET_DIR)
/"
...
...
run
浏览文件 @
4aa4f8de
...
...
@@ -20,4 +20,6 @@ then
exit
1
fi
SCRCPY_SERVER_PATH
=
"
$BUILDDIR
/server/scrcpy-server"
"
$BUILDDIR
/app/scrcpy"
"
$@
"
SCRCPY_ICON_PATH
=
"data/icon.png"
\
SCRCPY_SERVER_PATH
=
"
$BUILDDIR
/server/scrcpy-server"
\
"
$BUILDDIR
/app/scrcpy"
"
$@
"
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录