Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
3bd2228d
Commit
3bd2228d
authored
Aug 06, 2017
by
Marton Balint
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ffplay: add support for more SDL pixel formats when rendering video
Signed-off-by:
Marton Balint
<
cus@passwd.hu
>
parent
7004ac5e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
82 additions
and
32 deletions
+82
-32
ffplay.c
ffplay.c
+82
-32
No files found.
ffplay.c
View file @
3bd2228d
...
...
@@ -362,6 +362,32 @@ static AVPacket flush_pkt;
static
SDL_Window
*
window
;
static
SDL_Renderer
*
renderer
;
static
const
struct
TextureFormatEntry
{
enum
AVPixelFormat
format
;
int
texture_fmt
;
}
sdl_texture_format_map
[]
=
{
{
AV_PIX_FMT_RGB8
,
SDL_PIXELFORMAT_RGB332
},
{
AV_PIX_FMT_RGB444
,
SDL_PIXELFORMAT_RGB444
},
{
AV_PIX_FMT_RGB555
,
SDL_PIXELFORMAT_RGB555
},
{
AV_PIX_FMT_BGR555
,
SDL_PIXELFORMAT_BGR555
},
{
AV_PIX_FMT_RGB565
,
SDL_PIXELFORMAT_RGB565
},
{
AV_PIX_FMT_BGR565
,
SDL_PIXELFORMAT_BGR565
},
{
AV_PIX_FMT_RGB24
,
SDL_PIXELFORMAT_RGB24
},
{
AV_PIX_FMT_BGR24
,
SDL_PIXELFORMAT_BGR24
},
{
AV_PIX_FMT_0RGB32
,
SDL_PIXELFORMAT_RGB888
},
{
AV_PIX_FMT_0BGR32
,
SDL_PIXELFORMAT_BGR888
},
{
AV_PIX_FMT_NE
(
RGB0
,
0
BGR
),
SDL_PIXELFORMAT_RGBX8888
},
{
AV_PIX_FMT_NE
(
BGR0
,
0
RGB
),
SDL_PIXELFORMAT_BGRX8888
},
{
AV_PIX_FMT_RGB32
,
SDL_PIXELFORMAT_ARGB8888
},
{
AV_PIX_FMT_RGB32_1
,
SDL_PIXELFORMAT_RGBA8888
},
{
AV_PIX_FMT_BGR32
,
SDL_PIXELFORMAT_ABGR8888
},
{
AV_PIX_FMT_BGR32_1
,
SDL_PIXELFORMAT_BGRA8888
},
{
AV_PIX_FMT_YUV420P
,
SDL_PIXELFORMAT_IYUV
},
{
AV_PIX_FMT_YUYV422
,
SDL_PIXELFORMAT_YUY2
},
{
AV_PIX_FMT_UYVY422
,
SDL_PIXELFORMAT_UYVY
},
{
AV_PIX_FMT_NONE
,
SDL_PIXELFORMAT_UNKNOWN
},
};
#if CONFIG_AVFILTER
static
int
opt_add_vfilter
(
void
*
optctx
,
const
char
*
opt
,
const
char
*
arg
)
{
...
...
@@ -820,6 +846,7 @@ static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_wid
memset
(
pixels
,
0
,
pitch
*
new_height
);
SDL_UnlockTexture
(
*
texture
);
}
av_log
(
NULL
,
AV_LOG_VERBOSE
,
"Created %dx%d texture with %s.
\n
"
,
new_width
,
new_height
,
SDL_GetPixelFormatName
(
new_format
));
}
return
0
;
}
...
...
@@ -855,31 +882,33 @@ static void calculate_display_rect(SDL_Rect *rect,
rect
->
h
=
FFMAX
(
height
,
1
);
}
static
int
upload_texture
(
SDL_Texture
*
tex
,
AVFrame
*
frame
,
struct
SwsContext
**
img_convert_ctx
)
{
static
void
get_sdl_pix_fmt_and_blendmode
(
int
format
,
Uint32
*
sdl_pix_fmt
,
SDL_BlendMode
*
sdl_blendmode
)
{
int
i
;
*
sdl_blendmode
=
SDL_BLENDMODE_NONE
;
*
sdl_pix_fmt
=
SDL_PIXELFORMAT_UNKNOWN
;
if
(
format
==
AV_PIX_FMT_RGB32
||
format
==
AV_PIX_FMT_RGB32_1
||
format
==
AV_PIX_FMT_BGR32
||
format
==
AV_PIX_FMT_BGR32_1
)
*
sdl_blendmode
=
SDL_BLENDMODE_BLEND
;
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
sdl_texture_format_map
)
-
1
;
i
++
)
{
if
(
format
==
sdl_texture_format_map
[
i
].
format
)
{
*
sdl_pix_fmt
=
sdl_texture_format_map
[
i
].
texture_fmt
;
return
;
}
}
}
static
int
upload_texture
(
SDL_Texture
**
tex
,
AVFrame
*
frame
,
struct
SwsContext
**
img_convert_ctx
)
{
int
ret
=
0
;
switch
(
frame
->
format
)
{
case
AV_PIX_FMT_YUV420P
:
if
(
frame
->
linesize
[
0
]
>
0
&&
frame
->
linesize
[
1
]
>
0
&&
frame
->
linesize
[
2
]
>
0
)
{
ret
=
SDL_UpdateYUVTexture
(
tex
,
NULL
,
frame
->
data
[
0
],
frame
->
linesize
[
0
],
frame
->
data
[
1
],
frame
->
linesize
[
1
],
frame
->
data
[
2
],
frame
->
linesize
[
2
]);
}
else
if
(
frame
->
linesize
[
0
]
<
0
&&
frame
->
linesize
[
1
]
<
0
&&
frame
->
linesize
[
2
]
<
0
)
{
ret
=
SDL_UpdateYUVTexture
(
tex
,
NULL
,
frame
->
data
[
0
]
+
frame
->
linesize
[
0
]
*
(
frame
->
height
-
1
),
-
frame
->
linesize
[
0
],
frame
->
data
[
1
]
+
frame
->
linesize
[
1
]
*
(
AV_CEIL_RSHIFT
(
frame
->
height
,
1
)
-
1
),
-
frame
->
linesize
[
1
],
frame
->
data
[
2
]
+
frame
->
linesize
[
2
]
*
(
AV_CEIL_RSHIFT
(
frame
->
height
,
1
)
-
1
),
-
frame
->
linesize
[
2
]);
}
else
{
av_log
(
NULL
,
AV_LOG_ERROR
,
"Mixed negative and positive linesizes are not supported.
\n
"
);
return
-
1
;
}
break
;
case
AV_PIX_FMT_BGRA
:
if
(
frame
->
linesize
[
0
]
<
0
)
{
ret
=
SDL_UpdateTexture
(
tex
,
NULL
,
frame
->
data
[
0
]
+
frame
->
linesize
[
0
]
*
(
frame
->
height
-
1
),
-
frame
->
linesize
[
0
]);
}
else
{
ret
=
SDL_UpdateTexture
(
tex
,
NULL
,
frame
->
data
[
0
],
frame
->
linesize
[
0
]);
}
break
;
default:
Uint32
sdl_pix_fmt
;
SDL_BlendMode
sdl_blendmode
;
get_sdl_pix_fmt_and_blendmode
(
frame
->
format
,
&
sdl_pix_fmt
,
&
sdl_blendmode
);
if
(
realloc_texture
(
tex
,
sdl_pix_fmt
==
SDL_PIXELFORMAT_UNKNOWN
?
SDL_PIXELFORMAT_ARGB8888
:
sdl_pix_fmt
,
frame
->
width
,
frame
->
height
,
sdl_blendmode
,
0
)
<
0
)
return
-
1
;
switch
(
sdl_pix_fmt
)
{
case
SDL_PIXELFORMAT_UNKNOWN
:
/* This should only happen if we are not using avfilter... */
*
img_convert_ctx
=
sws_getCachedContext
(
*
img_convert_ctx
,
frame
->
width
,
frame
->
height
,
frame
->
format
,
frame
->
width
,
frame
->
height
,
...
...
@@ -887,16 +916,37 @@ static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **
if
(
*
img_convert_ctx
!=
NULL
)
{
uint8_t
*
pixels
[
4
];
int
pitch
[
4
];
if
(
!
SDL_LockTexture
(
tex
,
NULL
,
(
void
**
)
pixels
,
pitch
))
{
if
(
!
SDL_LockTexture
(
*
tex
,
NULL
,
(
void
**
)
pixels
,
pitch
))
{
sws_scale
(
*
img_convert_ctx
,
(
const
uint8_t
*
const
*
)
frame
->
data
,
frame
->
linesize
,
0
,
frame
->
height
,
pixels
,
pitch
);
SDL_UnlockTexture
(
tex
);
SDL_UnlockTexture
(
*
tex
);
}
}
else
{
av_log
(
NULL
,
AV_LOG_FATAL
,
"Cannot initialize the conversion context
\n
"
);
ret
=
-
1
;
}
break
;
case
SDL_PIXELFORMAT_IYUV
:
if
(
frame
->
linesize
[
0
]
>
0
&&
frame
->
linesize
[
1
]
>
0
&&
frame
->
linesize
[
2
]
>
0
)
{
ret
=
SDL_UpdateYUVTexture
(
*
tex
,
NULL
,
frame
->
data
[
0
],
frame
->
linesize
[
0
],
frame
->
data
[
1
],
frame
->
linesize
[
1
],
frame
->
data
[
2
],
frame
->
linesize
[
2
]);
}
else
if
(
frame
->
linesize
[
0
]
<
0
&&
frame
->
linesize
[
1
]
<
0
&&
frame
->
linesize
[
2
]
<
0
)
{
ret
=
SDL_UpdateYUVTexture
(
*
tex
,
NULL
,
frame
->
data
[
0
]
+
frame
->
linesize
[
0
]
*
(
frame
->
height
-
1
),
-
frame
->
linesize
[
0
],
frame
->
data
[
1
]
+
frame
->
linesize
[
1
]
*
(
AV_CEIL_RSHIFT
(
frame
->
height
,
1
)
-
1
),
-
frame
->
linesize
[
1
],
frame
->
data
[
2
]
+
frame
->
linesize
[
2
]
*
(
AV_CEIL_RSHIFT
(
frame
->
height
,
1
)
-
1
),
-
frame
->
linesize
[
2
]);
}
else
{
av_log
(
NULL
,
AV_LOG_ERROR
,
"Mixed negative and positive linesizes are not supported.
\n
"
);
return
-
1
;
}
break
;
default:
if
(
frame
->
linesize
[
0
]
<
0
)
{
ret
=
SDL_UpdateTexture
(
*
tex
,
NULL
,
frame
->
data
[
0
]
+
frame
->
linesize
[
0
]
*
(
frame
->
height
-
1
),
-
frame
->
linesize
[
0
]);
}
else
{
ret
=
SDL_UpdateTexture
(
*
tex
,
NULL
,
frame
->
data
[
0
],
frame
->
linesize
[
0
]);
}
break
;
}
return
ret
;
}
...
...
@@ -956,11 +1006,7 @@ static void video_image_display(VideoState *is)
calculate_display_rect
(
&
rect
,
is
->
xleft
,
is
->
ytop
,
is
->
width
,
is
->
height
,
vp
->
width
,
vp
->
height
,
vp
->
sar
);
if
(
!
vp
->
uploaded
)
{
int
sdl_pix_fmt
=
vp
->
frame
->
format
==
AV_PIX_FMT_YUV420P
?
SDL_PIXELFORMAT_YV12
:
SDL_PIXELFORMAT_ARGB8888
;
SDL_BlendMode
sdl_blendmode
=
vp
->
frame
->
format
==
AV_PIX_FMT_YUV420P
?
SDL_BLENDMODE_NONE
:
SDL_BLENDMODE_BLEND
;
if
(
realloc_texture
(
&
is
->
vid_texture
,
sdl_pix_fmt
,
vp
->
frame
->
width
,
vp
->
frame
->
height
,
sdl_blendmode
,
0
)
<
0
)
return
;
if
(
upload_texture
(
is
->
vid_texture
,
vp
->
frame
,
&
is
->
img_convert_ctx
)
<
0
)
if
(
upload_texture
(
&
is
->
vid_texture
,
vp
->
frame
,
&
is
->
img_convert_ctx
)
<
0
)
return
;
vp
->
uploaded
=
1
;
vp
->
flip_v
=
vp
->
frame
->
linesize
[
0
]
<
0
;
...
...
@@ -1796,7 +1842,7 @@ fail:
static
int
configure_video_filters
(
AVFilterGraph
*
graph
,
VideoState
*
is
,
const
char
*
vfilters
,
AVFrame
*
frame
)
{
static
const
enum
AVPixelFormat
pix_fmts
[]
=
{
AV_PIX_FMT_YUV420P
,
AV_PIX_FMT_BGRA
,
AV_PIX_FMT_NONE
}
;
enum
AVPixelFormat
pix_fmts
[
FF_ARRAY_ELEMS
(
sdl_texture_format_map
)]
;
char
sws_flags_str
[
512
]
=
""
;
char
buffersrc_args
[
256
];
int
ret
;
...
...
@@ -1804,6 +1850,10 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
AVCodecParameters
*
codecpar
=
is
->
video_st
->
codecpar
;
AVRational
fr
=
av_guess_frame_rate
(
is
->
ic
,
is
->
video_st
,
NULL
);
AVDictionaryEntry
*
e
=
NULL
;
int
i
;
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
pix_fmts
);
i
++
)
pix_fmts
[
i
]
=
sdl_texture_format_map
[
i
].
format
;
while
((
e
=
av_dict_get
(
sws_dict
,
""
,
e
,
AV_DICT_IGNORE_SUFFIX
)))
{
if
(
!
strcmp
(
e
->
key
,
"sws_flags"
))
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment