Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
7a0dda44
Commit
7a0dda44
authored
Oct 18, 2011
by
Jean-Paul Saman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
VAAPI-XCB: XvBA decoding support
Reworked vlc_va_conn_t and vlc_va_t to integrate better.
parent
26cecc2f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
197 additions
and
29 deletions
+197
-29
modules/codec/avcodec/va.c
modules/codec/avcodec/va.c
+64
-1
modules/codec/avcodec/va.h
modules/codec/avcodec/va.h
+3
-5
modules/codec/avcodec/vaapi.c
modules/codec/avcodec/vaapi.c
+68
-16
modules/codec/avcodec/vaapi.h
modules/codec/avcodec/vaapi.h
+47
-1
modules/codec/avcodec/vaapi_x11.c
modules/codec/avcodec/vaapi_x11.c
+15
-6
No files found.
modules/codec/avcodec/va.c
View file @
7a0dda44
...
...
@@ -48,7 +48,7 @@
#ifdef HAVE_AVCODEC_VAAPI
/* Global VAAPI connection state */
static
vlc_va_conn_t
vlc_va_conn
=
{
0
,
0
,
0
,
0
,
NULL
,
NULL
};
static
vlc_va_conn_t
vlc_va_conn
=
{
0
,
0
,
0
,
0
,
NULL
,
NULL
,
0
,
NULL
,
NULL
,
NULL
};
static
vlc_mutex_t
vlc_va_conn_lock
=
VLC_STATIC_MUTEX
;
static
void
vlc_va_lock
(
void
)
...
...
@@ -61,6 +61,61 @@ static void vlc_va_unlock(void)
vlc_mutex_unlock
(
&
vlc_va_conn_lock
);
}
static
VASurfaceID
*
vlc_va_create_surfaces
(
vlc_va_conn_t
*
conn
,
const
int
width
,
const
int
height
,
const
int
fourcc
,
const
int
num
)
{
assert
(
conn
);
if
(
(
width
<=
0
)
||
(
height
<=
0
)
||
(
num
<=
0
)
)
return
NULL
;
/* FIXME: The size does not necessary match */
if
(
conn
->
i_ref_count
>
1
)
{
assert
(
num
==
conn
->
i_surface_count
);
return
conn
->
p_surface_ids
;
}
assert
(
conn
->
p_surface_ids
==
NULL
);
assert
(
conn
->
i_surface_count
==
0
);
VASurfaceID
*
p_surfaces
=
(
VASurfaceID
*
)
calloc
(
num
,
sizeof
(
VASurfaceID
));
if
(
p_surfaces
==
NULL
)
return
NULL
;
int
i_surface_count
=
num
;
VAStatus
status
=
vaCreateSurfaces
(
conn
->
p_display
,
width
,
height
,
fourcc
,
num
,
p_surfaces
);
if
(
status
!=
VA_STATUS_SUCCESS
)
{
free
(
p_surfaces
);
return
NULL
;
}
assert
(
i_surface_count
==
num
);
conn
->
p_surface_ids
=
p_surfaces
;
conn
->
i_surface_count
=
i_surface_count
;
return
conn
->
p_surface_ids
;
}
static
void
vlc_va_destroy_surfaces
(
vlc_va_conn_t
*
conn
)
{
assert
(
conn
);
assert
(
conn
->
i_surface_count
>
0
);
assert
(
conn
->
p_surface_ids
);
if
(
conn
->
i_ref_count
>
1
)
return
;
if
(
conn
->
p_surface_ids
!=
NULL
)
vaDestroySurfaces
(
conn
->
p_display
,
conn
->
p_surface_ids
,
conn
->
i_surface_count
);
conn
->
i_surface_count
=
0
;
conn
->
p_surface_ids
=
NULL
;
}
/* */
vlc_va_conn_t
*
vlc_va_get_conn
(
void
)
{
...
...
@@ -84,6 +139,11 @@ vlc_va_conn_t *vlc_va_Initialize( Display *display )
conn
->
lock
=
vlc_va_lock
;
conn
->
unlock
=
vlc_va_unlock
;
conn
->
i_surface_count
=
0
;
conn
->
p_surface_ids
=
NULL
;
conn
->
create_surfaces
=
vlc_va_create_surfaces
;
conn
->
destroy_surfaces
=
vlc_va_destroy_surfaces
;
/* Create a VA display */
conn
->
p_display
=
vaGetDisplay
(
display
);
if
(
!
conn
->
p_display
)
...
...
@@ -109,6 +169,9 @@ void vlc_va_Terminate( vlc_va_conn_t *conn )
if
(
conn
->
i_ref_count
>
0
)
return
;
assert
(
conn
->
i_surface_count
==
0
);
assert
(
conn
->
p_surface_ids
==
NULL
);
if
(
conn
->
p_display
)
vaTerminate
(
conn
->
p_display
);
...
...
modules/codec/avcodec/va.h
View file @
7a0dda44
...
...
@@ -24,7 +24,10 @@
#ifndef _VLC_VA_H
#define _VLC_VA_H 1
typedef
struct
vlc_va_conn_t
vlc_va_conn_t
;
typedef
struct
vlc_va_ops_t
vlc_va_ops_t
;
typedef
struct
vlc_va_t
vlc_va_t
;
struct
vlc_va_t
{
char
*
description
;
vlc_object_t
*
obj
;
...
...
@@ -72,9 +75,4 @@ static inline void vlc_va_Delete(vlc_va_t *va)
vlc_va_t
*
vlc_va_NewVaapi
(
vlc_object_t
*
obj
,
int
codec_id
);
vlc_va_t
*
vlc_va_NewDxva2
(
vlc_object_t
*
log
,
int
codec_id
);
/* */
typedef
struct
vlc_va_conn_t
vlc_va_conn_t
;
vlc_va_conn_t
*
vlc_va_get_conn
(
void
);
#endif
modules/codec/avcodec/vaapi.c
View file @
7a0dda44
...
...
@@ -117,7 +117,7 @@ static int Open( vlc_va_vaapi_t *p_va, int i_codec_id )
break
;
case
CODEC_ID_H264
:
i_profile
=
VAProfileH264High
;
i_surface_count
=
16
+
1
;
i_surface_count
=
30
;
//
16+1;
break
;
default:
return
VLC_EGENERIC
;
...
...
@@ -173,7 +173,63 @@ error:
return
VLC_EGENERIC
;
}
static
void
DestroySurfaces
(
vlc_va_vaapi_t
*
p_va
)
static
void
DestroySurfaces
(
vlc_va_conn_t
*
conn
)
{
assert
(
conn
);
assert
(
conn
->
i_surface_count
>
0
);
assert
(
conn
->
p_surface_ids
);
if
(
conn
->
i_ref_count
>
1
)
return
;
if
(
conn
->
p_surface_ids
!=
NULL
)
vaDestroySurfaces
(
conn
->
p_display
,
conn
->
p_surface_ids
,
conn
->
i_surface_count
);
conn
->
i_surface_count
=
0
;
conn
->
p_surface_ids
=
NULL
;
}
static
VASurfaceID
*
CreateSurfaces
(
vlc_va_conn_t
*
conn
,
const
int
width
,
const
int
height
,
const
int
fourcc
,
const
int
num
)
{
assert
(
conn
);
if
(
(
width
<=
0
)
||
(
height
<=
0
)
||
(
num
<=
0
)
)
return
NULL
;
/* FIXME: The size does not necessary match */
if
(
conn
->
i_ref_count
>
1
)
{
assert
(
num
==
conn
->
i_surface_count
);
return
conn
->
p_surface_ids
;
}
assert
(
conn
->
p_surface_ids
==
NULL
);
assert
(
conn
->
i_surface_count
==
0
);
VASurfaceID
*
p_surfaces
=
(
VASurfaceID
*
)
calloc
(
num
,
sizeof
(
VASurfaceID
));
if
(
p_surfaces
==
NULL
)
return
NULL
;
int
i_surface_count
=
num
;
VAStatus
status
=
vaCreateSurfaces
(
conn
->
p_display
,
width
,
height
,
fourcc
,
num
,
p_surfaces
);
if
(
status
!=
VA_STATUS_SUCCESS
)
{
free
(
p_surfaces
);
return
NULL
;
}
assert
(
i_surface_count
==
num
);
conn
->
p_surface_ids
=
p_surfaces
;
conn
->
i_surface_count
=
i_surface_count
;
return
conn
->
p_surface_ids
;
}
static
void
DestroyDecodingContext
(
vlc_va_vaapi_t
*
p_va
)
{
p_va
->
conn
->
lock
();
if
(
p_va
->
image
.
image_id
!=
VA_INVALID_ID
)
...
...
@@ -185,12 +241,7 @@ static void DestroySurfaces( vlc_va_vaapi_t *p_va )
if
(
p_va
->
i_context_id
!=
VA_INVALID_ID
)
vaDestroyContext
(
p_va
->
conn
->
p_display
,
p_va
->
i_context_id
);
for
(
int
i
=
0
;
i
<
p_va
->
i_surface_count
&&
p_va
->
p_surface
;
i
++
)
{
vlc_va_surface_t
*
p_surface
=
&
p_va
->
p_surface
[
i
];
if
(
p_surface
->
i_id
!=
VA_INVALID_SURFACE
)
vaDestroySurfaces
(
p_va
->
conn
->
p_display
,
&
p_surface
->
i_id
,
1
);
}
DestroySurfaces
(
p_va
->
conn
);
free
(
p_va
->
p_surface
);
/* */
...
...
@@ -201,7 +252,8 @@ static void DestroySurfaces( vlc_va_vaapi_t *p_va )
p_va
->
i_surface_height
=
0
;
p_va
->
conn
->
unlock
();
}
static
int
CreateSurfaces
(
vlc_va_vaapi_t
*
p_va
,
void
**
pp_hw_ctx
,
vlc_fourcc_t
*
pi_chroma
,
static
int
CreateDecodingContext
(
vlc_va_vaapi_t
*
p_va
,
void
**
pp_hw_ctx
,
vlc_fourcc_t
*
pi_chroma
,
int
i_width
,
int
i_height
)
{
assert
(
i_width
>
0
&&
i_height
>
0
);
...
...
@@ -216,9 +268,9 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t
p_va
->
conn
->
lock
();
/* Create surfaces */
VASurfaceID
pi_surface_id
[
p_va
->
i_surface_count
];
if
(
vaCreateSurfaces
(
p_va
->
conn
->
p_display
,
i_width
,
i_height
,
VA_RT_FORMAT_YUV420
,
p_va
->
i_surface_count
,
pi_surface_id
)
)
VASurfaceID
*
pi_surface_id
=
CreateSurfaces
(
p_va
->
conn
,
i_width
,
i_height
,
VA_RT_FORMAT_YUV420
,
p_va
->
i_surface_count
);
if
(
pi_surface_id
==
NULL
)
{
for
(
int
i
=
0
;
i
<
p_va
->
i_surface_count
;
i
++
)
p_va
->
p_surface
[
i
].
i_id
=
VA_INVALID_SURFACE
;
...
...
@@ -306,7 +358,7 @@ static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t
error:
p_va
->
conn
->
unlock
();
Destroy
Surfaces
(
p_va
);
Destroy
DecodingContext
(
p_va
);
return
VLC_EGENERIC
;
}
...
...
@@ -326,10 +378,10 @@ static int Setup( vlc_va_t *p_external, void **pp_hw_ctx, vlc_fourcc_t *pi_chrom
*
pp_hw_ctx
=
NULL
;
*
pi_chroma
=
0
;
if
(
p_va
->
i_surface_width
||
p_va
->
i_surface_height
)
Destroy
Surfaces
(
p_va
);
Destroy
DecodingContext
(
p_va
);
if
(
i_width
>
0
&&
i_height
>
0
)
return
Create
Surfaces
(
p_va
,
pp_hw_ctx
,
pi_chroma
,
i_width
,
i_height
);
return
Create
DecodingContext
(
p_va
,
pp_hw_ctx
,
pi_chroma
,
i_width
,
i_height
);
return
VLC_EGENERIC
;
}
...
...
@@ -525,7 +577,7 @@ static void Release( vlc_va_t *p_external, AVFrame *p_ff )
static
void
Close
(
vlc_va_vaapi_t
*
p_va
)
{
if
(
p_va
->
i_surface_width
||
p_va
->
i_surface_height
)
Destroy
Surfaces
(
p_va
);
Destroy
DecodingContext
(
p_va
);
if
(
p_va
->
conn
)
{
...
...
modules/codec/avcodec/vaapi.h
View file @
7a0dda44
...
...
@@ -18,20 +18,65 @@
****************************************************************************/
#ifdef HAVE_AVCODEC_VAAPI
/* VA API connection shared structure
* The decoding thread and the display thread
* need to share the connection to libva and
* the created surfaces for use with decoding
* context.
*/
struct
vlc_va_conn_t
{
VADisplay
p_display
;
int
i_version_major
;
int
i_version_minor
;
int
i_ref_count
;
/* for internal use only */
int
i_ref_count
;
/* locking functions */
void
(
*
lock
)(
void
);
void
(
*
unlock
)(
void
);
/* NOTE: must be called with lock held */
int
i_surface_count
;
VASurfaceID
*
p_surface_ids
;
VASurfaceID
*
(
*
create_surfaces
)(
vlc_va_conn_t
*
conn
,
const
int
width
,
const
int
height
,
const
int
fourcc
,
const
int
num
);
void
(
*
destroy_surfaces
)(
vlc_va_conn_t
*
conn
);
};
/* Retrieve shared connection struct */
vlc_va_conn_t
*
vlc_va_get_conn
(
void
);
/* Initialize shared connection to libva */
vlc_va_conn_t
*
vlc_va_Initialize
(
Display
*
display
);
/* Deinitialize shared connection to libva */
void
vlc_va_Terminate
(
vlc_va_conn_t
*
conn
);
static
inline
VASurfaceID
*
vlc_va_conn_CreateSurface
(
vlc_va_conn_t
*
conn
,
const
int
width
,
const
int
height
,
const
int
fourcc
,
const
int
num
)
{
return
conn
->
create_surfaces
(
conn
,
width
,
height
,
fourcc
,
num
);
}
static
inline
void
vlc_va_conn_DestorySurfaces
(
vlc_va_conn_t
*
conn
)
{
conn
->
destroy_surfaces
(
conn
);
}
static
inline
VASurfaceID
*
vlc_va_conn_GetSurfaces
(
vlc_va_conn_t
*
conn
)
{
return
conn
->
p_surface_ids
;
}
static
inline
int
vlc_va_conn_SurfacesCount
(
vlc_va_conn_t
*
conn
)
{
return
conn
->
i_surface_count
;
}
/* vlc_va_surface_t */
typedef
struct
{
VASurfaceID
i_id
;
...
...
@@ -39,6 +84,7 @@ typedef struct
unsigned
int
i_order
;
}
vlc_va_surface_t
;
/* picture_sys_t */
struct
picture_sys_t
{
/* */
...
...
modules/codec/avcodec/vaapi_x11.c
View file @
7a0dda44
...
...
@@ -492,7 +492,7 @@ int OpenVaapiX11(vlc_object_t *obj)
sys
->
visible
=
false
;
sys
->
cursor
=
CreateBlankCursor
(
conn
,
scr
);
msg_
Dbg
(
vd
,
"using VAAPI X11
video output (libva version %d.%d)"
,
msg_
Info
(
vd
,
"using VAAPI XCB
video output (libva version %d.%d)"
,
sys
->
conn
->
i_version_major
,
sys
->
conn
->
i_version_minor
);
/* */
...
...
@@ -583,7 +583,10 @@ void CloseVaapiX11(vlc_object_t *obj)
}
if
(
sys
->
conn
)
{
sys
->
conn
->
destroy_surfaces
(
sys
->
conn
);
vlc_va_Terminate
(
sys
->
conn
);
}
if
(
sys
->
x11display
)
XCloseDisplay
(
sys
->
x11display
);
...
...
@@ -1426,16 +1429,22 @@ static picture_pool_t *Pool (vout_display_t *vd, unsigned requested_count)
}
int
i_surface_count
=
count
;
VASurfaceID
pi_surface_id
[
i_surface_count
];
if
(
count
==
0
)
goto
error
;
/* Create surfaces */
sys
->
conn
->
lock
();
if
(
vaCreateSurfaces
(
sys
->
conn
->
p_display
,
vd
->
fmt
.
i_visible_width
,
vd
->
fmt
.
i_visible_height
,
VA_RT_FORMAT_YUV420
,
i_surface_count
,
pi_surface_id
))
VASurfaceID
*
pi_surface_id
;
if
(
sys
->
conn
->
i_surface_count
<
i_surface_count
)
{
pi_surface_id
=
sys
->
conn
->
create_surfaces
(
sys
->
conn
,
vd
->
fmt
.
i_visible_width
,
vd
->
fmt
.
i_visible_height
,
VA_RT_FORMAT_YUV420
,
i_surface_count
);
}
else
pi_surface_id
=
sys
->
conn
->
p_surface_ids
;
if
(
pi_surface_id
==
NULL
)
{
sys
->
conn
->
unlock
();
goto
error
;
...
...
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