Commit b6dbbeaa authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont
Browse files

avcodec: split out and document vlc_va_t

parent 6a4b499a
......@@ -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 += \
......
/*****************************************************************************
* 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);
}
......@@ -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
......@@ -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 )
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment