[vlc-commits] avcodec: split out and document vlc_va_t
Rémi Denis-Courmont
git at videolan.org
Sat Jul 20 13:33:02 CEST 2013
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Jul 20 14:27:25 2013 +0300| [b6dbbeaa7319d6d9af42ee4967160032a6ea4693] | committer: Rémi Denis-Courmont
avcodec: split out and document vlc_va_t
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b6dbbeaa7319d6d9af42ee4967160032a6ea4693
---
modules/codec/Modules.am | 2 +-
modules/codec/avcodec/va.c | 69 +++++++++++++++++++++++++++++++++++++++++
modules/codec/avcodec/va.h | 66 +++++++++++++++++++++++++++++++++++++--
modules/codec/avcodec/video.c | 44 --------------------------
4 files changed, 133 insertions(+), 48 deletions(-)
diff --git a/modules/codec/Modules.am b/modules/codec/Modules.am
index 09a1853..1a5999b 100644
--- a/modules/codec/Modules.am
+++ b/modules/codec/Modules.am
@@ -100,7 +100,7 @@ libavcodec_plugin_la_SOURCES = \
avcodec/cpu.c \
avcodec/fourcc.c \
avcodec/chroma.c avcodec/chroma.h \
- avcodec/va.h \
+ avcodec/va.c avcodec/va.h \
avcodec/avcodec.c avcodec/avcodec.h
if ENABLE_SOUT
libavcodec_plugin_la_SOURCES += \
diff --git a/modules/codec/avcodec/va.c b/modules/codec/avcodec/va.c
new file mode 100644
index 0000000..94abb36
--- /dev/null
+++ b/modules/codec/avcodec/va.c
@@ -0,0 +1,69 @@
+/*****************************************************************************
+ * va.c: hardware acceleration plugins for avcodec
+ *****************************************************************************
+ * Copyright (C) 2009 Laurent Aimar
+ * Copyright (C) 2012-2013 Rémi Denis-Courmont
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <vlc_common.h>
+#include <vlc_modules.h>
+#include <libavcodec/avcodec.h>
+#include "va.h"
+
+static int vlc_va_Start(void *func, va_list ap)
+{
+ vlc_va_t *va = va_arg(ap, vlc_va_t *);
+ int codec = va_arg(ap, int);
+ const es_format_t *fmt = va_arg(ap, const es_format_t *);
+ int (*open)(vlc_va_t *, int, const es_format_t *) = func;
+
+ return open(va, codec, fmt);
+}
+
+static void vlc_va_Stop(void *func, va_list ap)
+{
+ vlc_va_t *va = va_arg(ap, vlc_va_t *);
+ void (*close)(vlc_va_t *) = func;
+
+ close(va);
+}
+
+vlc_va_t *vlc_va_New(vlc_object_t *obj, int codec_id, const es_format_t *fmt)
+{
+ vlc_va_t *va = vlc_object_create(obj, sizeof (*va));
+ if (unlikely(va == NULL))
+ return NULL;
+
+ va->module = vlc_module_load(va, "hw decoder", "$avcodec-hw", true,
+ vlc_va_Start, va, codec_id, fmt);
+ if (va->module == NULL)
+ {
+ vlc_object_release(va);
+ va = NULL;
+ }
+ return va;
+}
+
+void vlc_va_Delete(vlc_va_t *va)
+{
+ vlc_module_unload(va->module, vlc_va_Stop, va);
+ vlc_object_release(va);
+}
diff --git a/modules/codec/avcodec/va.h b/modules/codec/avcodec/va.h
index f564e1f..976000b 100644
--- a/modules/codec/avcodec/va.h
+++ b/modules/codec/avcodec/va.h
@@ -21,8 +21,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
-#ifndef _VLC_VA_H
-#define _VLC_VA_H 1
+#ifndef VLC_AVCODEC_VA_H
+#define VLC_AVCODEC_VA_H 1
typedef struct vlc_va_t vlc_va_t;
typedef struct vlc_va_sys_t vlc_va_sys_t;
@@ -42,22 +42,82 @@ struct vlc_va_t {
int (*extract)(vlc_va_t *, picture_t *dst, AVFrame *src);
};
+/**
+ * Creates an accelerated video decoding back-end for libavcodec.
+ * @param obj parent VLC object
+ * @param codec_id libavcodec codec ID of the content to decode
+ * @param fmt VLC format of the content to decode
+ * @return a new VLC object on success, NULL on error.
+ */
+vlc_va_t *vlc_va_New(vlc_object_t *obj, int codec_id, const es_format_t *fmt);
+
+/**
+ * Initializes the acceleration video decoding back-end for libavcodec.
+ * @param hw pointer to libavcodec hardware context pointer [OUT]
+ * @param output pointer to video chroma output by the back-end [OUT]
+ * @param width coded video width in pixels
+ * @param height coded video height in pixels
+ * @return VLC_SUCCESS on success, otherwise an error code.
+ */
static inline int vlc_va_Setup(vlc_va_t *va, void **hw, vlc_fourcc_t *output,
- int width, int height)
+ int width, int height)
{
return va->setup(va, hw, output, width, height);
}
+
+/**
+ * Allocates a hardware video surface for a libavcodec frame.
+ * The surface will be used as output for the hardware decoder, and possibly
+ * also as a reference frame to decode other surfaces.
+ *
+ * @note This function needs not be reentrant. However it may be called
+ * concurrently with vlc_va_Extract() and/or vlc_va_Release() from other
+ * threads and other frames.
+ *
+ * @param frame libavcodec frame [IN/OUT]
+ * @return VLC_SUCCESS on success, otherwise an error code.
+ */
static inline int vlc_va_Get(vlc_va_t *va, AVFrame *frame)
{
return va->get(va, frame);
}
+
+/**
+ * Releases a hardware surface from a libavcodec frame.
+ * The surface has been previously allocated with vlc_va_Get().
+ *
+ * @note This function needs not be reentrant. However it may be called
+ * concurrently with vlc_va_Get() and/or vlc_va_Extract() from other threads
+ * and other frames.
+ *
+ * @param frame libavcodec frame previously allocated by vlc_va_Get()
+ */
static inline void vlc_va_Release(vlc_va_t *va, AVFrame *frame)
{
va->release(va, frame);
}
+
+/**
+ * Extracts a hardware surface from a libavcodec frame into a VLC picture.
+ * The surface has been previously allocated with vlc_va_Get() and decoded
+ * by the libavcodec hardware acceleration.
+ * The surface may still be used by libavcodec as a reference frame until it is
+ * freed with vlc_va_Release().
+ *
+ * @note This function needs not be reentrant, but it may run concurrently with
+ * vlc_va_Get() or vlc_va_Release() in other threads (with distinct frames).
+ *
+ * @param frame libavcodec frame previously allocated by vlc_va_Get()
+ */
static inline int vlc_va_Extract(vlc_va_t *va, picture_t *dst, AVFrame *src)
{
return va->extract(va, dst, src);
}
+/**
+ * Destroys a libavcodec hardware acceleration back-end.
+ * All allocated surfaces shall have been released beforehand.
+ */
+void vlc_va_Delete(vlc_va_t *);
+
#endif
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 3e10808..384aae6 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -33,7 +33,6 @@
#include <vlc_codec.h>
#include <vlc_avcodec.h>
#include <vlc_cpu.h>
-#include <vlc_modules.h>
#include <assert.h>
#include <libavcodec/avcodec.h>
@@ -107,7 +106,6 @@ static int ffmpeg_GetFrameBuf ( struct AVCodecContext *, AVFrame * );
static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *, AVFrame * );
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *,
const enum PixelFormat * );
-static void vlc_va_Delete( vlc_va_t * );
static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc )
{
@@ -1063,48 +1061,6 @@ static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,
p_ff_pic->data[i] = NULL;
}
-static int ffmpeg_va_Start( void *func, va_list ap )
-{
- vlc_va_t *va = va_arg( ap, vlc_va_t * );
- int codec = va_arg( ap, int );
- const es_format_t *fmt = va_arg( ap, const es_format_t * );
- int (*open)( vlc_va_t *, int, const es_format_t * ) = func;
-
- return open( va, codec, fmt );
-}
-
-static vlc_va_t *vlc_va_New( vlc_object_t *parent, int codec_id,
- const es_format_t *fmt )
-{
- vlc_va_t *p_va = vlc_object_create( parent, sizeof( *p_va ) );
- if( unlikely(p_va == NULL) )
- return NULL;
-
- p_va->module = vlc_module_load( p_va, "hw decoder", "$avcodec-hw",
- true, ffmpeg_va_Start, p_va,
- codec_id, fmt );
- if( p_va->module == NULL )
- {
- vlc_object_release( p_va );
- p_va = NULL;
- }
- return p_va;
-}
-
-static void ffmpeg_va_Stop( void *func, va_list ap )
-{
- vlc_va_t *va = va_arg( ap, vlc_va_t * );
- void (*close)( vlc_va_t * ) = func;
-
- close( va );
-}
-
-static void vlc_va_Delete( vlc_va_t *va )
-{
- vlc_module_unload( va->module, ffmpeg_va_Stop, va );
- vlc_object_release( va );
-}
-
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
const enum PixelFormat *pi_fmt )
{
More information about the vlc-commits
mailing list