Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Releases
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Stefan Westerfeld
ffmpeg
Commits
89923e41
Commit
89923e41
authored
Nov 20, 2015
by
Anton Khirnov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavu: add a framework for handling hwaccel frames
parent
721a4efc
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
834 additions
and
0 deletions
+834
-0
APIchanges
doc/APIchanges
+2
-0
Makefile
libavutil/Makefile
+2
-0
frame.c
libavutil/frame.c
+11
-0
frame.h
libavutil/frame.h
+6
-0
hwcontext.c
libavutil/hwcontext.c
+396
-0
hwcontext.h
libavutil/hwcontext.h
+328
-0
hwcontext_internal.h
libavutil/hwcontext_internal.h
+89
-0
No files found.
doc/APIchanges
View file @
89923e41
...
...
@@ -15,6 +15,8 @@ API changes, most recent first:
2016-xx-xx - lavu 55.6.0
xxxxxxx buffer.h - Add av_buffer_pool_init2().
xxxxxxx hwcontext.h - Add a new installed header hwcontext.h with a new API
for handling hwaccel frames.
2016-xx-xx - xxxxxxx - lavf 57.3.0 - avformat.h
Add AVFormatContext.opaque, io_open and io_close, allowing custom IO
...
...
libavutil/Makefile
View file @
89923e41
...
...
@@ -23,6 +23,7 @@ HEADERS = adler32.h \
file.h
\
frame.h
\
hmac.h
\
hwcontext.h
\
imgutils.h
\
intfloat.h
\
intreadwrite.h
\
...
...
@@ -78,6 +79,7 @@ OBJS = adler32.o \
float_dsp.o
\
frame.o
\
hmac.o
\
hwcontext.o
\
imgutils.o
\
intmath.o
\
lfg.o
\
...
...
libavutil/frame.c
View file @
89923e41
...
...
@@ -251,6 +251,14 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
}
}
if
(
src
->
hw_frames_ctx
)
{
dst
->
hw_frames_ctx
=
av_buffer_ref
(
src
->
hw_frames_ctx
);
if
(
!
dst
->
hw_frames_ctx
)
{
ret
=
AVERROR
(
ENOMEM
);
goto
fail
;
}
}
/* duplicate extended data */
if
(
src
->
extended_data
!=
src
->
data
)
{
int
ch
=
av_get_channel_layout_nb_channels
(
src
->
channel_layout
);
...
...
@@ -303,6 +311,9 @@ void av_frame_unref(AVFrame *frame)
for
(
i
=
0
;
i
<
frame
->
nb_extended_buf
;
i
++
)
av_buffer_unref
(
&
frame
->
extended_buf
[
i
]);
av_freep
(
&
frame
->
extended_buf
);
av_buffer_unref
(
&
frame
->
hw_frames_ctx
);
get_frame_defaults
(
frame
);
}
...
...
libavutil/frame.h
View file @
89923e41
...
...
@@ -354,6 +354,12 @@ typedef struct AVFrame {
enum
AVColorSpace
colorspace
;
enum
AVChromaLocation
chroma_location
;
/**
* For hwaccel-format frames, this should be a reference to the
* AVHWFramesContext describing the frame.
*/
AVBufferRef
*
hw_frames_ctx
;
}
AVFrame
;
/**
...
...
libavutil/hwcontext.c
0 → 100644
View file @
89923e41
/*
* 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 "buffer.h"
#include "common.h"
#include "hwcontext.h"
#include "hwcontext_internal.h"
#include "imgutils.h"
#include "log.h"
#include "mem.h"
#include "pixdesc.h"
#include "pixfmt.h"
static
const
HWContextType
*
hw_table
[]
=
{
NULL
,
};
static
const
AVClass
hwdevice_ctx_class
=
{
.
class_name
=
"AVHWDeviceContext"
,
.
item_name
=
av_default_item_name
,
.
version
=
LIBAVUTIL_VERSION_INT
,
};
static
void
hwdevice_ctx_free
(
void
*
opaque
,
uint8_t
*
data
)
{
AVHWDeviceContext
*
ctx
=
(
AVHWDeviceContext
*
)
data
;
/* uninit might still want access the hw context and the user
* free() callback might destroy it, so uninit has to be called first */
if
(
ctx
->
internal
->
hw_type
->
device_uninit
)
ctx
->
internal
->
hw_type
->
device_uninit
(
ctx
);
if
(
ctx
->
free
)
ctx
->
free
(
ctx
);
av_freep
(
&
ctx
->
hwctx
);
av_freep
(
&
ctx
->
internal
->
priv
);
av_freep
(
&
ctx
->
internal
);
av_freep
(
&
ctx
);
}
AVBufferRef
*
av_hwdevice_ctx_alloc
(
enum
AVHWDeviceType
type
)
{
AVHWDeviceContext
*
ctx
;
AVBufferRef
*
buf
;
const
HWContextType
*
hw_type
=
NULL
;
int
i
;
for
(
i
=
0
;
hw_table
[
i
];
i
++
)
{
if
(
hw_table
[
i
]
->
type
==
type
)
{
hw_type
=
hw_table
[
i
];
break
;
}
}
if
(
!
hw_type
)
return
NULL
;
ctx
=
av_mallocz
(
sizeof
(
*
ctx
));
if
(
!
ctx
)
return
NULL
;
ctx
->
internal
=
av_mallocz
(
sizeof
(
*
ctx
->
internal
));
if
(
!
ctx
->
internal
)
goto
fail
;
if
(
hw_type
->
device_priv_size
)
{
ctx
->
internal
->
priv
=
av_mallocz
(
hw_type
->
device_priv_size
);
if
(
!
ctx
->
internal
->
priv
)
goto
fail
;
}
if
(
hw_type
->
device_hwctx_size
)
{
ctx
->
hwctx
=
av_mallocz
(
hw_type
->
device_hwctx_size
);
if
(
!
ctx
->
hwctx
)
goto
fail
;
}
buf
=
av_buffer_create
((
uint8_t
*
)
ctx
,
sizeof
(
*
ctx
),
hwdevice_ctx_free
,
NULL
,
AV_BUFFER_FLAG_READONLY
);
if
(
!
buf
)
goto
fail
;
ctx
->
type
=
type
;
ctx
->
av_class
=
&
hwdevice_ctx_class
;
ctx
->
internal
->
hw_type
=
hw_type
;
return
buf
;
fail:
if
(
ctx
->
internal
)
av_freep
(
&
ctx
->
internal
->
priv
);
av_freep
(
&
ctx
->
internal
);
av_freep
(
&
ctx
->
hwctx
);
av_freep
(
&
ctx
);
return
NULL
;
}
int
av_hwdevice_ctx_init
(
AVBufferRef
*
ref
)
{
AVHWDeviceContext
*
ctx
=
(
AVHWDeviceContext
*
)
ref
->
data
;
int
ret
;
if
(
ctx
->
internal
->
hw_type
->
device_init
)
{
ret
=
ctx
->
internal
->
hw_type
->
device_init
(
ctx
);
if
(
ret
<
0
)
goto
fail
;
}
return
0
;
fail:
if
(
ctx
->
internal
->
hw_type
->
device_uninit
)
ctx
->
internal
->
hw_type
->
device_uninit
(
ctx
);
return
ret
;
}
static
const
AVClass
hwframe_ctx_class
=
{
.
class_name
=
"AVHWFramesContext"
,
.
item_name
=
av_default_item_name
,
.
version
=
LIBAVUTIL_VERSION_INT
,
};
static
void
hwframe_ctx_free
(
void
*
opaque
,
uint8_t
*
data
)
{
AVHWFramesContext
*
ctx
=
(
AVHWFramesContext
*
)
data
;
if
(
ctx
->
internal
->
pool_internal
)
av_buffer_pool_uninit
(
&
ctx
->
internal
->
pool_internal
);
if
(
ctx
->
internal
->
hw_type
->
frames_uninit
)
ctx
->
internal
->
hw_type
->
frames_uninit
(
ctx
);
if
(
ctx
->
free
)
ctx
->
free
(
ctx
);
av_buffer_unref
(
&
ctx
->
device_ref
);
av_freep
(
&
ctx
->
hwctx
);
av_freep
(
&
ctx
->
internal
->
priv
);
av_freep
(
&
ctx
->
internal
);
av_freep
(
&
ctx
);
}
AVBufferRef
*
av_hwframe_ctx_alloc
(
AVBufferRef
*
device_ref_in
)
{
AVHWDeviceContext
*
device_ctx
=
(
AVHWDeviceContext
*
)
device_ref_in
->
data
;
const
HWContextType
*
hw_type
=
device_ctx
->
internal
->
hw_type
;
AVHWFramesContext
*
ctx
;
AVBufferRef
*
buf
,
*
device_ref
=
NULL
;;
ctx
=
av_mallocz
(
sizeof
(
*
ctx
));
if
(
!
ctx
)
return
NULL
;
ctx
->
internal
=
av_mallocz
(
sizeof
(
*
ctx
->
internal
));
if
(
!
ctx
->
internal
)
goto
fail
;
if
(
hw_type
->
frames_priv_size
)
{
ctx
->
internal
->
priv
=
av_mallocz
(
hw_type
->
frames_priv_size
);
if
(
!
ctx
->
internal
->
priv
)
goto
fail
;
}
if
(
hw_type
->
frames_hwctx_size
)
{
ctx
->
hwctx
=
av_mallocz
(
hw_type
->
frames_hwctx_size
);
if
(
!
ctx
->
hwctx
)
goto
fail
;
}
device_ref
=
av_buffer_ref
(
device_ref_in
);
if
(
!
device_ref
)
goto
fail
;
buf
=
av_buffer_create
((
uint8_t
*
)
ctx
,
sizeof
(
*
ctx
),
hwframe_ctx_free
,
NULL
,
AV_BUFFER_FLAG_READONLY
);
if
(
!
buf
)
goto
fail
;
ctx
->
av_class
=
&
hwframe_ctx_class
;
ctx
->
device_ref
=
device_ref
;
ctx
->
device_ctx
=
device_ctx
;
ctx
->
format
=
AV_PIX_FMT_NONE
;
ctx
->
internal
->
hw_type
=
hw_type
;
return
buf
;
fail:
if
(
device_ref
)
av_buffer_unref
(
&
device_ref
);
if
(
ctx
->
internal
)
av_freep
(
&
ctx
->
internal
->
priv
);
av_freep
(
&
ctx
->
internal
);
av_freep
(
&
ctx
->
hwctx
);
av_freep
(
&
ctx
);
return
NULL
;
}
static
int
hwframe_pool_prealloc
(
AVBufferRef
*
ref
)
{
AVHWFramesContext
*
ctx
=
(
AVHWFramesContext
*
)
ref
->
data
;
AVFrame
**
frames
;
int
i
,
ret
=
0
;
frames
=
av_mallocz_array
(
ctx
->
initial_pool_size
,
sizeof
(
*
frames
));
if
(
!
frames
)
return
AVERROR
(
ENOMEM
);
for
(
i
=
0
;
i
<
ctx
->
initial_pool_size
;
i
++
)
{
frames
[
i
]
=
av_frame_alloc
();
if
(
!
frames
[
i
])
goto
fail
;
ret
=
av_hwframe_get_buffer
(
ref
,
frames
[
i
],
0
);
if
(
ret
<
0
)
goto
fail
;
}
fail:
for
(
i
=
0
;
i
<
ctx
->
initial_pool_size
;
i
++
)
av_frame_free
(
&
frames
[
i
]);
av_freep
(
&
frames
);
return
ret
;
}
int
av_hwframe_ctx_init
(
AVBufferRef
*
ref
)
{
AVHWFramesContext
*
ctx
=
(
AVHWFramesContext
*
)
ref
->
data
;
const
enum
AVPixelFormat
*
pix_fmt
;
int
ret
;
/* validate the pixel format */
for
(
pix_fmt
=
ctx
->
internal
->
hw_type
->
pix_fmts
;
*
pix_fmt
!=
AV_PIX_FMT_NONE
;
pix_fmt
++
)
{
if
(
*
pix_fmt
==
ctx
->
format
)
break
;
}
if
(
*
pix_fmt
==
AV_PIX_FMT_NONE
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"The hardware pixel format '%s' is not supported by the device type '%s'
\n
"
,
av_get_pix_fmt_name
(
ctx
->
format
),
ctx
->
internal
->
hw_type
->
name
);
return
AVERROR
(
ENOSYS
);
}
/* validate the dimensions */
ret
=
av_image_check_size
(
ctx
->
width
,
ctx
->
height
,
0
,
ctx
);
if
(
ret
<
0
)
return
ret
;
/* format-specific init */
if
(
ctx
->
internal
->
hw_type
->
frames_init
)
{
ret
=
ctx
->
internal
->
hw_type
->
frames_init
(
ctx
);
if
(
ret
<
0
)
goto
fail
;
}
if
(
ctx
->
internal
->
pool_internal
&&
!
ctx
->
pool
)
ctx
->
pool
=
ctx
->
internal
->
pool_internal
;
/* preallocate the frames in the pool, if requested */
if
(
ctx
->
initial_pool_size
>
0
)
{
ret
=
hwframe_pool_prealloc
(
ref
);
if
(
ret
<
0
)
goto
fail
;
}
return
0
;
fail:
if
(
ctx
->
internal
->
hw_type
->
frames_uninit
)
ctx
->
internal
->
hw_type
->
frames_uninit
(
ctx
);
return
ret
;
}
int
av_hwframe_transfer_get_formats
(
AVBufferRef
*
hwframe_ref
,
enum
AVHWFrameTransferDirection
dir
,
enum
AVPixelFormat
**
formats
,
int
flags
)
{
AVHWFramesContext
*
ctx
=
(
AVHWFramesContext
*
)
hwframe_ref
->
data
;
if
(
!
ctx
->
internal
->
hw_type
->
transfer_get_formats
)
return
AVERROR
(
ENOSYS
);
return
ctx
->
internal
->
hw_type
->
transfer_get_formats
(
ctx
,
dir
,
formats
);
}
static
int
transfer_data_alloc
(
AVFrame
*
dst
,
const
AVFrame
*
src
,
int
flags
)
{
AVFrame
*
frame_tmp
;
int
ret
=
0
;
frame_tmp
=
av_frame_alloc
();
if
(
!
frame_tmp
)
return
AVERROR
(
ENOMEM
);
/* if the format is set, use that
* otherwise pick the first supported one */
if
(
dst
->
format
>=
0
)
{
frame_tmp
->
format
=
dst
->
format
;
}
else
{
enum
AVPixelFormat
*
formats
;
ret
=
av_hwframe_transfer_get_formats
(
src
->
hw_frames_ctx
,
AV_HWFRAME_TRANSFER_DIRECTION_FROM
,
&
formats
,
0
);
if
(
ret
<
0
)
goto
fail
;
frame_tmp
->
format
=
formats
[
0
];
av_freep
(
&
formats
);
}
frame_tmp
->
width
=
src
->
width
;
frame_tmp
->
height
=
src
->
height
;
ret
=
av_frame_get_buffer
(
frame_tmp
,
32
);
if
(
ret
<
0
)
goto
fail
;
ret
=
av_hwframe_transfer_data
(
frame_tmp
,
src
,
flags
);
if
(
ret
<
0
)
goto
fail
;
av_frame_move_ref
(
dst
,
frame_tmp
);
fail:
av_frame_free
(
&
frame_tmp
);
return
ret
;
}
int
av_hwframe_transfer_data
(
AVFrame
*
dst
,
const
AVFrame
*
src
,
int
flags
)
{
AVHWFramesContext
*
ctx
;
int
ret
;
if
(
!
dst
->
buf
[
0
])
return
transfer_data_alloc
(
dst
,
src
,
flags
);
if
(
src
->
hw_frames_ctx
)
{
ctx
=
(
AVHWFramesContext
*
)
src
->
hw_frames_ctx
->
data
;
ret
=
ctx
->
internal
->
hw_type
->
transfer_data_from
(
ctx
,
dst
,
src
);
if
(
ret
<
0
)
return
ret
;
}
else
if
(
dst
->
hw_frames_ctx
)
{
ctx
=
(
AVHWFramesContext
*
)
dst
->
hw_frames_ctx
->
data
;
ret
=
ctx
->
internal
->
hw_type
->
transfer_data_to
(
ctx
,
dst
,
src
);
if
(
ret
<
0
)
return
ret
;
}
else
return
AVERROR
(
ENOSYS
);
return
0
;
}
int
av_hwframe_get_buffer
(
AVBufferRef
*
hwframe_ref
,
AVFrame
*
frame
,
int
flags
)
{
AVHWFramesContext
*
ctx
=
(
AVHWFramesContext
*
)
hwframe_ref
->
data
;
int
ret
;
if
(
!
ctx
->
internal
->
hw_type
->
frames_get_buffer
)
return
AVERROR
(
ENOSYS
);
if
(
!
ctx
->
pool
)
return
AVERROR
(
EINVAL
);
frame
->
hw_frames_ctx
=
av_buffer_ref
(
hwframe_ref
);
if
(
!
frame
->
hw_frames_ctx
)
return
AVERROR
(
ENOMEM
);
ret
=
ctx
->
internal
->
hw_type
->
frames_get_buffer
(
ctx
,
frame
);
if
(
ret
<
0
)
{
av_buffer_unref
(
&
frame
->
hw_frames_ctx
);
return
ret
;
}
return
0
;
}
libavutil/hwcontext.h
0 → 100644
View file @
89923e41
/*
* 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
*/
#ifndef AVUTIL_HWCONTEXT_H
#define AVUTIL_HWCONTEXT_H
#include "buffer.h"
#include "frame.h"
#include "log.h"
#include "pixfmt.h"
enum
AVHWDeviceType
{
AV_HWDEVICE_TYPE_VDPAU
,
};
typedef
struct
AVHWDeviceInternal
AVHWDeviceInternal
;
/**
* This struct aggregates all the (hardware/vendor-specific) "high-level" state,
* i.e. state that is not tied to a concrete processing configuration.
* E.g., in an API that supports hardware-accelerated encoding and decoding,
* this struct will (if possible) wrap the state that is common to both encoding
* and decoding and from which specific instances of encoders or decoders can be
* derived.
*
* This struct is reference-counted with the AVBuffer mechanism. The
* av_hwdevice_ctx_alloc() constructor yields a reference, whose data field
* points to the actual AVHWDeviceContext. Further objects derived from
* AVHWDeviceContext (such as AVHWFramesContext, describing a frame pool with
* specific properties) will hold an internal reference to it. After all the
* references are released, the AVHWDeviceContext itself will be freed,
* optionally invoking a user-specified callback for uninitializing the hardware
* state.
*/
typedef
struct
AVHWDeviceContext
{
/**
* A class for logging. Set by av_hwdevice_ctx_alloc().
*/
const
AVClass
*
av_class
;
/**
* Private data used internally by libavutil. Must not be accessed in any
* way by the caller.
*/
AVHWDeviceInternal
*
internal
;
/**
* This field identifies the underlying API used for hardware access.
*
* This field is set when this struct is allocated and never changed
* afterwards.
*/
enum
AVHWDeviceType
type
;
/**
* The format-specific data, allocated and freed by libavutil along with
* this context.
*
* Should be cast by the user to the format-specific context defined in the
* corresponding header (hwcontext_*.h) and filled as described in the
* documentation before calling av_hwdevice_ctx_init().
*
* After calling av_hwdevice_ctx_init() this struct should not be modified
* by the caller.
*/
void
*
hwctx
;
/**
* This field may be set by the caller before calling av_hwdevice_ctx_init().
*
* If non-NULL, this callback will be called when the last reference to
* this context is unreferenced, immediately before it is freed.
*
* @note when other objects (e.g an AVHWFramesContext) are derived from this
* struct, this callback will be invoked after all such child objects
* are fully uninitialized and their respective destructors invoked.
*/
void
(
*
free
)(
struct
AVHWDeviceContext
*
ctx
);
/**
* Arbitrary user data, to be used e.g. by the free() callback.
*/
void
*
user_opaque
;
}
AVHWDeviceContext
;
typedef
struct
AVHWFramesInternal
AVHWFramesInternal
;
/**
* This struct describes a set or pool of "hardware" frames (i.e. those with
* data not located in normal system memory). All the frames in the pool are
* assumed to be allocated in the same way and interchangeable.
*
* This struct is reference-counted with the AVBuffer mechanism and tied to a
* given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
* yields a reference, whose data field points to the actual AVHWFramesContext
* struct.
*/
typedef
struct
AVHWFramesContext
{
/**
* A class for logging.
*/
const
AVClass
*
av_class
;
/**
* Private data used internally by libavutil. Must not be accessed in any
* way by the caller.
*/
AVHWFramesInternal
*
internal
;
/**
* A reference to the parent AVHWDeviceContext. This reference is owned and
* managed by the enclosing AVHWFramesContext, but the caller may derive
* additional references from it.
*/
AVBufferRef
*
device_ref
;
/**
* The parent AVHWDeviceContext. This is simply a pointer to
* device_ref->data provided for convenience.
*
* Set by libavutil in av_hwframe_ctx_init().
*/
AVHWDeviceContext
*
device_ctx
;
/**
* The format-specific data, allocated and freed automatically along with
* this context.
*
* Should be cast by the user to the format-specific context defined in the
* corresponding header (hwframe_*.h) and filled as described in the
* documentation before calling av_hwframe_ctx_init().
*
* After any frames using this context are created, the contents of this
* struct should not be modified by the caller.
*/
void
*
hwctx
;
/**
* This field may be set by the caller before calling av_hwframe_ctx_init().
*
* If non-NULL, this callback will be called when the last reference to
* this context is unreferenced, immediately before it is freed.
*/
void
(
*
free
)(
struct
AVHWFramesContext
*
ctx
);
/**
* Arbitrary user data, to be used e.g. by the free() callback.
*/
void
*
user_opaque
;
/**
* A pool from which the frames are allocated by av_hwframe_get_buffer().
* This field may be set by the caller before calling av_hwframe_ctx_init().
* The buffers returned by calling av_buffer_pool_get() on this pool must
* have the properties described in the documentation in the correponding hw
* type's header (hwcontext_*.h). The pool will be freed strictly before
* this struct's free() callback is invoked.
*
* This field may be NULL, then libavutil will attempt to allocate a pool
* internally. Note that certain device types enforce pools allocated at
* fixed size (frame count), which cannot be extended dynamically. In such a
* case, initial_pool_size must be set appropriately.
*/
AVBufferPool
*
pool
;
/**
* Initial size of the frame pool. If a device type does not support
* dynamically resizing the pool, then this is also the maximum pool size.
*
* May be set by the caller before calling av_hwframe_ctx_init(). Must be
* set if pool is NULL and the device type does not support dynamic pools.
*/
int
initial_pool_size
;
/**
* The pixel format identifying the underlying HW surface type.
*
* Must be a hwaccel format, i.e. the corresponding descriptor must have the
* AV_PIX_FMT_FLAG_HWACCEL flag set.
*
* Must be set by the user before calling av_hwframe_ctx_init().
*/
enum
AVPixelFormat
format
;
/**
* The pixel format identifying the actual data layout of the hardware
* frames.
*
* Must be set by the caller before calling av_hwframe_ctx_init().
*
* @note when the underlying API does not provide the exact data layout, but
* only the colorspace/bit depth, this field should be set to the fully
* planar version of that format (e.g. for 8-bit 420 YUV it should be
* AV_PIX_FMT_YUV420P, not AV_PIX_FMT_NV12 or anything else).
*/
enum
AVPixelFormat
sw_format
;
/**
* The allocated dimensions of the frames in this pool.
*
* Must be set by the user before calling av_hwframe_ctx_init().
*/
int
width
,
height
;
}
AVHWFramesContext
;
/**
* Allocate an AVHWDeviceContext for a given pixel format.
*
* @param format a hwaccel pixel format (AV_PIX_FMT_FLAG_HWACCEL must be set
* on the corresponding format descriptor)
* @return a reference to the newly created AVHWDeviceContext on success or NULL
* on failure.
*/
AVBufferRef
*
av_hwdevice_ctx_alloc
(
enum
AVHWDeviceType
type
);
/**
* Finalize the device context before use. This function must be called after
* the context is filled with all the required information and before it is
* used in any way.
*
* @param ref a reference to the AVHWDeviceContext
* @return 0 on success, a negative AVERROR code on failure
*/
int
av_hwdevice_ctx_init
(
AVBufferRef
*
ref
);
/**
* Allocate an AVHWFramesContext tied to a given device context.
*
* @param device_ctx a reference to a AVHWDeviceContext. This function will make
* a new reference for internal use, the one passed to the
* function remains owned by the caller.
* @return a reference to the newly created AVHWFramesContext on success or NULL
* on failure.
*/
AVBufferRef
*
av_hwframe_ctx_alloc
(
AVBufferRef
*
device_ctx
);
/**
* Finalize the context before use. This function must be called after the
* context is filled with all the required information and before it is attached
* to any frames.
*
* @param ref a reference to the AVHWFramesContext
* @return 0 on success, a negative AVERROR code on failure
*/
int
av_hwframe_ctx_init
(
AVBufferRef
*
ref
);
/**
* Allocate a new frame attached to the given AVHWFramesContext.
*
* @param hwframe_ctx a reference to an AVHWFramesContext
* @param frame an empty (freshly allocated or unreffed) frame to be filled with
* newly allocated buffers.
* @param flags currently unused, should be set to zero
* @return 0 on success, a negative AVERROR code on failure
*/
int
av_hwframe_get_buffer
(
AVBufferRef
*
hwframe_ctx
,
AVFrame
*
frame
,
int
flags
);
/**
* Copy data to or from a hw surface. At least one of dst/src must have an
* AVHWFramesContext attached.
*
* If src has an AVHWFramesContext attached, then the format of dst (if set)
* must use one of the formats returned by av_hwframe_transfer_get_formats(src,
* AV_HWFRAME_TRANSFER_DIRECTION_FROM).
* If dst has an AVHWFramesContext attached, then the format of src must use one
* of the formats returned by av_hwframe_transfer_get_formats(dst,
* AV_HWFRAME_TRANSFER_DIRECTION_TO)
*
* dst may be "clean" (i.e. with data/buf pointers unset), in which case the
* data buffers will be allocated by this function using av_frame_get_buffer().
* If dst->format is set, then this format will be used, otherwise (when
* dst->format is AV_PIX_FMT_NONE) the first acceptable format will be chosen.
*
* @param dst the destination frame. dst is not touched on failure.
* @param src the source frame.
* @param flags currently unused, should be set to zero
* @return 0 on success, a negative AVERROR error code on failure.
*/
int
av_hwframe_transfer_data
(
AVFrame
*
dst
,
const
AVFrame
*
src
,
int
flags
);
enum
AVHWFrameTransferDirection
{
/**
* Transfer the data from the queried hw frame.
*/
AV_HWFRAME_TRANSFER_DIRECTION_FROM
,
/**
* Transfer the data to the queried hw frame.
*/
AV_HWFRAME_TRANSFER_DIRECTION_TO
,
};
/**
* Get a list of possible source or target formats usable in
* av_hwframe_transfer_data().
*
* @param hwframe_ctx the frame context to obtain the information for
* @param dir the direction of the transfer
* @param formats the pointer to the output format list will be written here.
* The list is terminated with AV_PIX_FMT_NONE and must be freed
* by the caller when no longer needed using av_free().
* If this function returns successfully, the format list will
* have at least one item (not counting the terminator).
* On failure, the contents of this pointer are unspecified.
* @param flags currently unused, should be set to zero
* @return 0 on success, a negative AVERROR code on failure.
*/
int
av_hwframe_transfer_get_formats
(
AVBufferRef
*
hwframe_ctx
,
enum
AVHWFrameTransferDirection
dir
,
enum
AVPixelFormat
**
formats
,
int
flags
);
#endif
/* AVUTIL_HWCONTEXT_H */
libavutil/hwcontext_internal.h
0 → 100644
View file @
89923e41
/*
* 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
*/
#ifndef AVUTIL_HWCONTEXT_INTERNAL_H
#define AVUTIL_HWCONTEXT_INTERNAL_H
#include <stddef.h>
#include "buffer.h"
#include "hwcontext.h"
#include "frame.h"
#include "pixfmt.h"
typedef
struct
HWContextType
{
enum
AVHWDeviceType
type
;
const
char
*
name
;
/**
* An array of pixel formats supported by the AVHWFramesContext instances
* Terminated by AV_PIX_FMT_NONE.
*/
const
enum
AVPixelFormat
*
pix_fmts
;
/**
* size of the public hardware-specific context,
* i.e. AVHWDeviceContext.hwctx
*/
size_t
device_hwctx_size
;
/**
* size of the private data, i.e.
* AVHWDeviceInternal.priv
*/
size_t
device_priv_size
;
/**
* size of the public frame pool hardware-specific context,
* i.e. AVHWFramesContext.hwctx
*/
size_t
frames_hwctx_size
;
/**
* size of the private data, i.e.
* AVHWFramesInternal.priv
*/
size_t
frames_priv_size
;
int
(
*
device_init
)(
AVHWDeviceContext
*
ctx
);
void
(
*
device_uninit
)(
AVHWDeviceContext
*
ctx
);
int
(
*
frames_init
)(
AVHWFramesContext
*
ctx
);
void
(
*
frames_uninit
)(
AVHWFramesContext
*
ctx
);
int
(
*
frames_get_buffer
)(
AVHWFramesContext
*
ctx
,
AVFrame
*
frame
);
int
(
*
transfer_get_formats
)(
AVHWFramesContext
*
ctx
,
enum
AVHWFrameTransferDirection
dir
,
enum
AVPixelFormat
**
formats
);
int
(
*
transfer_data_to
)(
AVHWFramesContext
*
ctx
,
AVFrame
*
dst
,
const
AVFrame
*
src
);
int
(
*
transfer_data_from
)(
AVHWFramesContext
*
ctx
,
AVFrame
*
dst
,
const
AVFrame
*
src
);
}
HWContextType
;
struct
AVHWDeviceInternal
{
const
HWContextType
*
hw_type
;
void
*
priv
;
};
struct
AVHWFramesInternal
{
const
HWContextType
*
hw_type
;
void
*
priv
;
AVBufferPool
*
pool_internal
;
};
#endif
/* AVUTIL_HWCONTEXT_INTERNAL_H */
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