Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • gstreamer/gst-plugins-bad
  • thiblahute/gst-plugins-bad
  • slomo/gst-plugins-bad
  • sree/gst-plugins-bad
  • seungha.yang/gst-plugins-bad
  • xclaesse/gst-plugins-bad
  • haihao/gst-plugins-bad
  • Russel/gst-plugins-bad
  • heftig/gst-plugins-bad
  • joshuadoe/gst-plugins-bad
  • bilboed/gst-plugins-bad
  • ndufresne/gst-plugins-bad
  • ystreet/gst-plugins-bad
  • hgr/gst-plugins-bad
  • nielsdg/gst-plugins-bad
  • Brad/gst-plugins-bad
  • alatiera/gst-plugins-bad
  • SiewHoon/gst-plugins-bad
  • joykim/gst-plugins-bad
  • edholland/gst-plugins-bad
  • jh-hsd/gst-plugins-bad
  • lpendresen/gst-plugins-bad
  • daniels/gst-plugins-bad
  • nirbheek/gst-plugins-bad
  • tchakabam/gst-plugins-bad
  • wangfei/gst-plugins-bad
  • mangix/gst-plugins-bad
  • gdesmott/gst-plugins-bad
  • jonakn/gst-plugins-bad
  • Yeongjin-Jeong/gst-plugins-bad
  • harshadkhedkar/gst-plugins-bad
  • vjaquez/gst-plugins-bad
  • tpm/gst-plugins-bad
  • drakkan/gst-plugins-bad
  • milloni-ct/gst-plugins-bad
  • wonchul/gst-plugins-bad
  • philn/gst-plugins-bad
  • patricia/gst-plugins-bad
  • alexashley/gst-plugins-bad
  • gkiagia/gst-plugins-bad
  • dong9/gst-plugins-bad
  • michaelgruner/gst-plugins-bad
  • ikreymer/gst-plugins-bad
  • donghyeok/gst-plugins-bad
  • ullysses.a.eoff/gst-plugins-bad
  • CarlFK/gst-plugins-bad
  • ding/gst-plugins-bad
  • meh/gst-plugins-bad
  • victortoso/gst-plugins-bad
  • valbok/gst-plugins-bad
  • joel-holdsworth/gst-plugins-bad
  • jdm/gst-plugins-bad
  • thaytan/gst-plugins-bad
  • yangcha/gst-plugins-bad
  • ThomasSchlien/gst-plugins-bad
  • boxerab/gst-plugins-bad
  • den_erpel/gst-plugins-bad
  • alyyousuf7/gst-plugins-bad
  • andrey-konovalov/gst-plugins-bad
  • mvlad/gst-plugins-bad
  • JimmyOhn/gst-plugins-bad
  • chturne/gst-plugins-bad
  • yskkmi/gst-plugins-bad
  • vivia/gst-plugins-bad
  • billylindeman/gst-plugins-bad
  • nacho.garglez/gst-plugins-bad
  • MaZderMind/gst-plugins-bad
  • david.lee/gst-plugins-bad
  • JaredHu/gst-plugins-bad
  • ulfo/gst-plugins-bad
  • fuweitax/gst-plugins-bad
  • calvaris/gst-plugins-bad
  • codinho/gst-plugins-bad
  • lord.jacold/gst-plugins-bad
  • adn770/gst-plugins-bad
  • ayaka/gst-plugins-bad
  • kevinbing.song/gst-plugins-bad
  • billconan/gst-plugins-bad
  • psreport/gst-plugins-bad
  • welaq/gst-plugins-bad
  • dank/gst-plugins-bad
  • raytiley/gst-plugins-bad
  • myungjoo/gst-plugins-bad
  • fabio-d/gst-plugins-bad
  • marcosk/gst-plugins-bad
  • nh2/gst-plugins-bad
  • creiter/gst-plugins-bad
  • mnauw/gst-plugins-bad
  • dv1/gst-plugins-bad
  • santoscadenas/gst-plugins-bad
  • dabrain34/gst-plugins-bad
  • taylor.patton/gst-plugins-bad
  • edersondisouza/gst-plugins-bad
  • GNUDimarik/gst-plugins-bad
  • Aduskett/gst-plugins-bad
  • aleksandrm8/gst-plugins-bad
  • OleksandrKvl/gst-plugins-bad
  • autintim/gst-plugins-bad
  • charles/gst-plugins-bad
  • floobleflam/gst-plugins-bad
  • lantw/gst-plugins-bad
  • bellet/gst-plugins-bad
  • marxin.liska/gst-plugins-bad
  • therimar/gst-plugins-bad
  • xhaakon/gst-plugins-bad
  • zeidbekli48/gst-plugins-bad
  • okajun/gst-plugins-bad
  • szve/gst-plugins-bad
  • dougnazar/gst-plugins-bad
  • nacho.resa/gst-plugins-bad
  • pfy/gst-plugins-bad
  • coldtom/gst-plugins-bad
  • ankurdeepjaiswal/gst-plugins-bad
  • fdavulcu/gst-plugins-bad
  • lemenkov/gst-plugins-bad
  • Pyrrhvs/gst-plugins-bad
  • wangyan42164/gst-plugins-bad
  • tezcatli/gst-plugins-bad
  • ssaito/gst-plugins-bad
  • slabajo/gst-plugins-bad
  • hq/gst-plugins-bad
  • peat-psuwit/gst-plugins-bad
  • mol/gst-plugins-bad
  • luisbg/gst-plugins-bad
  • zubzub/gst-plugins-bad
  • fabiangreffrath/gst-plugins-bad
  • davidph/gst-plugins-bad
  • pH5/gst-plugins-bad
  • jmaibaum/gst-plugins-bad
  • aleb/gst-plugins-bad
  • jcelaya/gst-plugins-bad
  • StefanBruens/gst-plugins-bad
  • abranson/gst-plugins-bad
  • cap/gst-plugins-bad
  • ihalip/gst-plugins-bad
  • vedangpatel1/gst-plugins-bad
  • ali1234/gst-plugins-bad
  • jgilje/gst-plugins-bad
  • He_Junyan/gst-plugins-bad
  • aguedes/gst-plugins-bad
  • francisv/gst-plugins-bad
  • t/gst-plugins-bad
  • hwilkes/gst-plugins-bad
  • thiagossantos/gst-plugins-bad
  • linussn/gst-plugins-bad
  • Hosang/gst-plugins-bad
  • rob_gries/gst-plugins-bad
  • o0Ignition0o/gst-plugins-bad
  • ntrrgc/gst-plugins-bad
  • neithanmo/gst-plugins-bad
  • andrew.voznytsa/gst-plugins-bad
  • sf2020/gst-plugins-bad
  • danisla/gst-plugins-bad
  • juzza_uk/gst-plugins-bad
  • fraxinas/gst-plugins-bad
  • Arhno/gst-plugins-bad
  • leio/gst-plugins-bad
  • guillerodriguez/gst-plugins-bad
  • krivoguzovVlad/gst-plugins-bad
  • ludvigr/gst-plugins-bad
  • nazar-pc/gst-plugins-bad
  • Buora/gst-plugins-bad
  • heinrich.kruger/gst-plugins-bad
  • motownread/gst-plugins-bad
  • jwestman/gst-plugins-bad
  • paulyc/gst-plugins-bad
  • balte/gst-plugins-bad
  • jurijs.satcs/gst-plugins-bad
  • rgonzalez/gst-plugins-bad
  • antonovitch/gst-plugins-bad
  • jan.vermaete/gst-plugins-bad
  • XuGuangxin/gst-plugins-bad
  • 123vivekr/gst-plugins-bad
  • decembersoul/gst-plugins-bad
  • mparisdiaz/gst-plugins-bad
  • worldofpeace/gst-plugins-bad
  • achris/gst-plugins-bad
  • nanonyme/gst-plugins-bad
  • arun/gst-plugins-bad
  • DuBistKomisch/gst-plugins-bad
  • lblasc/gst-plugins-bad
  • ahoenig/gst-plugins-bad
  • Mats/gst-plugins-bad
  • Andruxin52rus/gst-plugins-bad
  • cketti/gst-plugins-bad
  • MM_Star/gst-plugins-bad
  • Chikushu/gst-plugins-bad
  • daniel.qtec/gst-plugins-bad
  • 4kevinking/gst-plugins-bad
  • fritzprix/gst-plugins-bad
  • dhobsong/gst-plugins-bad
  • rambden/gst-plugins-bad
  • razvanphp/gst-plugins-bad
  • foreverneilyoung/gst-plugins-bad
  • wtaymans/gst-plugins-bad
  • ezequielgarcia/gst-plugins-bad
  • trollkarlen/gst-plugins-bad
  • jedevc/gst-plugins-bad
  • jusizela/gst-plugins-bad
  • karim.davoodi/gst-plugins-bad
  • quaresma.jose/gst-plugins-bad
  • felixonmars/gst-plugins-bad
  • louisharris/gst-plugins-bad
  • lmurillo/gst-plugins-bad
  • trilene/gst-plugins-bad
  • jlaheurte/gst-plugins-bad
  • jmatthew/gst-plugins-bad
  • wilkinsw/gst-plugins-bad
  • yychao/gst-plugins-bad
  • eckhart.koppen/gst-plugins-bad
  • AdamW/gst-plugins-bad
  • SanchayanMaity/gst-plugins-bad
  • twischer/gst-plugins-bad
  • marian/gst-plugins-bad
  • linkmauve/gst-plugins-bad
  • gvanmeter/gst-plugins-bad
  • julian/gst-plugins-bad
  • raghu447/gst-plugins-bad
  • TobiasR/gst-plugins-bad
  • MoizAhmedd/gst-plugins-bad
  • gstreamer-release-bot/gst-plugins-bad
  • artectrex/gst-plugins-bad
  • Rafostar/gst-plugins-bad
  • mindriot88/gst-plugins-bad
  • mexxik/gst-plugins-bad
  • robin.carlisle/gst-plugins-bad
  • MarijnS95/gst-plugins-bad
  • igor.v.kovalenko/gst-plugins-bad
  • chriswiggins/gst-plugins-bad
  • johast/gst-plugins-bad
  • fauxsoup1/gst-plugins-bad
  • ekwange/gst-plugins-bad
  • raju.babannavar/gst-plugins-bad
  • eater/gst-plugins-bad
  • ds/gst-plugins-bad
  • avantgardnerio/gst-plugins-bad
  • marsupial/gst-plugins-bad
  • ignacy.ruksza/gst-plugins-bad
  • t-8ch/gst-plugins-bad
  • trey.hutcheson/gst-plugins-bad
  • ssanders1449/gst-plugins-bad
  • stazio/gst-plugins-bad
  • obbardc/gst-plugins-bad
  • dwlsalmeida/gst-plugins-bad
  • benjamin.gaignard1/gst-plugins-bad
  • AntoninRousset/gst-plugins-bad
  • AdhBash816/gst-plugins-bad
  • jjanku/gst-plugins-bad
  • liuyinhangx/gst-plugins-bad
  • AdvanceSoftware/gst-plugins-bad
  • jn/gst-plugins-bad
  • wantlamy/gst-plugins-bad
  • hjanuschka/gst-plugins-bad
  • Nei/gst-plugins-bad
  • arojas/gst-plugins-bad
  • zhao-gang/gst-plugins-bad
  • sid.sethupathi/gst-plugins-bad
  • mkba/gst-plugins-bad
  • YakoYakoYokuYoku/gst-plugins-bad
  • CartoonFan/gst-plugins-bad
  • rsiv/gst-plugins-bad
  • martinetd/gst-plugins-bad
  • reynaldo/gst-plugins-bad
  • kay0u1/gst-plugins-bad
  • thongthai/gst-plugins-bad
  • spartazhc/gst-plugins-bad
  • leeys888/gst-plugins-bad
  • ferruck/gst-plugins-bad
  • benjamin545/gst-plugins-bad
  • budziq/gst-plugins-bad
  • madsbuvi/gst-plugins-bad
  • agx/gst-plugins-bad
  • amotzte/gst-plugins-bad
  • devarsht/gst-plugins-bad
  • kimtinh/gst-plugins-bad
  • lshuying/gst-plugins-bad
  • rsnk96/gst-plugins-bad
  • mortimergoro/gst-plugins-bad
  • cfoch/gst-plugins-bad
  • jfelder/gst-plugins-bad
  • kathirvel621/gst-plugins-bad
  • bradh/gst-plugins-bad
  • middelschultele/gst-plugins-bad
  • pocock/gst-plugins-bad
  • marex/gst-plugins-bad
  • vivienne/gst-plugins-bad
  • pldin601/gst-plugins-bad
  • heirecka/gst-plugins-bad
  • Casey-Bateman/gst-plugins-bad
  • adrianf0/gst-plugins-bad
  • ovchinnikov.dmitrii/gst-plugins-bad
  • DimStar77/gst-plugins-bad
  • intelfx/gst-plugins-bad
  • derschueddi/gst-plugins-bad
  • driss.el.bouhali/gst-plugins-bad
  • jinsl00000/gst-plugins-bad
  • Wenlin/gst-plugins-bad
  • carra8674/gst-plugins-bad
  • ssdeng6812/gst-plugins-bad
  • glepag1/gst-plugins-bad
  • cnhzcy14/gst-plugins-bad
  • HuQian/gst-plugins-bad
  • Zhipeng/gst-plugins-bad
  • Harikrishnan/gst-plugins-bad
  • benjaminGraef/gst-plugins-bad
  • vnguyentrong/gst-plugins-bad
306 results
Show changes
Commits on Source (17)
Showing
with 1028 additions and 412 deletions
......@@ -71,22 +71,6 @@ typedef struct _GstD3D11BufferPoolPrivate GstD3D11BufferPoolPrivate;
typedef struct _GstD3D11Format GstD3D11Format;
typedef struct _GstD3D11BaseFilter GstD3D11BaseFilter;
typedef struct _GstD3D11BaseFilterClass GstD3D11BaseFilterClass;
typedef struct _GstD3D11Upload GstD3D11Upload;
typedef struct _GstD3D11UploadClass GstD3D11UploadClass;
typedef struct _GstD3D11Download GstD3D11Download;
typedef struct _GstD3D11DownloadClass GstD3D11DownloadClass;
typedef struct _GstD3D11ColorConvert GstD3D11ColorConvert;
typedef struct _GstD3D11ColorConvertClass GstD3D11ColorConvertClass;
typedef struct _GstD3D11Decoder GstD3D11Decoder;
typedef struct _GstD3D11DecoderClass GstD3D11DecoderClass;
typedef struct _GstD3D11DecoderPrivate GstD3D11DecoderPrivate;
G_END_DECLS
#endif /* __GST_D3D11_FWD_H__ */
......@@ -36,6 +36,9 @@ G_BEGIN_DECLS
#define GST_IS_D3D11_BASE_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_D3D11_BASE_FILTER))
#define GST_D3D11_BASE_FILTER_CAST(obj) ((GstD3D11BaseFilter*)(obj))
typedef struct _GstD3D11BaseFilter GstD3D11BaseFilter;
typedef struct _GstD3D11BaseFilterClass GstD3D11BaseFilterClass;
struct _GstD3D11BaseFilter
{
GstBaseTransform parent;
......@@ -60,6 +63,8 @@ struct _GstD3D11BaseFilterClass
GType gst_d3d11_base_filter_get_type (void);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstD3D11BaseFilter, gst_object_unref)
G_END_DECLS
#endif /* __GST_D3D11_BASE_FILTER_H__ */
......@@ -24,6 +24,9 @@
#include "gstd3d11bufferpool.h"
#include "gstd3d11memory.h"
#include "gstd3d11device.h"
#include "gstd3d11utils.h"
#include <string.h>
GST_DEBUG_CATEGORY_STATIC (gst_d3d11_buffer_pool_debug);
#define GST_CAT_DEFAULT gst_d3d11_buffer_pool_debug
......@@ -33,11 +36,12 @@ struct _GstD3D11BufferPoolPrivate
GstD3D11Device *device;
GstD3D11Allocator *allocator;
/* initial buffer used for calculating buffer size */
GstBuffer *initial_buffer;
gboolean add_videometa;
GstD3D11AllocationParams *d3d11_params;
gint stride[GST_VIDEO_MAX_PLANES];
gsize size[GST_VIDEO_MAX_PLANES];
gsize offset[GST_VIDEO_MAX_PLANES];
};
#define gst_d3d11_buffer_pool_parent_class parent_class
......@@ -87,7 +91,6 @@ gst_d3d11_buffer_pool_dispose (GObject * object)
gst_d3d11_allocation_params_free (priv->d3d11_params);
priv->d3d11_params = NULL;
gst_clear_buffer (&priv->initial_buffer);
gst_clear_object (&priv->device);
gst_clear_object (&priv->allocator);
......@@ -114,6 +117,7 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
GstAllocator *allocator = NULL;
gboolean ret = TRUE;
D3D11_TEXTURE2D_DESC *desc;
GstBuffer *staging_buffer;
gint i;
if (!gst_buffer_pool_config_get_params (config, &caps, NULL, &min_buffers,
......@@ -133,7 +137,6 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
if (!gst_buffer_pool_config_get_allocator (config, &allocator, NULL))
goto wrong_config;
gst_clear_buffer (&priv->initial_buffer);
gst_clear_object (&priv->allocator);
if (allocator) {
......@@ -227,14 +230,33 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
}
}
gst_d3d11_buffer_pool_alloc (pool, &priv->initial_buffer, NULL);
staging_buffer = gst_d3d11_allocate_staging_buffer (priv->allocator,
&info, priv->d3d11_params->d3d11_format, priv->d3d11_params->desc, TRUE);
if (!priv->initial_buffer) {
GST_ERROR_OBJECT (pool, "Could not create initial buffer");
if (!staging_buffer) {
GST_ERROR_OBJECT (pool, "Couldn't allocated staging buffer");
return FALSE;
} else {
GstVideoMeta *meta = gst_buffer_get_video_meta (staging_buffer);
if (!meta) {
GST_ERROR_OBJECT (pool, "Buffer doesn't have video meta");
gst_buffer_unref (staging_buffer);
return FALSE;
}
for (i = 0; i < gst_buffer_n_memory (staging_buffer); i++) {
GstMemory *mem = gst_buffer_peek_memory (staging_buffer, i);
priv->size[i] = gst_memory_get_sizes (mem, NULL, NULL);
}
memcpy (priv->offset, meta->offset, sizeof (priv->offset));
memcpy (priv->stride, meta->stride, sizeof (priv->stride));
}
self->buffer_size = gst_buffer_get_size (priv->initial_buffer);
self->buffer_size = gst_buffer_get_size (staging_buffer);
gst_buffer_unref (staging_buffer);
gst_buffer_pool_config_set_params (config,
caps, self->buffer_size, min_buffers, max_buffers);
......@@ -275,34 +297,22 @@ gst_d3d11_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
GstBuffer *buf;
GstD3D11AllocationParams *d3d11_params = priv->d3d11_params;
GstVideoInfo *info = &d3d11_params->info;
GstVideoInfo *aligned_info = &d3d11_params->aligned_info;
gint n_texture = 0;
gint i;
gsize offset[GST_VIDEO_MAX_PLANES] = { 0, };
/* consume pre-allocated buffer if any */
if (G_UNLIKELY (priv->initial_buffer)) {
*buffer = priv->initial_buffer;
priv->initial_buffer = NULL;
return GST_FLOW_OK;
}
buf = gst_buffer_new ();
if (d3d11_params->d3d11_format->dxgi_format == DXGI_FORMAT_UNKNOWN) {
for (n_texture = 0; n_texture < GST_VIDEO_INFO_N_PLANES (info); n_texture++) {
d3d11_params->plane = n_texture;
mem = gst_d3d11_allocator_alloc (priv->allocator, d3d11_params);
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) {
mem = gst_d3d11_allocator_alloc (priv->allocator, &d3d11_params->desc[i],
d3d11_params->flags, priv->size[i]);
if (!mem)
goto error;
gst_buffer_append_memory (buf, mem);
}
} else {
d3d11_params->plane = 0;
mem = gst_d3d11_allocator_alloc (priv->allocator, priv->d3d11_params);
n_texture++;
mem = gst_d3d11_allocator_alloc (priv->allocator, &d3d11_params->desc[0],
d3d11_params->flags, priv->size[0]);
if (!mem)
goto error;
......@@ -310,18 +320,12 @@ gst_d3d11_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
gst_buffer_append_memory (buf, mem);
}
/* calculate offset */
for (i = 0; i < n_texture && i < GST_VIDEO_MAX_PLANES - 1; i++) {
offset[i + 1] = offset[i] +
d3d11_params->stride[i] * GST_VIDEO_INFO_COMP_HEIGHT (aligned_info, i);
}
if (priv->add_videometa) {
GST_DEBUG_OBJECT (self, "adding GstVideoMeta");
gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info),
offset, d3d11_params->stride);
priv->offset, priv->stride);
}
*buffer = buf;
......
......@@ -48,6 +48,7 @@
#endif
#include "gstd3d11colorconvert.h"
#include "gstd3d11colorconverter.h"
#include "gstd3d11utils.h"
#include "gstd3d11memory.h"
#include "gstd3d11device.h"
......@@ -78,6 +79,28 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_D3D11_SRC_FORMATS))
);
struct _GstD3D11ColorConvert
{
GstD3D11BaseFilter parent;
const GstD3D11Format *in_d3d11_format;
const GstD3D11Format *out_d3d11_format;
ID3D11Texture2D *in_texture[GST_VIDEO_MAX_PLANES];
ID3D11ShaderResourceView *shader_resource_view[GST_VIDEO_MAX_PLANES];
guint num_input_view;
ID3D11Texture2D *out_texture[GST_VIDEO_MAX_PLANES];
ID3D11RenderTargetView *render_target_view[GST_VIDEO_MAX_PLANES];
guint num_output_view;
GstD3D11ColorConverter *converter;
/* used for fallback texture copy */
D3D11_BOX in_src_box;
D3D11_BOX out_src_box;
};
#define gst_d3d11_color_convert_parent_class parent_class
G_DEFINE_TYPE (GstD3D11ColorConvert,
gst_d3d11_color_convert, GST_TYPE_D3D11_BASE_FILTER);
......
......@@ -23,45 +23,12 @@
#include <gst/gst.h>
#include "gstd3d11basefilter.h"
#include "gstd3d11colorconverter.h"
G_BEGIN_DECLS
#define GST_TYPE_D3D11_COLOR_CONVERT (gst_d3d11_color_convert_get_type())
#define GST_D3D11_COLOR_CONVERT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_D3D11_COLOR_CONVERT,GstD3D11ColorConvert))
#define GST_D3D11_COLOR_CONVERT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_D3D11_COLOR_CONVERT,GstD3D11ColorConvertClass))
#define GST_D3D11_COLOR_CONVERT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_D3D11_COLOR_CONVERT,GstD3D11ColorConvertClass))
#define GST_IS_D3D11_COLOR_CONVERT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_D3D11_COLOR_CONVERT))
#define GST_IS_D3D11_COLOR_CONVERT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_D3D11_COLOR_CONVERT))
struct _GstD3D11ColorConvert
{
GstD3D11BaseFilter parent;
const GstD3D11Format *in_d3d11_format;
const GstD3D11Format *out_d3d11_format;
ID3D11Texture2D *in_texture[GST_VIDEO_MAX_PLANES];
ID3D11ShaderResourceView *shader_resource_view[GST_VIDEO_MAX_PLANES];
guint num_input_view;
ID3D11Texture2D *out_texture[GST_VIDEO_MAX_PLANES];
ID3D11RenderTargetView *render_target_view[GST_VIDEO_MAX_PLANES];
guint num_output_view;
GstD3D11ColorConverter *converter;
/* used for fallback texture copy */
D3D11_BOX in_src_box;
D3D11_BOX out_src_box;
};
struct _GstD3D11ColorConvertClass
{
GstD3D11BaseFilterClass parent_class;
};
GType gst_d3d11_color_convert_get_type (void);
#define GST_TYPE_D3D11_COLOR_CONVERT (gst_d3d11_color_convert_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11ColorConvert,
gst_d3d11_color_convert, GST, D3D11_COLOR_CONVERT, GstD3D11BaseFilter);
G_END_DECLS
......
......@@ -28,19 +28,11 @@
G_BEGIN_DECLS
#define GST_TYPE_D3D11_DECODER \
(gst_d3d11_decoder_get_type())
#define GST_D3D11_DECODER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_D3D11_DECODER,GstD3D11Decoder))
#define GST_D3D11_DECODER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_D3D11_DECODER,GstD3D11DecoderClass))
#define GST_D3D11_DECODER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_D3D11_DECODER,GstD3D11DecoderClass))
#define GST_IS_D3D11_DECODER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_D3D11_DECODER))
#define GST_IS_D3D11_DECODER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_D3D11_DECODER))
#define GST_TYPE_D3D11_DECODER (gst_d3d11_decoder_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11Decoder,
gst_d3d11_decoder, GST, D3D11_DECODER, GstObject);
typedef struct _GstD3D11DecoderPrivate GstD3D11DecoderPrivate;
typedef struct _GstD3D11DecoderOutputView GstD3D11DecoderOutputView;
struct _GstD3D11DecoderOutputView
......@@ -84,13 +76,6 @@ struct _GstD3D11Decoder
gpointer padding[GST_PADDING_LARGE];
};
struct _GstD3D11DecoderClass
{
GstObjectClass parent_class;
};
GType gst_d3d11_decoder_get_type (void);
GstD3D11Decoder * gst_d3d11_decoder_new (GstD3D11Device * device);
gboolean gst_d3d11_decoder_open (GstD3D11Decoder * decoder,
......
......@@ -62,10 +62,21 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_D3D11_ALL_FORMATS)
));
struct _GstD3D11Download
{
GstD3D11BaseFilter parent;
GstBuffer *staging_buffer;
};
#define gst_d3d11_download_parent_class parent_class
G_DEFINE_TYPE (GstD3D11Download, gst_d3d11_download,
GST_TYPE_D3D11_BASE_FILTER);
static void gst_d3d11_download_dispose (GObject * object);
static gboolean gst_d3d11_download_stop (GstBaseTransform * trans);
static gboolean gst_d3d11_download_sink_event (GstBaseTransform * trans,
GstEvent * event);
static GstCaps *gst_d3d11_download_transform_caps (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps, GstCaps * filter);
static gboolean gst_d3d11_download_propose_allocation (GstBaseTransform * trans,
......@@ -74,12 +85,19 @@ static gboolean gst_d3d11_download_decide_allocation (GstBaseTransform * trans,
GstQuery * query);
static GstFlowReturn gst_d3d11_download_transform (GstBaseTransform * trans,
GstBuffer * inbuf, GstBuffer * outbuf);
static gboolean gst_d3d11_download_set_info (GstD3D11BaseFilter * filter,
GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
GstVideoInfo * out_info);
static void
gst_d3d11_download_class_init (GstD3D11DownloadClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass);
GstD3D11BaseFilterClass *bfilter_class = GST_D3D11_BASE_FILTER_CLASS (klass);
gobject_class->dispose = gst_d3d11_download_dispose;
gst_element_class_add_static_pad_template (element_class, &sink_template);
gst_element_class_add_static_pad_template (element_class, &src_template);
......@@ -91,6 +109,8 @@ gst_d3d11_download_class_init (GstD3D11DownloadClass * klass)
trans_class->passthrough_on_same_caps = TRUE;
trans_class->stop = GST_DEBUG_FUNCPTR (gst_d3d11_download_stop);
trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_d3d11_download_sink_event);
trans_class->transform_caps =
GST_DEBUG_FUNCPTR (gst_d3d11_download_transform_caps);
trans_class->propose_allocation =
......@@ -99,6 +119,8 @@ gst_d3d11_download_class_init (GstD3D11DownloadClass * klass)
GST_DEBUG_FUNCPTR (gst_d3d11_download_decide_allocation);
trans_class->transform = GST_DEBUG_FUNCPTR (gst_d3d11_download_transform);
bfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_d3d11_download_set_info);
GST_DEBUG_CATEGORY_INIT (gst_d3d11_download_debug,
"d3d11download", 0, "d3d11download Element");
}
......@@ -108,6 +130,43 @@ gst_d3d11_download_init (GstD3D11Download * download)
{
}
static void
gst_d3d11_download_dispose (GObject * object)
{
GstD3D11Download *self = GST_D3D11_DOWNLOAD (object);
gst_clear_buffer (&self->staging_buffer);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static gboolean
gst_d3d11_download_stop (GstBaseTransform * trans)
{
GstD3D11Download *self = GST_D3D11_DOWNLOAD (trans);
gst_clear_buffer (&self->staging_buffer);
return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
}
static gboolean
gst_d3d11_download_sink_event (GstBaseTransform * trans, GstEvent * event)
{
GstD3D11Download *self = GST_D3D11_DOWNLOAD (trans);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
/* We don't need to hold this staging buffer after eos */
gst_clear_buffer (&self->staging_buffer);
break;
default:
break;
}
return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
}
static GstCaps *
_set_caps_features (const GstCaps * caps, const gchar * feature_name)
{
......@@ -284,15 +343,63 @@ gst_d3d11_download_decide_allocation (GstBaseTransform * trans,
query);
}
static gboolean
gst_d3d11_download_can_use_staging_buffer (GstD3D11Download * self,
GstBuffer * inbuf)
{
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (self);
gint i;
/* staging buffer doesn't need to be used for non-d3d11 memory */
for (i = 0; i < gst_buffer_n_memory (inbuf); i++) {
GstMemory *mem = gst_buffer_peek_memory (inbuf, i);
if (!gst_is_d3d11_memory (mem))
return FALSE;
}
if (self->staging_buffer)
return TRUE;
self->staging_buffer = gst_d3d11_allocate_staging_buffer_for (inbuf,
&filter->in_info, TRUE);
if (!self->staging_buffer) {
GST_WARNING_OBJECT (self, "Couldn't allocate staging buffer");
return FALSE;
}
return TRUE;
}
static GstFlowReturn
gst_d3d11_download_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstBuffer * outbuf)
{
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
GstD3D11Download *self = GST_D3D11_DOWNLOAD (trans);
GstVideoFrame in_frame, out_frame;
GstFlowReturn ret = GST_FLOW_OK;
gboolean use_staging_buf;
GstBuffer *target_inbuf = inbuf;
gint i;
if (!gst_video_frame_map (&in_frame, &filter->in_info, inbuf,
use_staging_buf = gst_d3d11_download_can_use_staging_buffer (self, inbuf);
if (use_staging_buf) {
GST_TRACE_OBJECT (self, "Copy input buffer to staging buffer");
/* Copy d3d11 texture to staging texture */
if (!gst_d3d11_buffer_copy_into (self->staging_buffer, inbuf)) {
GST_ERROR_OBJECT (self,
"Failed to copy input buffer into staging texture");
return GST_FLOW_ERROR;
}
target_inbuf = self->staging_buffer;
}
if (!gst_video_frame_map (&in_frame, &filter->in_info, target_inbuf,
GST_MAP_READ | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))
goto invalid_buffer;
......@@ -305,14 +412,15 @@ gst_d3d11_download_transform (GstBaseTransform * trans, GstBuffer * inbuf,
for (i = 0; i < GST_VIDEO_FRAME_N_PLANES (&in_frame); i++) {
if (!gst_video_frame_copy_plane (&out_frame, &in_frame, i)) {
GST_ERROR_OBJECT (filter, "Couldn't copy %dth plane", i);
return GST_FLOW_ERROR;
ret = GST_FLOW_ERROR;
break;
}
}
gst_video_frame_unmap (&out_frame);
gst_video_frame_unmap (&in_frame);
return GST_FLOW_OK;
return ret;
/* ERRORS */
invalid_buffer:
......@@ -322,3 +430,15 @@ invalid_buffer:
return GST_FLOW_ERROR;
}
}
static gboolean
gst_d3d11_download_set_info (GstD3D11BaseFilter * filter,
GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
GstVideoInfo * out_info)
{
GstD3D11Download *self = GST_D3D11_DOWNLOAD (filter);
gst_clear_buffer (&self->staging_buffer);
return TRUE;
}
......@@ -24,24 +24,9 @@
G_BEGIN_DECLS
#define GST_TYPE_D3D11_DOWNLOAD (gst_d3d11_download_get_type())
#define GST_D3D11_DOWNLOAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_D3D11_DOWNLOAD,GstD3D11Download))
#define GST_D3D11_DOWNLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_D3D11_DOWNLOAD,GstD3D11DownloadClass))
#define GST_D3D11_DOWNLOAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_D3D11_DOWNLOAD,GstD3D11DownloadClass))
#define GST_IS_D3D11_DOWNLOAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_D3D11_DOWNLOAD))
#define GST_IS_D3D11_DOWNLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_D3D11_DOWNLOAD))
struct _GstD3D11Download
{
GstD3D11BaseFilter parent;
};
struct _GstD3D11DownloadClass
{
GstD3D11BaseFilterClass parent_class;
};
GType gst_d3d11_download_get_type (void);
#define GST_TYPE_D3D11_DOWNLOAD (gst_d3d11_download_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11Download,
gst_d3d11_download, GST, D3D11_DOWNLOAD, GstD3D11BaseFilter);
G_END_DECLS
......
......@@ -261,11 +261,55 @@ map_cpu_access_data (GstD3D11Memory * dmem, D3D11_MAP map_type)
return ret;
}
static gpointer
gst_d3d11_memory_map_staging (GstMemory * mem, GstMapFlags flags)
{
GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
g_mutex_lock (&dmem->lock);
if (dmem->cpu_map_count == 0) {
ID3D11DeviceContext *device_context =
gst_d3d11_device_get_device_context_handle (dmem->device);
D3D11_MAP map_type;
HRESULT hr;
gboolean ret = TRUE;
map_type = gst_map_flags_to_d3d11 (flags);
gst_d3d11_device_lock (dmem->device);
hr = ID3D11DeviceContext_Map (device_context,
(ID3D11Resource *) dmem->texture, 0, map_type, 0, &dmem->map);
if (!gst_d3d11_result (hr, dmem->device)) {
GST_ERROR_OBJECT (GST_MEMORY_CAST (dmem)->allocator,
"Failed to map staging texture (0x%x)", (guint) hr);
ret = FALSE;
}
gst_d3d11_device_unlock (dmem->device);
if (!ret) {
g_mutex_unlock (&dmem->lock);
return NULL;
}
}
dmem->cpu_map_count++;
g_mutex_unlock (&dmem->lock);
return dmem->map.pData;
}
static gpointer
gst_d3d11_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags)
{
GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
if (dmem->type == GST_D3D11_MEMORY_TYPE_STAGING) {
if ((flags & GST_MAP_D3D11) == GST_MAP_D3D11)
return dmem->texture;
return gst_d3d11_memory_map_staging (mem, flags);
}
g_mutex_lock (&dmem->lock);
if ((flags & GST_MAP_D3D11) == GST_MAP_D3D11) {
if (dmem->staging &&
......@@ -336,6 +380,9 @@ unmap_cpu_access_data (GstD3D11Memory * dmem)
ID3D11DeviceContext *device_context =
gst_d3d11_device_get_device_context_handle (dmem->device);
if (dmem->type == GST_D3D11_MEMORY_TYPE_STAGING)
staging = (ID3D11Resource *) dmem->texture;
gst_d3d11_device_lock (dmem->device);
ID3D11DeviceContext_Unmap (device_context, staging, 0);
gst_d3d11_device_unlock (dmem->device);
......@@ -348,14 +395,16 @@ gst_d3d11_memory_unmap_full (GstMemory * mem, GstMapInfo * info)
g_mutex_lock (&dmem->lock);
if ((info->flags & GST_MAP_D3D11) == GST_MAP_D3D11) {
if ((info->flags & GST_MAP_WRITE) == GST_MAP_WRITE)
if (dmem->type != GST_D3D11_MEMORY_TYPE_STAGING &&
(info->flags & GST_MAP_WRITE) == GST_MAP_WRITE)
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
g_mutex_unlock (&dmem->lock);
return;
}
if ((info->flags & GST_MAP_WRITE))
if (dmem->type != GST_D3D11_MEMORY_TYPE_STAGING &&
(info->flags & GST_MAP_WRITE))
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_UPLOAD);
dmem->cpu_map_count--;
......@@ -498,7 +547,7 @@ gst_d3d11_allocator_new (GstD3D11Device * device)
static gboolean
calculate_mem_size (GstD3D11Device * device, ID3D11Texture2D * texture,
D3D11_TEXTURE2D_DESC * desc, D3D11_MAP map_type,
const D3D11_TEXTURE2D_DESC * desc, D3D11_MAP map_type,
gint stride[GST_VIDEO_MAX_PLANES], gsize * size)
{
HRESULT hr;
......@@ -684,31 +733,24 @@ error:
GstMemory *
gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
GstD3D11AllocationParams * params)
const D3D11_TEXTURE2D_DESC * desc, GstD3D11AllocationFlags flags,
gsize size)
{
GstD3D11Memory *mem;
GstD3D11Device *device;
ID3D11Texture2D *texture = NULL;
ID3D11Texture2D *staging = NULL;
D3D11_TEXTURE2D_DESC *desc;
gsize *size;
gboolean is_first = FALSE;
guint index_to_use = 0;
GstD3D11AllocatorPrivate *priv;
GstD3D11MemoryType type = GST_D3D11_MEMORY_TYPE_TEXTURE;
g_return_val_if_fail (GST_IS_D3D11_ALLOCATOR (allocator), NULL);
g_return_val_if_fail (params != NULL, NULL);
g_return_val_if_fail (desc != NULL, NULL);
g_return_val_if_fail (size > 0, NULL);
priv = allocator->priv;
device = allocator->device;
desc = &params->desc[params->plane];
size = &params->size[params->plane];
if (*size == 0)
is_first = TRUE;
if ((params->flags & GST_D3D11_ALLOCATION_FLAG_TEXTURE_ARRAY)) {
if ((flags & GST_D3D11_ALLOCATION_FLAG_TEXTURE_ARRAY)) {
gint i;
do_again:
......@@ -758,50 +800,69 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
}
}
/* per plane, allocated staging texture to calculate actual size,
* stride, and offset */
if (is_first) {
gint num_plane;
gint stride[GST_VIDEO_MAX_PLANES];
gsize mem_size;
gint i;
mem = g_new0 (GstD3D11Memory, 1);
staging = create_staging_texture (device, desc);
if (!staging) {
GST_ERROR_OBJECT (allocator, "Couldn't create staging texture");
goto error;
}
gst_memory_init (GST_MEMORY_CAST (mem),
0, GST_ALLOCATOR_CAST (allocator), NULL, size, 0, 0, size);
if (!calculate_mem_size (device,
staging, desc, D3D11_MAP_READ, stride, &mem_size))
goto error;
g_mutex_init (&mem->lock);
mem->desc = *desc;
mem->texture = texture;
mem->device = gst_object_ref (device);
mem->type = type;
mem->subresource_index = index_to_use;
num_plane = gst_d3d11_dxgi_format_n_planes (desc->Format);
return GST_MEMORY_CAST (mem);
for (i = 0; i < num_plane; i++) {
params->stride[params->plane + i] = stride[i];
}
error:
if (texture)
gst_d3d11_device_release_texture (device, texture);
return NULL;
}
*size = mem_size;
GstMemory *
gst_d3d11_allocator_alloc_staging (GstD3D11Allocator * allocator,
const D3D11_TEXTURE2D_DESC * desc, GstD3D11AllocationFlags flags,
gint * stride)
{
GstD3D11Memory *mem;
GstD3D11Device *device;
ID3D11Texture2D *texture = NULL;
gsize mem_size = 0;
gint mem_stride[GST_VIDEO_MAX_PLANES];
g_return_val_if_fail (GST_IS_D3D11_ALLOCATOR (allocator), NULL);
g_return_val_if_fail (desc != NULL, NULL);
device = allocator->device;
texture = create_staging_texture (device, desc);
if (!texture) {
GST_ERROR_OBJECT (allocator, "Couldn't create staging texture");
goto error;
}
if (!calculate_mem_size (device,
texture, desc, D3D11_MAP_READ, mem_stride, &mem_size)) {
GST_ERROR_OBJECT (allocator, "Couldn't calculate staging texture size");
goto error;
}
mem = g_new0 (GstD3D11Memory, 1);
gst_memory_init (GST_MEMORY_CAST (mem),
0, GST_ALLOCATOR_CAST (allocator), NULL, *size, 0, 0, *size);
0, GST_ALLOCATOR_CAST (allocator), NULL, mem_size, 0, 0, mem_size);
g_mutex_init (&mem->lock);
mem->info = params->info;
mem->plane = params->plane;
mem->desc = *desc;
mem->texture = texture;
mem->staging = staging;
mem->device = gst_object_ref (device);
mem->type = type;
mem->subresource_index = index_to_use;
mem->type = GST_D3D11_MEMORY_TYPE_STAGING;
if (staging)
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
/* every plan will have identical size */
if (stride)
*stride = mem_stride[0];
return GST_MEMORY_CAST (mem);
......@@ -809,9 +870,6 @@ error:
if (texture)
gst_d3d11_device_release_texture (device, texture);
if (staging)
gst_d3d11_device_release_texture (device, texture);
return NULL;
}
......
......@@ -84,13 +84,6 @@ struct _GstD3D11AllocationParams
GstVideoInfo aligned_info;
const GstD3D11Format *d3d11_format;
/* size and stride of staging texture, set by allocator */
gint stride[GST_VIDEO_MAX_PLANES];
gsize size[GST_VIDEO_MAX_PLANES];
/* Current target plane for allocation */
guint plane;
GstD3D11AllocationFlags flags;
/*< private >*/
......@@ -101,6 +94,7 @@ typedef enum
{
GST_D3D11_MEMORY_TYPE_TEXTURE = 0,
GST_D3D11_MEMORY_TYPE_ARRAY = 1,
GST_D3D11_MEMORY_TYPE_STAGING = 2,
} GstD3D11MemoryType;
struct _GstD3D11Memory
......@@ -119,9 +113,6 @@ struct _GstD3D11Memory
ID3D11RenderTargetView *render_target_view[GST_VIDEO_MAX_PLANES];
guint num_render_target_views;
GstVideoInfo info;
guint plane;
GstD3D11MemoryType type;
/* > 0 if this is Array typed memory */
......@@ -173,7 +164,15 @@ GType gst_d3d11_allocator_get_type (void);
GstD3D11Allocator * gst_d3d11_allocator_new (GstD3D11Device *device);
GstMemory * gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator,
GstD3D11AllocationParams * params);
const D3D11_TEXTURE2D_DESC * desc,
GstD3D11AllocationFlags flags,
gsize size);
GstMemory * gst_d3d11_allocator_alloc_staging (GstD3D11Allocator * allocator,
const D3D11_TEXTURE2D_DESC * desc,
GstD3D11AllocationFlags flags,
gint * stride);
void gst_d3d11_allocator_set_flushing (GstD3D11Allocator * allocator,
gboolean flushing);
......
......@@ -57,9 +57,20 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
GST_D3D11_ALL_FORMATS)));
struct _GstD3D11Upload
{
GstD3D11BaseFilter parent;
GstBuffer *staging_buffer;
};
#define gst_d3d11_upload_parent_class parent_class
G_DEFINE_TYPE (GstD3D11Upload, gst_d3d11_upload, GST_TYPE_D3D11_BASE_FILTER);
static void gst_d3d11_upload_dispose (GObject * object);
static gboolean gst_d3d11_upload_stop (GstBaseTransform * trans);
static gboolean gst_d3d11_upload_sink_event (GstBaseTransform * trans,
GstEvent * event);
static GstCaps *gst_d3d11_upload_transform_caps (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps, GstCaps * filter);
static gboolean gst_d3d11_upload_propose_allocation (GstBaseTransform * trans,
......@@ -68,12 +79,19 @@ static gboolean gst_d3d11_upload_decide_allocation (GstBaseTransform * trans,
GstQuery * query);
static GstFlowReturn gst_d3d11_upload_transform (GstBaseTransform * trans,
GstBuffer * inbuf, GstBuffer * outbuf);
static gboolean gst_d3d11_upload_set_info (GstD3D11BaseFilter * filter,
GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
GstVideoInfo * out_info);
static void
gst_d3d11_upload_class_init (GstD3D11UploadClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass);
GstD3D11BaseFilterClass *bfilter_class = GST_D3D11_BASE_FILTER_CLASS (klass);
gobject_class->dispose = gst_d3d11_upload_dispose;
gst_element_class_add_static_pad_template (element_class, &sink_template);
gst_element_class_add_static_pad_template (element_class, &src_template);
......@@ -85,6 +103,8 @@ gst_d3d11_upload_class_init (GstD3D11UploadClass * klass)
trans_class->passthrough_on_same_caps = TRUE;
trans_class->stop = GST_DEBUG_FUNCPTR (gst_d3d11_upload_stop);
trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_d3d11_upload_sink_event);
trans_class->transform_caps =
GST_DEBUG_FUNCPTR (gst_d3d11_upload_transform_caps);
trans_class->propose_allocation =
......@@ -93,6 +113,8 @@ gst_d3d11_upload_class_init (GstD3D11UploadClass * klass)
GST_DEBUG_FUNCPTR (gst_d3d11_upload_decide_allocation);
trans_class->transform = GST_DEBUG_FUNCPTR (gst_d3d11_upload_transform);
bfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_d3d11_upload_set_info);
GST_DEBUG_CATEGORY_INIT (gst_d3d11_upload_debug,
"d3d11upload", 0, "d3d11upload Element");
}
......@@ -102,6 +124,43 @@ gst_d3d11_upload_init (GstD3D11Upload * upload)
{
}
static void
gst_d3d11_upload_dispose (GObject * object)
{
GstD3D11Upload *self = GST_D3D11_UPLOAD (object);
gst_clear_buffer (&self->staging_buffer);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static gboolean
gst_d3d11_upload_stop (GstBaseTransform * trans)
{
GstD3D11Upload *self = GST_D3D11_UPLOAD (trans);
gst_clear_buffer (&self->staging_buffer);
return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
}
static gboolean
gst_d3d11_upload_sink_event (GstBaseTransform * trans, GstEvent * event)
{
GstD3D11Upload *self = GST_D3D11_UPLOAD (trans);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
/* We don't need to hold this staging buffer after eos */
gst_clear_buffer (&self->staging_buffer);
break;
default:
break;
}
return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
}
static GstCaps *
_set_caps_features (const GstCaps * caps, const gchar * feature_name)
{
......@@ -326,21 +385,59 @@ gst_d3d11_upload_decide_allocation (GstBaseTransform * trans, GstQuery * query)
query);
}
static gboolean
gst_d3d11_upload_can_use_staging_buffer (GstD3D11Upload * self,
GstBuffer * outbuf)
{
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (self);
gint i;
/* staging buffer doesn't need to be used for non-d3d11 memory */
for (i = 0; i < gst_buffer_n_memory (outbuf); i++) {
GstMemory *mem = gst_buffer_peek_memory (outbuf, i);
if (!gst_is_d3d11_memory (mem))
return FALSE;
}
if (self->staging_buffer)
return TRUE;
self->staging_buffer = gst_d3d11_allocate_staging_buffer_for (outbuf,
&filter->out_info, TRUE);
if (!self->staging_buffer) {
GST_WARNING_OBJECT (self, "Couldn't allocate staging buffer");
return FALSE;
}
return TRUE;
}
static GstFlowReturn
gst_d3d11_upload_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstBuffer * outbuf)
{
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
GstD3D11Upload *self = GST_D3D11_UPLOAD (trans);
GstVideoFrame in_frame, out_frame;
gint i;
GstFlowReturn ret = GST_FLOW_OK;
gboolean use_staging_buf;
GstBuffer *target_outbuf = outbuf;
gint i;
use_staging_buf = gst_d3d11_upload_can_use_staging_buffer (self, outbuf);
if (use_staging_buf) {
GST_TRACE_OBJECT (self, "Copy input buffer to staging buffer");
target_outbuf = self->staging_buffer;
}
if (!gst_video_frame_map (&in_frame, &filter->in_info, inbuf,
GST_MAP_READ | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))
goto invalid_buffer;
if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf,
if (!gst_video_frame_map (&out_frame, &filter->out_info, target_outbuf,
GST_MAP_WRITE | GST_VIDEO_FRAME_MAP_FLAG_NO_REF)) {
gst_video_frame_unmap (&in_frame);
goto invalid_buffer;
......@@ -348,7 +445,7 @@ gst_d3d11_upload_transform (GstBaseTransform * trans, GstBuffer * inbuf,
for (i = 0; i < GST_VIDEO_FRAME_N_PLANES (&in_frame); i++) {
if (!gst_video_frame_copy_plane (&out_frame, &in_frame, i)) {
GST_ERROR_OBJECT (filter, "Couldn't copy %dth plane", i);
GST_ERROR_OBJECT (filter, "Couldn't copy plane %d", i);
ret = GST_FLOW_ERROR;
break;
}
......@@ -357,6 +454,14 @@ gst_d3d11_upload_transform (GstBaseTransform * trans, GstBuffer * inbuf,
gst_video_frame_unmap (&out_frame);
gst_video_frame_unmap (&in_frame);
/* Copy staging texture to d3d11 texture */
if (use_staging_buf) {
if (!gst_d3d11_buffer_copy_into (outbuf, self->staging_buffer)) {
GST_ERROR_OBJECT (self, "Cannot copy staging texture into texture");
return GST_FLOW_ERROR;
}
}
return ret;
/* ERRORS */
......@@ -367,3 +472,15 @@ invalid_buffer:
return GST_FLOW_ERROR;
}
}
static gboolean
gst_d3d11_upload_set_info (GstD3D11BaseFilter * filter,
GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
GstVideoInfo * out_info)
{
GstD3D11Upload *self = GST_D3D11_UPLOAD (filter);
gst_clear_buffer (&self->staging_buffer);
return TRUE;
}
......@@ -24,24 +24,9 @@
G_BEGIN_DECLS
#define GST_TYPE_D3D11_UPLOAD (gst_d3d11_upload_get_type())
#define GST_D3D11_UPLOAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_D3D11_UPLOAD,GstD3D11Upload))
#define GST_D3D11_UPLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_D3D11_UPLOAD,GstD3D11UploadClass))
#define GST_D3D11_UPLOAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_D3D11_UPLOAD,GstD3D11UploadClass))
#define GST_IS_D3D11_UPLOAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_D3D11_UPLOAD))
#define GST_IS_D3D11_UPLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_D3D11_UPLOAD))
struct _GstD3D11Upload
{
GstD3D11BaseFilter parent;
};
struct _GstD3D11UploadClass
{
GstD3D11BaseFilterClass parent_class;
};
GType gst_d3d11_upload_get_type (void);
#define GST_TYPE_D3D11_UPLOAD (gst_d3d11_upload_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11Upload,
gst_d3d11_upload, GST, D3D11_UPLOAD, GstD3D11BaseFilter);
G_END_DECLS
......
......@@ -23,6 +23,7 @@
#include "gstd3d11utils.h"
#include "gstd3d11device.h"
#include "gstd3d11memory.h"
#include <windows.h>
#include <versionhelpers.h>
......@@ -397,6 +398,153 @@ gst_d3d11_get_device_vendor (GstD3D11Device * device)
return vendor;
}
GstBuffer *
gst_d3d11_allocate_staging_buffer (GstD3D11Allocator * allocator,
const GstVideoInfo * info, const GstD3D11Format * format,
const D3D11_TEXTURE2D_DESC desc[GST_VIDEO_MAX_PLANES],
gboolean add_videometa)
{
GstBuffer *buffer;
gint i;
gint stride[GST_VIDEO_MAX_PLANES] = { 0, };
gsize offset[GST_VIDEO_MAX_PLANES] = { 0, };
GstMemory *mem;
g_return_val_if_fail (GST_IS_D3D11_ALLOCATOR (allocator), NULL);
g_return_val_if_fail (info != NULL, NULL);
g_return_val_if_fail (format != NULL, NULL);
g_return_val_if_fail (desc != NULL, NULL);
buffer = gst_buffer_new ();
if (format->dxgi_format == DXGI_FORMAT_UNKNOWN) {
gsize size[GST_VIDEO_MAX_PLANES] = { 0, };
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) {
mem = gst_d3d11_allocator_alloc_staging (allocator, &desc[i], 0,
&stride[i]);
if (!mem) {
GST_ERROR_OBJECT (allocator, "Couldn't allocate memory for plane %d",
i);
goto error;
}
size[i] = gst_memory_get_sizes (mem, NULL, NULL);
if (i > 0)
offset[i] = offset[i - 1] + size[i - 1];
gst_buffer_append_memory (buffer, mem);
}
} else {
/* must be YUV semi-planar or single plane */
g_assert (GST_VIDEO_INFO_N_PLANES (info) <= 2);
mem = gst_d3d11_allocator_alloc_staging (allocator, &desc[0], 0,
&stride[0]);
if (!mem) {
GST_ERROR_OBJECT (allocator, "Couldn't allocate memory");
goto error;
}
gst_memory_get_sizes (mem, NULL, NULL);
gst_buffer_append_memory (buffer, mem);
if (GST_VIDEO_INFO_N_PLANES (info) == 2) {
stride[1] = stride[0];
offset[1] = stride[0] * desc[0].Height;
}
}
if (add_videometa) {
gst_buffer_add_video_meta_full (buffer, GST_VIDEO_FRAME_FLAG_NONE,
GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info),
offset, stride);
}
return buffer;
error:
gst_buffer_unref (buffer);
return NULL;
}
GstBuffer *
gst_d3d11_allocate_staging_buffer_for (GstBuffer * buffer,
const GstVideoInfo * info, gboolean add_videometa)
{
GstD3D11Memory *dmem;
GstD3D11Device *device;
GstD3D11AllocationParams *params = NULL;
GstD3D11Allocator *alloc = NULL;
GstBuffer *staging_buffer = NULL;
D3D11_TEXTURE2D_DESC *desc;
gint i;
for (i = 0; i < gst_buffer_n_memory (buffer); i++) {
GstMemory *mem = gst_buffer_peek_memory (buffer, i);
if (!gst_is_d3d11_memory (mem)) {
GST_DEBUG ("Not a d3d11 memory");
return NULL;
}
}
dmem = (GstD3D11Memory *) gst_buffer_peek_memory (buffer, 0);
device = dmem->device;
params = gst_d3d11_allocation_params_new (device, (GstVideoInfo *) info,
0, 0);
if (!params) {
GST_WARNING ("Couldn't create alloc params");
goto done;
}
desc = &params->desc[0];
/* resolution of semi-planar formats must be multiple of 2 */
if (desc[0].Format == DXGI_FORMAT_NV12 || desc[0].Format == DXGI_FORMAT_P010
|| desc[0].Format == DXGI_FORMAT_P016) {
if (desc[0].Width % 2 || desc[0].Height % 2) {
gint width, height;
GstVideoAlignment align;
width = GST_ROUND_UP_2 (desc[0].Width);
height = GST_ROUND_UP_2 (desc[0].Height);
gst_video_alignment_reset (&align);
align.padding_right = width - desc[0].Width;
align.padding_bottom = height - desc[0].Height;
gst_d3d11_allocation_params_alignment (params, &align);
}
}
alloc = gst_d3d11_allocator_new (device);
if (!alloc) {
GST_WARNING ("Couldn't create allocator");
goto done;
}
staging_buffer = gst_d3d11_allocate_staging_buffer (alloc,
info, params->d3d11_format, params->desc, add_videometa);
if (!staging_buffer)
GST_WARNING ("Couldn't allocate staging buffer");
done:
if (params)
gst_d3d11_allocation_params_free (params);
if (alloc)
gst_object_unref (alloc);
return staging_buffer;
}
gboolean
_gst_d3d11_result (HRESULT hr, GstD3D11Device * device, GstDebugCategory * cat,
const gchar * file, const gchar * function, gint line)
......@@ -430,3 +578,93 @@ _gst_d3d11_result (HRESULT hr, GstD3D11Device * device, GstDebugCategory * cat,
return SUCCEEDED (hr);
#endif
}
gboolean
gst_d3d11_buffer_copy_into (GstBuffer * dst, GstBuffer * src)
{
guint i;
guint num_mem;
g_return_val_if_fail (GST_IS_BUFFER (dst), FALSE);
g_return_val_if_fail (GST_IS_BUFFER (src), FALSE);
num_mem = gst_buffer_n_memory (dst);
if (num_mem != gst_buffer_n_memory (src)) {
GST_WARNING ("different num memory");
return FALSE;
}
for (i = 0; i < num_mem; i++) {
GstMemory *dst_mem, *src_mem;
GstD3D11Memory *dst_dmem, *src_dmem;
GstMapInfo dst_info;
GstMapInfo src_info;
ID3D11Resource *dst_texture, *src_texture;
ID3D11DeviceContext *device_context;
GstD3D11Device *device;
D3D11_BOX src_box = { 0, };
dst_mem = gst_buffer_peek_memory (dst, i);
src_mem = gst_buffer_peek_memory (src, i);
if (!gst_is_d3d11_memory (dst_mem)) {
GST_WARNING ("dst memory is not d3d11");
return FALSE;
}
if (!gst_is_d3d11_memory (src_mem)) {
GST_WARNING ("src memory is not d3d11");
return FALSE;
}
dst_dmem = (GstD3D11Memory *) dst_mem;
src_dmem = (GstD3D11Memory *) src_mem;
device = dst_dmem->device;
if (device != src_dmem->device) {
GST_WARNING ("different device");
return FALSE;
}
if (dst_dmem->desc.Format != src_dmem->desc.Format) {
GST_WARNING ("different dxgi format");
return FALSE;
}
device_context = gst_d3d11_device_get_device_context_handle (device);
if (!gst_memory_map (dst_mem, &dst_info, GST_MAP_WRITE | GST_MAP_D3D11)) {
GST_ERROR ("Cannot map dst d3d11 memory");
return FALSE;
}
if (!gst_memory_map (src_mem, &src_info, GST_MAP_READ | GST_MAP_D3D11)) {
GST_ERROR ("Cannot map src d3d11 memory");
gst_memory_unmap (dst_mem, &dst_info);
return FALSE;
}
dst_texture = (ID3D11Resource *) dst_info.data;
src_texture = (ID3D11Resource *) src_info.data;
/* src/dst texture size might be different if padding was used.
* select smaller size */
src_box.left = 0;
src_box.top = 0;
src_box.front = 0;
src_box.back = 1;
src_box.right = MIN (src_dmem->desc.Width, dst_dmem->desc.Width);
src_box.bottom = MIN (src_dmem->desc.Height, dst_dmem->desc.Height);
gst_d3d11_device_lock (device);
ID3D11DeviceContext_CopySubresourceRegion (device_context,
dst_texture, dst_dmem->subresource_index, 0, 0, 0,
src_texture, src_dmem->subresource_index, &src_box);
gst_d3d11_device_unlock (device);
gst_memory_unmap (src_mem, &src_info);
gst_memory_unmap (dst_mem, &dst_info);
}
return TRUE;
}
......@@ -54,6 +54,19 @@ gboolean gst_d3d11_is_windows_8_or_greater (void);
GstD3D11DeviceVendor gst_d3d11_get_device_vendor (GstD3D11Device * device);
GstBuffer * gst_d3d11_allocate_staging_buffer (GstD3D11Allocator * allocator,
const GstVideoInfo * info,
const GstD3D11Format * format,
const D3D11_TEXTURE2D_DESC desc[GST_VIDEO_MAX_PLANES],
gboolean add_videometa);
GstBuffer * gst_d3d11_allocate_staging_buffer_for (GstBuffer * buffer,
const GstVideoInfo * info,
gboolean add_videometa);
gboolean gst_d3d11_buffer_copy_into (GstBuffer * dst,
GstBuffer * src);
gboolean _gst_d3d11_result (HRESULT hr,
GstD3D11Device * device,
GstDebugCategory * cat,
......
......@@ -66,6 +66,34 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_DEBUG_CATEGORY (d3d11_video_sink_debug);
#define GST_CAT_DEFAULT d3d11_video_sink_debug
struct _GstD3D11VideoSink
{
GstVideoSink parent;
GstD3D11Device *device;
GstD3D11Window *window;
gint video_width;
gint video_height;
GstVideoInfo info;
guintptr window_id;
/* properties */
gint adapter;
gboolean force_aspect_ratio;
gboolean enable_navigation_events;
GstD3D11WindowFullscreenToggleMode fullscreen_toggle_mode;
gboolean fullscreen;
/* saved render rectangle until we have a window */
GstVideoRectangle render_rect;
gboolean pending_render_rect;
GstBufferPool *fallback_pool;
gboolean can_convert;
gboolean have_video_processor;
};
static void gst_d3d11_videosink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_d3d11_videosink_get_property (GObject * object, guint prop_id,
......
......@@ -31,52 +31,10 @@
G_BEGIN_DECLS
#define GST_TYPE_D3D11_VIDEO_SINK (gst_d3d11_video_sink_get_type())
#define GST_D3D11_VIDEO_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_D3D11_VIDEO_SINK,GstD3D11VideoSink))
#define GST_D3D11_VIDEO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_D3D11_VIDEO_SINK,GstD3D11VideoSinkClass))
#define GST_D3D11_VIDEO_SINK_GET_CLASS(obj) (GST_D3D11_VIDEO_SINK_CLASS(G_OBJECT_GET_CLASS(obj)))
#define GST_IS_D3D11_VIDEO_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_D3D11_VIDEO_SINK))
#define GST_IS_D3D11_VIDEO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_D3D11_VIDEO_SINK))
typedef struct _GstD3D11VideoSink GstD3D11VideoSink;
typedef struct _GstD3D11VideoSinkClass GstD3D11VideoSinkClass;
struct _GstD3D11VideoSink
{
GstVideoSink sink;
GstD3D11Device *device;
GstD3D11Window *window;
gint video_width;
gint video_height;
GstVideoInfo info;
guintptr window_id;
/* properties */
gint adapter;
gboolean force_aspect_ratio;
gboolean enable_navigation_events;
GstD3D11WindowFullscreenToggleMode fullscreen_toggle_mode;
gboolean fullscreen;
/* saved render rectangle until we have a window */
GstVideoRectangle render_rect;
gboolean pending_render_rect;
GstBufferPool *fallback_pool;
gboolean can_convert;
gboolean have_video_processor;
};
struct _GstD3D11VideoSinkClass
{
GstVideoSinkClass parent_class;
};
GType gst_d3d11_video_sink_get_type (void);
#define GST_TYPE_D3D11_VIDEO_SINK (gst_d3d11_video_sink_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11VideoSink,
gst_d3d11_video_sink, GST, D3D11_VIDEO_SINK, GstVideoSink);
G_END_DECLS
#endif /* __GST_D3D11_VIDEO_SINK_H__ */
......@@ -21,6 +21,11 @@
#include "config.h"
#endif
#include <gst/video/video.h>
#include <gst/video/gstvideosink.h>
#include <gst/video/videooverlay.h>
#include <gst/video/navigation.h>
#include "gstd3d11videosinkbin.h"
#include "gstd3d11videosink.h"
#include "gstd3d11upload.h"
......@@ -100,6 +105,16 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_DEBUG_CATEGORY (d3d11_video_sink_bin_debug);
#define GST_CAT_DEFAULT d3d11_video_sink_bin_debug
struct _GstD3D11VideoSinkBin
{
GstBin parent;
GstPad *sinkpad;
GstElement *upload;
GstElement *sink;
};
static void gst_d3d11_video_sink_bin_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_d3d11_video_sink_bin_get_property (GObject * object,
......
......@@ -21,43 +21,13 @@
#define __GST_D3D11_VIDEO_SINK_BIN_H__
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideosink.h>
#include <gst/video/videooverlay.h>
#include <gst/video/navigation.h>
#include "gstd3d11_fwd.h"
G_BEGIN_DECLS
#define GST_TYPE_D3D11_VIDEO_SINK_BIN (gst_d3d11_video_sink_bin_get_type())
#define GST_D3D11_VIDEO_SINK_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_D3D11_VIDEO_SINK_BIN,GstD3D11VideoSinkBin))
#define GST_D3D11_VIDEO_SINK_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_D3D11_VIDEO_SINK_BIN,GstD3D11VideoSinkBinClass))
#define GST_D3D11_VIDEO_SINK_BIN_GET_CLASS(obj) (GST_D3D11_VIDEO_SINK_BIN_CLASS(G_OBJECT_GET_CLASS(obj)))
#define GST_IS_D3D11_VIDEO_SINK_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_D3D11_VIDEO_SINK_BIN))
#define GST_IS_D3D11_VIDEO_SINK_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_D3D11_VIDEO_SINK_BIN))
typedef struct _GstD3D11VideoSinkBin GstD3D11VideoSinkBin;
typedef struct _GstD3D11VideoSinkBinClass GstD3D11VideoSinkBinClass;
struct _GstD3D11VideoSinkBin
{
GstBin parent;
GstPad *sinkpad;
GstElement *upload;
GstElement *sink;
};
struct _GstD3D11VideoSinkBinClass
{
GstBinClass parent_class;
};
GType gst_d3d11_video_sink_bin_get_type (void);
#define GST_TYPE_D3D11_VIDEO_SINK_BIN (gst_d3d11_video_sink_bin_get_type())
G_DECLARE_FINAL_TYPE (GstD3D11VideoSinkBin,
gst_d3d11_video_sink_bin, GST, D3D11_VIDEO_SINK_BIN, GstBin);
G_END_DECLS
#endif /* __GST_D3D11_VIDEO_SINK_BIN_H__ */
......@@ -34,32 +34,6 @@
#define GST_CAT_DEFAULT gst_va_memory_debug
GST_DEBUG_CATEGORY_STATIC (gst_va_memory_debug);
struct _GstVaDmabufAllocator
{
GstDmaBufAllocator parent;
/* queue for disposable surfaces */
GstAtomicQueue *queue;
GstVaDisplay *display;
GstMemoryMapFunction parent_map;
};
static void _init_debug_category (void);
#define gst_va_dmabuf_allocator_parent_class dmabuf_parent_class
G_DEFINE_TYPE_WITH_CODE (GstVaDmabufAllocator, gst_va_dmabuf_allocator,
GST_TYPE_DMABUF_ALLOCATOR, _init_debug_category ());
typedef struct _GstVaBufferSurface GstVaBufferSurface;
struct _GstVaBufferSurface
{
GstVaDisplay *display;
GstVideoInfo info;
VASurfaceID surface;
volatile gint ref_count;
};
static void
_init_debug_category (void)
{
......@@ -318,6 +292,8 @@ _put_image (GstVaDisplay * display, VASurfaceID surface, VAImage * image)
return TRUE;
}
/*=========================== Quarks for GstMemory ===========================*/
static GQuark
gst_va_buffer_surface_quark (void)
{
......@@ -344,6 +320,86 @@ gst_va_drm_mod_quark (void)
return drm_mod_quark;
}
/*========================= GstVaBufferSurface ===============================*/
typedef struct _GstVaBufferSurface GstVaBufferSurface;
struct _GstVaBufferSurface
{
GstVaDisplay *display;
GstVideoInfo info;
VASurfaceID surface;
volatile gint ref_count;
};
static void
gst_va_buffer_surface_unref (gpointer data)
{
GstVaBufferSurface *buf = data;
g_return_if_fail (buf && GST_IS_VA_DISPLAY (buf->display));
if (g_atomic_int_dec_and_test (&buf->ref_count)) {
GST_LOG_OBJECT (buf->display, "Destroying surface %#x", buf->surface);
_destroy_surfaces (buf->display, &buf->surface, 1);
gst_clear_object (&buf->display);
g_slice_free (GstVaBufferSurface, buf);
}
}
static GstVaBufferSurface *
gst_va_buffer_surface_new (VASurfaceID surface, GstVideoFormat format,
gint width, gint height)
{
GstVaBufferSurface *buf = g_slice_new (GstVaBufferSurface);
g_atomic_int_set (&buf->ref_count, 0);
buf->surface = surface;
buf->display = NULL;
gst_video_info_set_format (&buf->info, format, width, height);
return buf;
}
static void
_available_mems_flush (GstVaDisplay * display, GstAtomicQueue * available_mems)
{
GstMemory *mem;
GstVaBufferSurface *buf;
while ((mem = gst_atomic_queue_pop (available_mems))) {
/* destroy the surface */
buf = gst_mini_object_get_qdata (GST_MINI_OBJECT (mem),
gst_va_buffer_surface_quark ());
if (buf && g_atomic_int_dec_and_test (&buf->ref_count)) {
GST_LOG ("Destroying surface %#x", buf->surface);
_destroy_surfaces (display, &buf->surface, 1);
g_slice_free (GstVaBufferSurface, buf);
}
GST_MINI_OBJECT_CAST (mem)->dispose = NULL;
gst_memory_unref (mem);
}
}
/*=========================== GstVaDmabufAllocator ===========================*/
struct _GstVaDmabufAllocator
{
GstDmaBufAllocator parent;
/* queue for disposed surfaces */
GstAtomicQueue *available_mems;
GstVaDisplay *display;
GstMemoryMapFunction parent_map;
GCond buffer_cond;
};
#define gst_va_dmabuf_allocator_parent_class dmabuf_parent_class
G_DEFINE_TYPE_WITH_CODE (GstVaDmabufAllocator, gst_va_dmabuf_allocator,
GST_TYPE_DMABUF_ALLOCATOR, _init_debug_category ());
static gpointer
gst_va_dmabuf_mem_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags)
{
......@@ -369,46 +425,41 @@ gst_va_dmabuf_mem_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags)
}
static void
gst_va_dmabuf_allocator_dispose (GObject * object)
gst_va_dmabuf_allocator_finalize (GObject * object)
{
GstVaDmabufAllocator *self = GST_VA_DMABUF_ALLOCATOR (object);
gst_clear_object (&self->display);
gst_atomic_queue_unref (self->queue);
g_cond_clear (&self->buffer_cond);
G_OBJECT_CLASS (dmabuf_parent_class)->dispose (object);
G_OBJECT_CLASS (dmabuf_parent_class)->finalize (object);
}
static void
gst_va_dmabuf_allocator_free (GstAllocator * allocator, GstMemory * mem)
gst_va_dmabuf_allocator_dispose (GObject * object)
{
GstVaDmabufAllocator *self = GST_VA_DMABUF_ALLOCATOR (allocator);
GstVaBufferSurface *buf;
GstVaDmabufAllocator *self = GST_VA_DMABUF_ALLOCATOR (object);
/* first close the dmabuf fd */
GST_ALLOCATOR_CLASS (dmabuf_parent_class)->free (allocator, mem);
_available_mems_flush (self->display, self->available_mems);
gst_atomic_queue_unref (self->available_mems);
while ((buf = gst_atomic_queue_pop (self->queue))) {
GST_LOG_OBJECT (self, "Destroying surface %#x", buf->surface);
_destroy_surfaces (self->display, &buf->surface, 1);
g_slice_free (GstVaBufferSurface, buf);
}
gst_clear_object (&self->display);
G_OBJECT_CLASS (dmabuf_parent_class)->dispose (object);
}
static void
gst_va_dmabuf_allocator_class_init (GstVaDmabufAllocatorClass * klass)
{
GstAllocatorClass *allocator_class = GST_ALLOCATOR_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gst_va_dmabuf_allocator_dispose;
allocator_class->free = gst_va_dmabuf_allocator_free;
object_class->finalize = gst_va_dmabuf_allocator_finalize;
}
static void
gst_va_dmabuf_allocator_init (GstVaDmabufAllocator * self)
{
self->queue = gst_atomic_queue_new (2);
self->available_mems = gst_atomic_queue_new (2);
self->parent_map = GST_ALLOCATOR (self)->mem_map;
GST_ALLOCATOR (self)->mem_map = gst_va_dmabuf_mem_map;
......@@ -428,34 +479,6 @@ gst_va_dmabuf_allocator_new (GstVaDisplay * display)
return GST_ALLOCATOR (self);
}
static void
_buffer_surface_unref (gpointer data)
{
GstVaBufferSurface *buf = data;
g_return_if_fail (buf && GST_IS_VA_DISPLAY (buf->display));
if (g_atomic_int_dec_and_test (&buf->ref_count)) {
GST_LOG_OBJECT (buf->display, "Destroying surface %#x", buf->surface);
_destroy_surfaces (buf->display, &buf->surface, 1);
gst_object_unref (buf->display);
g_slice_free (GstVaBufferSurface, buf);
}
}
static GstVaBufferSurface *
_create_buffer_surface (VASurfaceID surface, GstVideoFormat format,
gint width, gint height)
{
GstVaBufferSurface *buf = g_slice_new (GstVaBufferSurface);
g_atomic_int_set (&buf->ref_count, 0);
buf->surface = surface;
gst_video_info_set_format (&buf->info, format, width, height);
return buf;
}
static inline goffset
_get_fd_size (gint fd)
{
......@@ -463,24 +486,29 @@ _get_fd_size (gint fd)
}
static gboolean
gst_va_memory_dispose (GstMiniObject * mini_object)
gst_va_dmabuf_memory_release (GstMiniObject * mini_object)
{
GstMemory *mem = GST_MEMORY_CAST (mini_object);
GstVaDmabufAllocator *self = GST_VA_DMABUF_ALLOCATOR (mem->allocator);
GstVaBufferSurface *buf;
buf = gst_mini_object_get_qdata (mini_object, gst_va_buffer_surface_quark ());
if (buf && g_atomic_int_dec_and_test (&buf->ref_count))
gst_atomic_queue_push (self->queue, buf);
GST_OBJECT_LOCK (self);
return TRUE;
GST_LOG ("releasing %p", mem);
gst_atomic_queue_push (self->available_mems, gst_memory_ref (mem));
g_cond_signal (&self->buffer_cond);
GST_OBJECT_UNLOCK (self);
/* don't call mini_object's free */
return FALSE;
}
/* creates an exported VASurface and adds it as @buffer's memories
* qdata */
gboolean
gst_va_dmabuf_setup_buffer (GstAllocator * allocator, GstBuffer * buffer,
GstVaAllocationParams * params)
gst_va_dmabuf_allocator_setup_buffer (GstAllocator * allocator,
GstBuffer * buffer, GstVaAllocationParams * params)
{
GstVaBufferSurface *buf;
GstVaDmabufAllocator *self = GST_VA_DMABUF_ALLOCATOR (allocator);
......@@ -531,7 +559,8 @@ gst_va_dmabuf_setup_buffer (GstAllocator * allocator, GstBuffer * buffer,
goto failed;
}
buf = _create_buffer_surface (surface, format, desc.width, desc.height);
buf = gst_va_buffer_surface_new (surface, format, desc.width, desc.height);
GST_VIDEO_INFO_SIZE (&buf->info) = 0;
for (i = 0; i < desc.num_objects; i++) {
gint fd = desc.objects[i].fd;
......@@ -542,7 +571,7 @@ gst_va_dmabuf_setup_buffer (GstAllocator * allocator, GstBuffer * buffer,
gst_buffer_append_memory (buffer, mem);
GST_MINI_OBJECT (mem)->dispose = gst_va_memory_dispose;
GST_MINI_OBJECT (mem)->dispose = gst_va_dmabuf_memory_release;
g_atomic_int_add (&buf->ref_count, 1);
gst_mini_object_set_qdata (GST_MINI_OBJECT (mem),
......@@ -551,6 +580,8 @@ gst_va_dmabuf_setup_buffer (GstAllocator * allocator, GstBuffer * buffer,
*drm_mod = desc.objects[i].drm_format_modifier;
gst_mini_object_set_qdata (GST_MINI_OBJECT (mem), gst_va_drm_mod_quark (),
drm_mod, g_free);
GST_VIDEO_INFO_SIZE (&buf->info) += size;
}
for (i = 0; i < desc.num_layers; i++) {
......@@ -559,7 +590,6 @@ gst_va_dmabuf_setup_buffer (GstAllocator * allocator, GstBuffer * buffer,
GST_VIDEO_INFO_PLANE_STRIDE (&buf->info, i) = desc.layers[i].pitch[0];
}
GST_VIDEO_INFO_SIZE (&buf->info) = gst_buffer_get_size (buffer);
GST_LOG_OBJECT (self, "Created surface %#x [%dx%d] size %" G_GSIZE_FORMAT,
buf->surface, GST_VIDEO_INFO_WIDTH (&buf->info),
GST_VIDEO_INFO_HEIGHT (&buf->info), GST_VIDEO_INFO_SIZE (&buf->info));
......@@ -575,6 +605,58 @@ failed:
}
}
gboolean
gst_va_dmabuf_allocator_prepare_buffer (GstAllocator * allocator,
GstBuffer * buffer)
{
GstMemory *pmem, *mem[GST_VIDEO_MAX_PLANES] = { 0, };
GstVaDmabufAllocator *self = GST_VA_DMABUF_ALLOCATOR (allocator);
VASurfaceID surface, psurface;
gint j, idx = 1;
GST_OBJECT_LOCK (self);
/* if available mems, use them */
if (gst_atomic_queue_length (self->available_mems) == 0)
g_cond_wait (&self->buffer_cond, GST_OBJECT_GET_LOCK (self));
mem[0] = gst_atomic_queue_pop (self->available_mems);
surface = gst_va_memory_get_surface (mem[0], NULL);
do {
pmem = gst_atomic_queue_peek (self->available_mems);
if (!pmem)
break;
psurface = gst_va_memory_get_surface (pmem, NULL);
if (psurface != surface)
break;
mem[idx++] = gst_atomic_queue_pop (self->available_mems);
} while (TRUE);
GST_OBJECT_UNLOCK (self);
/* append them in reverse order */
for (j = idx - 1; j >= 0; j--)
gst_buffer_append_memory (buffer, mem[j]);
GST_TRACE_OBJECT (self, "Prepared surface %#x in buffer %p", surface, buffer);
return TRUE;
}
void
gst_va_dmabuf_allocator_flush (GstAllocator * allocator)
{
GstVaDmabufAllocator *self = GST_VA_DMABUF_ALLOCATOR (allocator);
GST_OBJECT_LOCK (self);
_available_mems_flush (self->display, self->available_mems);
g_cond_signal (&self->buffer_cond);
GST_OBJECT_UNLOCK (self);
}
gboolean
gst_va_dmabuf_try (GstAllocator * allocator, GstVaAllocationParams * params)
{
......@@ -582,7 +664,7 @@ gst_va_dmabuf_try (GstAllocator * allocator, GstVaAllocationParams * params)
GstMapInfo map_info;
gboolean ret;
ret = gst_va_dmabuf_setup_buffer (allocator, buffer, params);
ret = gst_va_dmabuf_allocator_setup_buffer (allocator, buffer, params);
if (ret) {
/* XXX: radeonsi for kadaveri cannot map dmabufs to user space */
if (!gst_buffer_map (buffer, &map_info, GST_MAP_READWRITE)) {
......@@ -647,7 +729,7 @@ gst_va_dmabuf_memories_setup (GstVaDisplay * display, GstVideoInfo * info,
GST_LOG_OBJECT (display, "Created surface %#x [%dx%d]", surface,
ext_buf.width, ext_buf.height);
buf = _create_buffer_surface (surface, rt_format, ext_buf.width,
buf = gst_va_buffer_surface_new (surface, rt_format, ext_buf.width,
ext_buf.height);
buf->info = *info;
buf->display = gst_object_ref (display);
......@@ -655,7 +737,7 @@ gst_va_dmabuf_memories_setup (GstVaDisplay * display, GstVideoInfo * info,
for (i = 0; i < n_planes; i++) {
g_atomic_int_add (&buf->ref_count, 1);
gst_mini_object_set_qdata (GST_MINI_OBJECT (mem[i]),
gst_va_buffer_surface_quark (), buf, _buffer_surface_unref);
gst_va_buffer_surface_quark (), buf, gst_va_buffer_surface_unref);
GST_INFO_OBJECT (display, "setting surface %#x to dmabuf fd %d",
buf->surface, gst_dmabuf_memory_get_fd (mem[i]));
}
......@@ -669,15 +751,20 @@ struct _GstVaAllocator
{
GstAllocator parent;
/* queue for disposed surfaces */
GstAtomicQueue *available_mems;
GstVaDisplay *display;
gboolean use_derived;
GArray *surface_formats;
GCond buffer_cond;
};
typedef struct _GstVaMemory GstVaMemory;
struct _GstVaMemory
{
GstMemory parent;
GstMemory mem;
GstVideoInfo info;
VASurfaceID surface;
......@@ -696,11 +783,26 @@ struct _GstVaMemory
G_DEFINE_TYPE_WITH_CODE (GstVaAllocator, gst_va_allocator, GST_TYPE_ALLOCATOR,
_init_debug_category ());
static gboolean _va_unmap (GstVaMemory * mem);
static void
gst_va_allocator_finalize (GObject * object)
{
GstVaAllocator *self = GST_VA_ALLOCATOR (object);
g_cond_clear (&self->buffer_cond);
G_OBJECT_CLASS (gst_va_allocator_parent_class)->finalize (object);
}
static void
gst_va_allocator_dispose (GObject * object)
{
GstVaAllocator *self = GST_VA_ALLOCATOR (object);
_available_mems_flush (self->display, self->available_mems);
gst_atomic_queue_unref (self->available_mems);
gst_clear_object (&self->display);
g_clear_pointer (&self->surface_formats, g_array_unref);
......@@ -713,11 +815,20 @@ _va_free (GstAllocator * allocator, GstMemory * mem)
GstVaAllocator *self = GST_VA_ALLOCATOR (allocator);
GstVaMemory *va_mem = (GstVaMemory *) mem;
GST_LOG_OBJECT (self, "Destroying surface %#x", va_mem->surface);
if (va_mem->mapped_data) {
g_warning (G_STRLOC ":%s: Freeing memory %p still mapped", G_STRFUNC,
va_mem);
_va_unmap (va_mem);
}
if (va_mem->surface != VA_INVALID_ID && mem->parent == NULL) {
GST_LOG_OBJECT (self, "Destroying surface %#x", va_mem->surface);
_destroy_surfaces (self->display, &va_mem->surface, 1);
}
_destroy_surfaces (self->display, &va_mem->surface, 1);
g_mutex_clear (&va_mem->lock);
GST_DEBUG ("%p: freed", va_mem);
g_slice_free (GstVaMemory, va_mem);
}
......@@ -728,6 +839,7 @@ gst_va_allocator_class_init (GstVaAllocatorClass * klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gst_va_allocator_dispose;
object_class->finalize = gst_va_allocator_finalize;
allocator_class->free = _va_free;
}
......@@ -751,8 +863,8 @@ _reset_mem (GstVaMemory * mem, GstAllocator * allocator, gsize size)
g_atomic_int_set (&mem->map_count, 0);
g_mutex_init (&mem->lock);
gst_memory_init (GST_MEMORY_CAST (mem), GST_MEMORY_FLAG_NO_SHARE, allocator,
NULL, size, 0 /* align */ , 0 /* offset */ , size);
gst_memory_init (GST_MEMORY_CAST (mem), 0, allocator, NULL, size,
0 /* align */ , 0 /* offset */ , size);
}
static inline gboolean
......@@ -910,50 +1022,38 @@ _va_unmap (GstVaMemory * mem)
return ret;
}
/* XXX(victor): shallow copy -- only the surface */
static GstMemory *
_va_copy_unlocked (GstVaMemory * mem)
_va_share (GstMemory * mem, gssize offset, gssize size)
{
GstVaMemory *ret;
gsize size;
ret = g_slice_new (GstVaMemory);
GstVaMemory *vamem = (GstVaMemory *) mem;
GstVaMemory *sub;
GstMemory *parent;
GST_DEBUG ("%p: share %" G_GSSIZE_FORMAT ", %" G_GSIZE_FORMAT, mem, offset,
size);
size = GST_VIDEO_INFO_SIZE (&mem->info);
/* find real parent */
if ((parent = vamem->mem.parent) == NULL)
parent = (GstMemory *) vamem;
ret->info = mem->info;
ret->surface = mem->surface;
if (size == -1)
size = mem->maxsize - offset;
_reset_mem (ret, GST_MEMORY_CAST (mem)->allocator, size);
sub = g_slice_new (GstVaMemory);
/* the shared memory is alwyas readonly */
gst_memory_init (GST_MEMORY_CAST (sub), GST_MINI_OBJECT_FLAGS (parent) |
GST_MINI_OBJECT_FLAG_LOCK_READONLY, vamem->mem.allocator, parent,
vamem->mem.maxsize, vamem->mem.align, vamem->mem.offset + offset, size);
return GST_MEMORY_CAST (ret);
}
sub->surface = vamem->surface;
sub->surface_format = vamem->surface_format;
sub->info = vamem->info;
static GstMemory *
_va_copy (GstVaMemory * mem, gssize offset, gssize size)
{
GstMemory *ret;
_clean_mem (sub);
g_mutex_lock (&mem->lock);
ret = _va_copy_unlocked (mem);
g_mutex_unlock (&mem->lock);
g_atomic_int_set (&sub->map_count, 0);
g_mutex_init (&sub->lock);
return ret;
}
static GstMemory *
_va_share (GstMemory * mem, gssize offset, gssize size)
{
/* VA surfaces are opaque structures, which cannot be shared */
return NULL;
}
static gboolean
_va_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
{
/* VA surfaces are opaque structures, which might live in other
* memory. It is impossible to know, so far, if they can mergable. */
return FALSE;
return GST_MEMORY_CAST (sub);
}
static void
......@@ -961,18 +1061,38 @@ gst_va_allocator_init (GstVaAllocator * self)
{
GstAllocator *allocator = GST_ALLOCATOR (self);
self->available_mems = gst_atomic_queue_new (2);
allocator->mem_type = GST_ALLOCATOR_VASURFACE;
allocator->mem_map = (GstMemoryMapFunction) _va_map;
allocator->mem_unmap = (GstMemoryUnmapFunction) _va_unmap;
allocator->mem_copy = (GstMemoryCopyFunction) _va_copy;
allocator->mem_share = _va_share;
allocator->mem_is_span = _va_is_span;
self->use_derived = TRUE;
g_cond_init (&self->buffer_cond);
GST_OBJECT_FLAG_SET (self, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
}
static gboolean
gst_va_memory_release (GstMiniObject * mini_object)
{
GstMemory *mem = GST_MEMORY_CAST (mini_object);
GstVaAllocator *self = GST_VA_ALLOCATOR (mem->allocator);
GST_OBJECT_LOCK (self);
GST_LOG ("releasing %p", mem);
gst_atomic_queue_push (self->available_mems, gst_memory_ref (mem));
g_cond_signal (&self->buffer_cond);
GST_OBJECT_UNLOCK (self);
/* don't call mini_object's free */
return FALSE;
}
GstMemory *
gst_va_allocator_alloc (GstAllocator * allocator,
GstVaAllocationParams * params)
......@@ -1026,6 +1146,8 @@ gst_va_allocator_alloc (GstAllocator * allocator,
_reset_mem (mem, allocator, GST_VIDEO_INFO_SIZE (&params->info));
GST_MINI_OBJECT (mem)->dispose = gst_va_memory_release;
GST_LOG_OBJECT (self, "Created surface %#x [%dx%d]", mem->surface,
GST_VIDEO_INFO_WIDTH (&mem->info), GST_VIDEO_INFO_HEIGHT (&mem->info));
......@@ -1047,6 +1169,40 @@ gst_va_allocator_new (GstVaDisplay * display, GArray * surface_formats)
return GST_ALLOCATOR (self);
}
gboolean
gst_va_allocator_prepare_buffer (GstAllocator * allocator, GstBuffer * buffer)
{
GstMemory *mem;
GstVaAllocator *self = GST_VA_ALLOCATOR (allocator);
VASurfaceID surface;
GST_OBJECT_LOCK (self);
/* if available mems, use them */
if (gst_atomic_queue_length (self->available_mems) == 0)
g_cond_wait (&self->buffer_cond, GST_OBJECT_GET_LOCK (self));
mem = gst_atomic_queue_pop (self->available_mems);
GST_OBJECT_UNLOCK (self);
surface = gst_va_memory_get_surface (mem, NULL);
gst_buffer_append_memory (buffer, mem);
GST_TRACE_OBJECT (self, "Prepared surface %#x in buffer %p", surface, buffer);
return TRUE;
}
void
gst_va_allocator_flush (GstAllocator * allocator)
{
GstVaAllocator *self = GST_VA_ALLOCATOR (allocator);
GST_OBJECT_LOCK (self);
_available_mems_flush (self->display, self->available_mems);
g_cond_signal (&self->buffer_cond);
GST_OBJECT_UNLOCK (self);
}
gboolean
gst_va_allocator_try (GstAllocator * allocator, GstVaAllocationParams * params)
{
......
......@@ -39,9 +39,12 @@ G_DECLARE_FINAL_TYPE (GstVaDmabufAllocator, gst_va_dmabuf_allocator, GST,
VA_DMABUF_ALLOCATOR, GstDmaBufAllocator);
GstAllocator * gst_va_dmabuf_allocator_new (GstVaDisplay * display);
gboolean gst_va_dmabuf_setup_buffer (GstAllocator * allocator,
GstBuffer * buffer,
GstVaAllocationParams * params);
gboolean gst_va_dmabuf_allocator_setup_buffer (GstAllocator * allocator,
GstBuffer * buffer,
GstVaAllocationParams * params);
gboolean gst_va_dmabuf_allocator_prepare_buffer (GstAllocator * allocator,
GstBuffer * buffer);
void gst_va_dmabuf_allocator_flush (GstAllocator * allocator);
gboolean gst_va_dmabuf_try (GstAllocator * allocator,
GstVaAllocationParams * params);
......@@ -64,6 +67,9 @@ GstAllocator * gst_va_allocator_new (GstVaDisplay * displa
GArray * surface_formats);
GstMemory * gst_va_allocator_alloc (GstAllocator * allocator,
GstVaAllocationParams * params);
gboolean gst_va_allocator_prepare_buffer (GstAllocator * allocator,
GstBuffer * buffer);
void gst_va_allocator_flush (GstAllocator * allocator);
gboolean gst_va_allocator_try (GstAllocator * allocator,
GstVaAllocationParams * params);
......