Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
62a1ef9f
Commit
62a1ef9f
authored
Mar 04, 2017
by
Mark Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avconv: Enable generic hwaccel support for VAAPI
parent
d2e6dd32
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
16 additions
and
238 deletions
+16
-238
Makefile
avtools/Makefile
+0
-1
avconv.h
avtools/avconv.h
+0
-2
avconv_opt.c
avtools/avconv_opt.c
+16
-4
avconv_vaapi.c
avtools/avconv_vaapi.c
+0
-231
No files found.
avtools/Makefile
View file @
62a1ef9f
...
...
@@ -11,7 +11,6 @@ ALLAVPROGS = $(AVBASENAMES:%=%$(EXESUF))
OBJS-avconv
+=
avtools/avconv_opt.o avtools/avconv_filter.o
\
avtools/avconv_hw.o
OBJS-avconv-$(CONFIG_LIBMFX)
+=
avtools/avconv_qsv.o
OBJS-avconv-$(CONFIG_VAAPI)
+=
avtools/avconv_vaapi.o
OBJS-avconv-$(CONFIG_VDA)
+=
avtools/avconv_vda.o
OBJS-avconv-$(HAVE_DXVA2_LIB)
+=
avtools/avconv_dxva2.o
OBJS-avconv-$(HAVE_VDPAU_X11)
+=
avtools/avconv_vdpau.o
...
...
avtools/avconv.h
View file @
62a1ef9f
...
...
@@ -515,8 +515,6 @@ int dxva2_init(AVCodecContext *s);
int
vda_init
(
AVCodecContext
*
s
);
int
qsv_init
(
AVCodecContext
*
s
);
int
qsv_transcode_init
(
OutputStream
*
ost
);
int
vaapi_decode_init
(
AVCodecContext
*
avctx
);
int
vaapi_device_init
(
const
char
*
device
);
HWDevice
*
hw_device_get_by_name
(
const
char
*
name
);
int
hw_device_init_from_string
(
const
char
*
arg
,
HWDevice
**
dev
);
...
...
avtools/avconv_opt.c
View file @
62a1ef9f
...
...
@@ -73,8 +73,8 @@ const HWAccel hwaccels[] = {
AV_HWDEVICE_TYPE_NONE
},
#endif
#if CONFIG_VAAPI
{
"vaapi"
,
vaapi
_decode_init
,
HWACCEL_VAAPI
,
AV_PIX_FMT_VAAPI
,
AV_HWDEVICE_TYPE_
NONE
},
{
"vaapi"
,
hwaccel
_decode_init
,
HWACCEL_VAAPI
,
AV_PIX_FMT_VAAPI
,
AV_HWDEVICE_TYPE_
VAAPI
},
#endif
{
0
},
};
...
...
@@ -334,10 +334,22 @@ static int opt_attach(void *optctx, const char *opt, const char *arg)
#if CONFIG_VAAPI
static
int
opt_vaapi_device
(
void
*
optctx
,
const
char
*
opt
,
const
char
*
arg
)
{
HWDevice
*
dev
;
const
char
*
prefix
=
"vaapi:"
;
char
*
tmp
;
int
err
;
err
=
vaapi_device_init
(
arg
);
tmp
=
av_malloc
(
strlen
(
prefix
)
+
strlen
(
arg
)
+
1
);
if
(
!
tmp
)
return
AVERROR
(
ENOMEM
);
strcpy
(
tmp
,
prefix
);
strcat
(
tmp
,
arg
);
err
=
hw_device_init_from_string
(
tmp
,
&
dev
);
av_free
(
tmp
);
if
(
err
<
0
)
exit_program
(
1
);
return
err
;
hw_device_ctx
=
av_buffer_ref
(
dev
->
device_ref
);
if
(
!
hw_device_ctx
)
return
AVERROR
(
ENOMEM
);
return
0
;
}
#endif
...
...
avtools/avconv_vaapi.c
deleted
100644 → 0
View file @
d2e6dd32
/*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "libavutil/avassert.h"
#include "libavutil/frame.h"
#include "libavutil/hwcontext.h"
#include "libavutil/log.h"
#include "avconv.h"
static
AVClass
vaapi_class
=
{
.
class_name
=
"vaapi"
,
.
item_name
=
av_default_item_name
,
.
version
=
LIBAVUTIL_VERSION_INT
,
};
#define DEFAULT_SURFACES 20
typedef
struct
VAAPIDecoderContext
{
const
AVClass
*
class
;
AVBufferRef
*
device_ref
;
AVHWDeviceContext
*
device
;
AVBufferRef
*
frames_ref
;
AVHWFramesContext
*
frames
;
// The output need not have the same format, width and height as the
// decoded frames - the copy for non-direct-mapped access is actually
// a whole vpp instance which can do arbitrary scaling and format
// conversion.
enum
AVPixelFormat
output_format
;
}
VAAPIDecoderContext
;
static
int
vaapi_get_buffer
(
AVCodecContext
*
avctx
,
AVFrame
*
frame
,
int
flags
)
{
InputStream
*
ist
=
avctx
->
opaque
;
VAAPIDecoderContext
*
ctx
=
ist
->
hwaccel_ctx
;
int
err
;
err
=
av_hwframe_get_buffer
(
ctx
->
frames_ref
,
frame
,
0
);
if
(
err
<
0
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Failed to allocate decoder surface.
\n
"
);
}
else
{
av_log
(
ctx
,
AV_LOG_DEBUG
,
"Decoder given surface %#x.
\n
"
,
(
unsigned
int
)(
uintptr_t
)
frame
->
data
[
3
]);
}
return
err
;
}
static
int
vaapi_retrieve_data
(
AVCodecContext
*
avctx
,
AVFrame
*
input
)
{
InputStream
*
ist
=
avctx
->
opaque
;
VAAPIDecoderContext
*
ctx
=
ist
->
hwaccel_ctx
;
AVFrame
*
output
=
0
;
int
err
;
av_assert0
(
input
->
format
==
AV_PIX_FMT_VAAPI
);
if
(
ctx
->
output_format
==
AV_PIX_FMT_VAAPI
)
{
// Nothing to do.
return
0
;
}
av_log
(
ctx
,
AV_LOG_DEBUG
,
"Retrieve data from surface %#x.
\n
"
,
(
unsigned
int
)(
uintptr_t
)
input
->
data
[
3
]);
output
=
av_frame_alloc
();
if
(
!
output
)
return
AVERROR
(
ENOMEM
);
output
->
format
=
ctx
->
output_format
;
err
=
av_hwframe_transfer_data
(
output
,
input
,
0
);
if
(
err
<
0
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Failed to transfer data to "
"output frame: %d.
\n
"
,
err
);
goto
fail
;
}
err
=
av_frame_copy_props
(
output
,
input
);
if
(
err
<
0
)
{
av_frame_unref
(
output
);
goto
fail
;
}
av_frame_unref
(
input
);
av_frame_move_ref
(
input
,
output
);
av_frame_free
(
&
output
);
return
0
;
fail:
if
(
output
)
av_frame_free
(
&
output
);
return
err
;
}
static
void
vaapi_decode_uninit
(
AVCodecContext
*
avctx
)
{
InputStream
*
ist
=
avctx
->
opaque
;
VAAPIDecoderContext
*
ctx
=
ist
->
hwaccel_ctx
;
if
(
ctx
)
{
av_buffer_unref
(
&
ctx
->
frames_ref
);
av_buffer_unref
(
&
ctx
->
device_ref
);
av_free
(
ctx
);
}
av_buffer_unref
(
&
ist
->
hw_frames_ctx
);
ist
->
hwaccel_ctx
=
NULL
;
ist
->
hwaccel_uninit
=
NULL
;
ist
->
hwaccel_get_buffer
=
NULL
;
ist
->
hwaccel_retrieve_data
=
NULL
;
}
int
vaapi_decode_init
(
AVCodecContext
*
avctx
)
{
InputStream
*
ist
=
avctx
->
opaque
;
VAAPIDecoderContext
*
ctx
;
int
err
;
int
loglevel
=
(
ist
->
hwaccel_id
!=
HWACCEL_VAAPI
?
AV_LOG_VERBOSE
:
AV_LOG_ERROR
);
if
(
ist
->
hwaccel_ctx
)
vaapi_decode_uninit
(
avctx
);
// We have -hwaccel without -vaapi_device, so just initialise here with
// the device passed as -hwaccel_device (if -vaapi_device was passed, it
// will always have been called before now).
if
(
!
hw_device_ctx
)
{
err
=
vaapi_device_init
(
ist
->
hwaccel_device
);
if
(
err
<
0
)
return
err
;
}
ctx
=
av_mallocz
(
sizeof
(
*
ctx
));
if
(
!
ctx
)
return
AVERROR
(
ENOMEM
);
ctx
->
class
=
&
vaapi_class
;
ctx
->
device_ref
=
av_buffer_ref
(
hw_device_ctx
);
ctx
->
device
=
(
AVHWDeviceContext
*
)
ctx
->
device_ref
->
data
;
ctx
->
output_format
=
ist
->
hwaccel_output_format
;
avctx
->
pix_fmt
=
ctx
->
output_format
;
ctx
->
frames_ref
=
av_hwframe_ctx_alloc
(
ctx
->
device_ref
);
if
(
!
ctx
->
frames_ref
)
{
av_log
(
ctx
,
loglevel
,
"Failed to create VAAPI frame context.
\n
"
);
err
=
AVERROR
(
ENOMEM
);
goto
fail
;
}
ctx
->
frames
=
(
AVHWFramesContext
*
)
ctx
->
frames_ref
->
data
;
ctx
->
frames
->
format
=
AV_PIX_FMT_VAAPI
;
ctx
->
frames
->
width
=
avctx
->
coded_width
;
ctx
->
frames
->
height
=
avctx
->
coded_height
;
// It would be nice if we could query the available formats here,
// but unfortunately we don't have a VAConfigID to do it with.
// For now, just assume an NV12 format (or P010 if 10-bit).
ctx
->
frames
->
sw_format
=
(
avctx
->
sw_pix_fmt
==
AV_PIX_FMT_YUV420P10
?
AV_PIX_FMT_P010
:
AV_PIX_FMT_NV12
);
// For frame-threaded decoding, at least one additional surface
// is needed for each thread.
ctx
->
frames
->
initial_pool_size
=
DEFAULT_SURFACES
;
if
(
avctx
->
active_thread_type
&
FF_THREAD_FRAME
)
ctx
->
frames
->
initial_pool_size
+=
avctx
->
thread_count
;
err
=
av_hwframe_ctx_init
(
ctx
->
frames_ref
);
if
(
err
<
0
)
{
av_log
(
ctx
,
loglevel
,
"Failed to initialise VAAPI frame "
"context: %d
\n
"
,
err
);
goto
fail
;
}
ist
->
hw_frames_ctx
=
av_buffer_ref
(
ctx
->
frames_ref
);
if
(
!
ist
->
hw_frames_ctx
)
{
err
=
AVERROR
(
ENOMEM
);
goto
fail
;
}
ist
->
hwaccel_ctx
=
ctx
;
ist
->
hwaccel_uninit
=
&
vaapi_decode_uninit
;
ist
->
hwaccel_get_buffer
=
&
vaapi_get_buffer
;
ist
->
hwaccel_retrieve_data
=
&
vaapi_retrieve_data
;
return
0
;
fail:
vaapi_decode_uninit
(
avctx
);
return
err
;
}
static
AVClass
*
vaapi_log
=
&
vaapi_class
;
av_cold
int
vaapi_device_init
(
const
char
*
device
)
{
int
err
;
err
=
av_hwdevice_ctx_create
(
&
hw_device_ctx
,
AV_HWDEVICE_TYPE_VAAPI
,
device
,
NULL
,
0
);
if
(
err
<
0
)
{
av_log
(
&
vaapi_log
,
AV_LOG_ERROR
,
"Failed to create a VAAPI device
\n
"
);
return
err
;
}
return
0
;
}
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