Skip to content

Commit

Permalink
add dxva2 decoder. still have bugs
Browse files Browse the repository at this point in the history
bugs:
1. memory leak
2. sometimes crash. can not open 2 players, or other players using hw.
Assertion abs(src_linesize) >= bytewidth failed at libavutil/imgutils.c:
  • Loading branch information
wang-bin committed Nov 27, 2013
1 parent 0e78072 commit 3e432a7
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 37 deletions.
3 changes: 3 additions & 0 deletions QtAV.pro
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ OTHER_FILES += \
EssentialDepends = avutil avcodec avformat swscale
OptionalDepends = portaudio direct2d gdiplus gl \
swresample avresample
win32 {
OptionalDepends += dxva
}
unix {
OptionalDepends += xv
}
Expand Down
4 changes: 4 additions & 0 deletions config.tests/dxva/dxva.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CONFIG -= qt
CONFIG += console

SOURCES += main.cpp
42 changes: 42 additions & 0 deletions config.tests/dxva/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2013 Wang Bin <[email protected]>
* This file is part of QtAV
This library 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 library 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 library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/

extern "C" {
#include <libavcodec/dxva2.h> //will include d3d9.h, dxva2api.h
}
#define VA_DXVA2_MAX_SURFACE_COUNT (64)

#include <d3d9.h>
#include <dxva2api.h>

#define MS_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
static const GUID name = { l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}}
#ifdef __MINGW32__
# include <_mingw.h>
# if defined(__MINGW64_VERSION_MAJOR)
# include <dxva.h>
# endif
#endif /* __MINGW32__ */

int main()
{
return 0;
}
9 changes: 8 additions & 1 deletion src/QtAV/VideoDecoderTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,16 @@

namespace QtAV {

/*!
* \brief GetRegisted
* \return count of available id
* if pass a null ids, only return the count. otherwise regitered ids will be stored in ids
*/
int GetRegisted(VideoDecoderId** ids = 0, int inSize = -1);

extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_FFmpeg;
extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_CUDA;
extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_FFmpeg_DXVA;
extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_DXVA;
extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_FFmpeg_VAAPI;
extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_FFmpeg_VDPAU;
extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_FFmpeg_VDA;
Expand Down
6 changes: 4 additions & 2 deletions src/VideoDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ namespace QtAV {
FACTORY_DEFINE(VideoDecoder)

extern void RegisterVideoDecoderFFmpeg_Man();
extern void RegisterVideoDecoderFFmpeg_DXVA_Man();
extern void RegisterVideoDecoderDXVA_Man();

void VideoDecoder_RegisterAll()
{
RegisterVideoDecoderFFmpeg_Man();
//RegisterVideoDecoderFFmpeg_DXVA_Man();
#if QTAV_HAVE(DXVA)
RegisterVideoDecoderDXVA_Man();
#endif //QTAV_HAVE(DXVA)
}


Expand Down
52 changes: 26 additions & 26 deletions src/VideoDecoderFFmpegDXVA.cpp → src/VideoDecoderDXVA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,26 +121,26 @@ DEFINE_GUID(DXVA_ModeMPEG4pt2_VLD_AdvSimple_Avivo, 0x7C74ADC6, 0xe2ba, 0x4ade,

namespace QtAV {

class VideoDecoderFFmpeg_DXVAPrivate;
class VideoDecoderFFmpeg_DXVA : public VideoDecoder
class VideoDecoderDXVAPrivate;
class VideoDecoderDXVA : public VideoDecoder
{
DPTR_DECLARE_PRIVATE(VideoDecoderFFmpeg_DXVA)
DPTR_DECLARE_PRIVATE(VideoDecoderDXVA)
public:
VideoDecoderFFmpeg_DXVA();
virtual ~VideoDecoderFFmpeg_DXVA();
VideoDecoderDXVA();
virtual ~VideoDecoderDXVA();
virtual bool prepare();
virtual bool open();
virtual bool close();
virtual bool decode(const QByteArray &encoded);
virtual VideoFrame frame();
};

extern VideoDecoderId VideoDecoderId_FFmpeg_DXVA;
FACTORY_REGISTER_ID_AUTO(VideoDecoder, FFmpeg_DXVA, "DXVA(FFmpeg)")
extern VideoDecoderId VideoDecoderId_DXVA;
FACTORY_REGISTER_ID_AUTO(VideoDecoder, DXVA, "DXVA(FFmpeg)")

void RegisterVideoDecoderFFmpeg_DXVA_Man()
void RegisterVideoDecoderDXVA_Man()
{
FACTORY_REGISTER_ID_MAN(VideoDecoder, FFmpeg_DXVA, "DXVA(FFmpeg)")
FACTORY_REGISTER_ID_MAN(VideoDecoder, DXVA, "DXVA(FFmpeg)")
}

typedef struct {
Expand Down Expand Up @@ -267,15 +267,15 @@ static QString DxDescribe(D3DADAPTER_IDENTIFIER9 *id) //vlc_va_dxva2_t *va
}


class VideoDecoderFFmpeg_DXVAPrivate : public VideoDecoderPrivate
class VideoDecoderDXVAPrivate : public VideoDecoderPrivate
{
public:
VideoDecoderFFmpeg_DXVAPrivate():
VideoDecoderDXVAPrivate():
VideoDecoderPrivate()
{
available = loadDll();
}
virtual ~VideoDecoderFFmpeg_DXVAPrivate()
virtual ~VideoDecoderDXVAPrivate()
{
unloadDll();
}
Expand Down Expand Up @@ -758,7 +758,7 @@ class VideoDecoderFFmpeg_DXVAPrivate : public VideoDecoderPrivate
/* FIXME it is nearly common with VAAPI */
static int ffmpeg_get_dxva2_buffer(struct AVCodecContext *c, AVFrame *ff)//vlc_va_t *external, AVFrame *ff)
{
VideoDecoderFFmpeg_DXVAPrivate* va = (VideoDecoderFFmpeg_DXVAPrivate*)c->opaque;
VideoDecoderDXVAPrivate* va = (VideoDecoderDXVAPrivate*)c->opaque;
/* */
ff->opaque = NULL;
#if ! LIBAVCODEC_VERSION_CHECK(54, 34, 0, 79, 101)
Expand Down Expand Up @@ -811,7 +811,7 @@ static int ffmpeg_get_dxva2_buffer(struct AVCodecContext *c, AVFrame *ff)//vlc_v

static void ffmpeg_release_buffer(struct AVCodecContext *p_context, AVFrame *ff)
{
VideoDecoderFFmpeg_DXVAPrivate *va = (VideoDecoderFFmpeg_DXVAPrivate*)p_context->opaque;
VideoDecoderDXVAPrivate *va = (VideoDecoderDXVAPrivate*)p_context->opaque;
LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)ff->data[3];
for (unsigned i = 0; i < va->surface_count; i++) {
vlc_va_surface_t *surface = &va->surface[i];
Expand All @@ -831,7 +831,7 @@ static AVPixelFormat ffmpeg_get_dxva2_format(struct AVCodecContext *p_context, c
}
return fmt[0];
*/
VideoDecoderFFmpeg_DXVAPrivate *p_va = (VideoDecoderFFmpeg_DXVAPrivate*)p_context->opaque;
VideoDecoderDXVAPrivate *p_va = (VideoDecoderDXVAPrivate*)p_context->opaque;
p_va->setCodec(p_context->codec_id);
/* Profile and level informations are needed now.
* TODO: avoid code duplication with avcodec.c */
Expand Down Expand Up @@ -879,24 +879,24 @@ static AVPixelFormat ffmpeg_get_dxva2_format(struct AVCodecContext *p_context, c



VideoDecoderFFmpeg_DXVA::VideoDecoderFFmpeg_DXVA()
: VideoDecoder(*new VideoDecoderFFmpeg_DXVAPrivate())
VideoDecoderDXVA::VideoDecoderDXVA()
: VideoDecoder(*new VideoDecoderDXVAPrivate())
{
}

VideoDecoderFFmpeg_DXVA::~VideoDecoderFFmpeg_DXVA()
VideoDecoderDXVA::~VideoDecoderDXVA()
{
setCodecContext(0);
}

bool VideoDecoderFFmpeg_DXVA::prepare()
bool VideoDecoderDXVA::prepare()
{
return VideoDecoder::prepare();
}

bool VideoDecoderFFmpeg_DXVA::open()
bool VideoDecoderDXVA::open()
{
DPTR_D(VideoDecoderFFmpeg_DXVA);
DPTR_D(VideoDecoderDXVA);
if (!d.codec_ctx) {
qWarning("FFmpeg codec context not ready");
return false;
Expand Down Expand Up @@ -947,14 +947,14 @@ bool VideoDecoderFFmpeg_DXVA::open()
return true;
}

bool VideoDecoderFFmpeg_DXVA::close()
bool VideoDecoderDXVA::close()
{
DPTR_D(VideoDecoderFFmpeg_DXVA);
DPTR_D(VideoDecoderDXVA);
d.close();
return VideoDecoder::close();
}

bool VideoDecoderFFmpeg_DXVA::decode(const QByteArray &encoded)
bool VideoDecoderDXVA::decode(const QByteArray &encoded)
{
if (!isAvailable())
return false;
Expand Down Expand Up @@ -985,9 +985,9 @@ bool VideoDecoderFFmpeg_DXVA::decode(const QByteArray &encoded)
return true;
}

VideoFrame VideoDecoderFFmpeg_DXVA::frame()
VideoFrame VideoDecoderDXVA::frame()
{
DPTR_D(VideoDecoderFFmpeg_DXVA);
DPTR_D(VideoDecoderDXVA);
if (d.width <= 0 || d.height <= 0 || !d.codec_ctx)
return VideoFrame(0, 0, VideoFormat(VideoFormat::Format_Invalid));
/*
Expand Down
4 changes: 2 additions & 2 deletions src/VideoDecoderTypes.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "VideoDecoderTypes.h"
#include "QtAV/VideoDecoderTypes.h"

namespace QtAV {

VideoDecoderId VideoDecoderId_FFmpeg = 0;
VideoDecoderId VideoDecoderId_CUDA = 1;
VideoDecoderId VideoDecoderId_FFmpeg_DXVA = 2;
VideoDecoderId VideoDecoderId_DXVA = 2;

} //namespace QtAV
12 changes: 6 additions & 6 deletions src/libQtAV.pro
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ TARGET = QtAV

QT += core gui
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets gui-private
QT += widgets
*linux*: gui-private
}

CONFIG *= qtav-buildlib
Expand Down Expand Up @@ -53,7 +54,6 @@ config_avresample {
SOURCES += AudioResamplerLibav.cpp
LIBS += -lavresample
}

ipp-link {
DEFINES += IPP_LINK
ICCROOT = $$(IPPROOT)/../compiler
Expand All @@ -62,7 +62,6 @@ ipp-link {
-L$$(IPPROOT)/../compiler/lib/ia32 -L$$(IPPROOT)/../compiler/lib/intel64 -lsvml -limf
#omp for static link. _t is multi-thread static link
}

config_portaudio {
SOURCES += AOPortAudio.cpp
SDK_HEADERS += QtAV/AOPortAudio.h
Expand All @@ -78,15 +77,13 @@ config_openal {
win32:LIBS *= -lOpenAL32
else: LIBS *= -lopenal
}

config_gdiplus {
DEFINES *= QTAV_HAVE_GDIPLUS=1
SOURCES += GDIRenderer.cpp
HEADERS += QtAV/private/GDIRenderer_p.h
SDK_HEADERS += QtAV/GDIRenderer.h
LIBS += -lgdiplus -lGdi32
}

config_direct2d {
DEFINES *= QTAV_HAVE_DIRECT2D=1
!*msvc*: INCLUDEPATH += $$PROJECTROOT/contrib/d2d1headers
Expand All @@ -109,7 +106,10 @@ config_gl {
HEADERS += QtAV/private/GLWidgetRenderer_p.h
SDK_HEADERS += QtAV/GLWidgetRenderer.h
}

config_dxva {
DEFINES *= QTAV_HAVE_DXVA=1
SOURCES += VideoDecoderDXVA.cpp
}
SOURCES += \
QtAV_Compat.cpp \
QtAV_Global.cpp \
Expand Down

0 comments on commit 3e432a7

Please sign in to comment.