summaryrefslogtreecommitdiff
path: root/sys/d3d11/gstd3d11av1dec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sys/d3d11/gstd3d11av1dec.cpp')
-rw-r--r--sys/d3d11/gstd3d11av1dec.cpp359
1 files changed, 134 insertions, 225 deletions
diff --git a/sys/d3d11/gstd3d11av1dec.cpp b/sys/d3d11/gstd3d11av1dec.cpp
index e148dbb6c..aa1392d6a 100644
--- a/sys/d3d11/gstd3d11av1dec.cpp
+++ b/sys/d3d11/gstd3d11av1dec.cpp
@@ -40,6 +40,7 @@
#include <gst/codecs/gstav1decoder.h>
#include <string.h>
+#include <vector>
/* HACK: to expose dxva data structure on UWP */
#ifdef WINAPI_PARTITION_DESKTOP
@@ -353,26 +354,28 @@ typedef struct _GST_DXVA_Tile_AV1
/* reference list 8 + 4 margin */
#define NUM_OUTPUT_VIEW 12
-typedef struct _GstD3D11AV1Dec
+/* *INDENT-OFF* */
+typedef struct _GstD3D11AV1DecInner
{
- GstAV1Decoder parent;
-
- GstD3D11Device *device;
- GstD3D11Decoder *d3d11_decoder;
+ GstD3D11Device *device = nullptr;
+ GstD3D11Decoder *d3d11_decoder = nullptr;
GstAV1SequenceHeaderOBU seq_hdr;
-
GST_DXVA_PicParams_AV1 pic_params;
- /* Array of GST_DXVA_Tile_AV1 */
- GArray *tile_list;
- guint written_buffer_size;
- guint remaining_buffer_size;
- guint8 *bitstream_buffer_data;
+ std::vector<GST_DXVA_Tile_AV1> tile_list;
+ std::vector<guint8> bitstream_buffer;
+
+ guint max_width = 0;
+ guint max_height = 0;
+ guint bitdepth = 0;
+} GstD3D11AV1DecInner;
+/* *INDENT-ON* */
- guint max_width;
- guint max_height;
- guint bitdepth;
+typedef struct _GstD3D11AV1Dec
+{
+ GstAV1Decoder parent;
+ GstD3D11AV1DecInner *inner;
} GstD3D11AV1Dec;
typedef struct _GstD3D11AV1DecClass
@@ -389,7 +392,7 @@ static GstElementClass *parent_class = NULL;
static void gst_d3d11_av1_dec_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
-static void gst_d3d11_av1_dec_dispose (GObject * object);
+static void gst_d3d11_av1_dec_finalize (GObject * object);
static void gst_d3d11_av1_dec_set_context (GstElement * element,
GstContext * context);
@@ -430,7 +433,7 @@ gst_d3d11_av1_dec_class_init (GstD3D11AV1DecClass * klass, gpointer data)
GstD3D11DecoderClassData *cdata = (GstD3D11DecoderClassData *) data;
gobject_class->get_property = gst_d3d11_av1_dec_get_property;
- gobject_class->dispose = gst_d3d11_av1_dec_dispose;
+ gobject_class->finalize = gst_d3d11_av1_dec_finalize;
element_class->set_context =
GST_DEBUG_FUNCPTR (gst_d3d11_av1_dec_set_context);
@@ -467,7 +470,7 @@ gst_d3d11_av1_dec_class_init (GstD3D11AV1DecClass * klass, gpointer data)
static void
gst_d3d11_av1_dec_init (GstD3D11AV1Dec * self)
{
- self->tile_list = g_array_new (FALSE, TRUE, sizeof (GST_DXVA_Tile_AV1));
+ self->inner = new GstD3D11AV1DecInner ();
}
static void
@@ -481,24 +484,25 @@ gst_d3d11_av1_dec_get_property (GObject * object, guint prop_id,
}
static void
-gst_d3d11_av1_dec_dispose (GObject * object)
+gst_d3d11_av1_dec_finalize (GObject * object)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (object);
- g_clear_pointer (&self->tile_list, g_array_unref);
+ delete self->inner;
- G_OBJECT_CLASS (parent_class)->dispose (object);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gst_d3d11_av1_dec_set_context (GstElement * element, GstContext * context)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (element);
+ GstD3D11AV1DecInner *inner = self->inner;
GstD3D11AV1DecClass *klass = GST_D3D11_AV1_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
gst_d3d11_handle_set_context (element, context, cdata->adapter,
- &self->device);
+ &inner->device);
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}
@@ -507,20 +511,22 @@ static gboolean
gst_d3d11_av1_dec_open (GstVideoDecoder * decoder)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
+ GstD3D11AV1DecInner *inner = self->inner;
GstD3D11AV1DecClass *klass = GST_D3D11_AV1_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
if (!gst_d3d11_ensure_element_data (GST_ELEMENT_CAST (self), cdata->adapter,
- &self->device)) {
+ &inner->device)) {
GST_ERROR_OBJECT (self, "Cannot create d3d11device");
return FALSE;
}
- self->d3d11_decoder = gst_d3d11_decoder_new (self->device);
+ inner->d3d11_decoder = gst_d3d11_decoder_new (inner->device,
+ GST_DXVA_CODEC_AV1);
- if (!self->d3d11_decoder) {
+ if (!inner->d3d11_decoder) {
GST_ERROR_OBJECT (self, "Cannot create d3d11 decoder");
- gst_clear_object (&self->device);
+ gst_clear_object (&inner->device);
return FALSE;
}
@@ -531,9 +537,10 @@ static gboolean
gst_d3d11_av1_dec_close (GstVideoDecoder * decoder)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
+ GstD3D11AV1DecInner *inner = self->inner;
- gst_clear_object (&self->d3d11_decoder);
- gst_clear_object (&self->device);
+ gst_clear_object (&inner->d3d11_decoder);
+ gst_clear_object (&inner->device);
return TRUE;
}
@@ -542,8 +549,9 @@ static gboolean
gst_d3d11_av1_dec_negotiate (GstVideoDecoder * decoder)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
+ GstD3D11AV1DecInner *inner = self->inner;
- if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder))
+ if (!gst_d3d11_decoder_negotiate (inner->d3d11_decoder, decoder))
return FALSE;
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
@@ -554,8 +562,9 @@ gst_d3d11_av1_dec_decide_allocation (GstVideoDecoder * decoder,
GstQuery * query)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
+ GstD3D11AV1DecInner *inner = self->inner;
- if (!gst_d3d11_decoder_decide_allocation (self->d3d11_decoder,
+ if (!gst_d3d11_decoder_decide_allocation (inner->d3d11_decoder,
decoder, query)) {
return FALSE;
}
@@ -568,11 +577,12 @@ static gboolean
gst_d3d11_av1_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
+ GstD3D11AV1DecInner *inner = self->inner;
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_CONTEXT:
if (gst_d3d11_handle_context_query (GST_ELEMENT (decoder),
- query, self->device)) {
+ query, inner->device)) {
return TRUE;
}
break;
@@ -587,15 +597,16 @@ static gboolean
gst_d3d11_av1_dec_sink_event (GstVideoDecoder * decoder, GstEvent * event)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
+ GstD3D11AV1DecInner *inner = self->inner;
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
- if (self->d3d11_decoder)
- gst_d3d11_decoder_set_flushing (self->d3d11_decoder, decoder, TRUE);
+ if (inner->d3d11_decoder)
+ gst_d3d11_decoder_set_flushing (inner->d3d11_decoder, decoder, TRUE);
break;
case GST_EVENT_FLUSH_STOP:
- if (self->d3d11_decoder)
- gst_d3d11_decoder_set_flushing (self->d3d11_decoder, decoder, FALSE);
+ if (inner->d3d11_decoder)
+ gst_d3d11_decoder_set_flushing (inner->d3d11_decoder, decoder, FALSE);
break;
default:
break;
@@ -609,6 +620,7 @@ gst_d3d11_av1_dec_new_sequence (GstAV1Decoder * decoder,
const GstAV1SequenceHeaderOBU * seq_hdr)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
+ GstD3D11AV1DecInner *inner = self->inner;
gboolean modified = FALSE;
guint max_width, max_height;
@@ -624,33 +636,33 @@ gst_d3d11_av1_dec_new_sequence (GstAV1Decoder * decoder,
return FALSE;
}
- self->seq_hdr = *seq_hdr;
+ inner->seq_hdr = *seq_hdr;
- if (self->bitdepth != seq_hdr->bit_depth) {
- GST_INFO_OBJECT (self, "Bitdepth changed %d -> %d", self->bitdepth,
+ if (inner->bitdepth != seq_hdr->bit_depth) {
+ GST_INFO_OBJECT (self, "Bitdepth changed %d -> %d", inner->bitdepth,
seq_hdr->bit_depth);
- self->bitdepth = seq_hdr->bit_depth;
+ inner->bitdepth = seq_hdr->bit_depth;
modified = TRUE;
}
max_width = seq_hdr->max_frame_width_minus_1 + 1;
max_height = seq_hdr->max_frame_height_minus_1 + 1;
- if (self->max_width != max_width || self->max_height != max_height) {
+ if (inner->max_width != max_width || inner->max_height != max_height) {
GST_INFO_OBJECT (self, "Resolution changed %dx%d -> %dx%d",
- self->max_width, self->max_height, max_width, max_height);
- self->max_width = max_width;
- self->max_height = max_height;
+ inner->max_width, inner->max_height, max_width, max_height);
+ inner->max_width = max_width;
+ inner->max_height = max_height;
modified = TRUE;
}
- if (modified || !gst_d3d11_decoder_is_configured (self->d3d11_decoder)) {
+ if (modified || !gst_d3d11_decoder_is_configured (inner->d3d11_decoder)) {
GstVideoInfo info;
GstVideoFormat out_format = GST_VIDEO_FORMAT_UNKNOWN;
- if (self->bitdepth == 8) {
+ if (inner->bitdepth == 8) {
out_format = GST_VIDEO_FORMAT_NV12;
- } else if (self->bitdepth == 10) {
+ } else if (inner->bitdepth == 10) {
out_format = GST_VIDEO_FORMAT_P010_10LE;
} else {
GST_WARNING_OBJECT (self, "Invalid bit-depth %d", seq_hdr->bit_depth);
@@ -658,11 +670,11 @@ gst_d3d11_av1_dec_new_sequence (GstAV1Decoder * decoder,
}
gst_video_info_set_format (&info,
- out_format, self->max_width, self->max_height);
+ out_format, inner->max_width, inner->max_height);
- if (!gst_d3d11_decoder_configure (self->d3d11_decoder, GST_D3D11_CODEC_AV1,
- decoder->input_state, &info, (gint) self->max_width,
- (gint) self->max_height, NUM_OUTPUT_VIEW)) {
+ if (!gst_d3d11_decoder_configure (inner->d3d11_decoder,
+ decoder->input_state, &info, (gint) inner->max_width,
+ (gint) inner->max_height, NUM_OUTPUT_VIEW)) {
GST_ERROR_OBJECT (self, "Failed to create decoder");
return FALSE;
}
@@ -681,9 +693,10 @@ gst_d3d11_av1_dec_new_picture (GstAV1Decoder * decoder,
GstVideoCodecFrame * frame, GstAV1Picture * picture)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
+ GstD3D11AV1DecInner *inner = self->inner;
GstBuffer *view_buffer;
- view_buffer = gst_d3d11_decoder_get_output_view_buffer (self->d3d11_decoder,
+ view_buffer = gst_d3d11_decoder_get_output_view_buffer (inner->d3d11_decoder,
GST_VIDEO_DECODER (decoder));
if (!view_buffer) {
GST_DEBUG_OBJECT (self, "No available output view buffer");
@@ -726,28 +739,11 @@ gst_d3d11_av1_dec_duplicate_picture (GstAV1Decoder * decoder,
return new_picture;
}
-static gboolean
-gst_d3d11_av1_dec_get_bitstream_buffer (GstD3D11AV1Dec * self)
-{
- GST_TRACE_OBJECT (self, "Getting bitstream buffer");
- if (!gst_d3d11_decoder_get_decoder_buffer (self->d3d11_decoder,
- D3D11_VIDEO_DECODER_BUFFER_BITSTREAM, &self->remaining_buffer_size,
- (gpointer *) & self->bitstream_buffer_data)) {
- GST_ERROR_OBJECT (self, "Faild to get bitstream buffer");
- return FALSE;
- }
-
- GST_TRACE_OBJECT (self, "Got bitstream buffer %p with size %d",
- self->bitstream_buffer_data, self->remaining_buffer_size);
- self->written_buffer_size = 0;
-
- return TRUE;
-}
-
static ID3D11VideoDecoderOutputView *
gst_d3d11_av1_dec_get_output_view_from_picture (GstD3D11AV1Dec * self,
GstAV1Picture * picture, guint8 * view_id)
{
+ GstD3D11AV1DecInner *inner = self->inner;
GstBuffer *view_buffer;
ID3D11VideoDecoderOutputView *view;
@@ -758,7 +754,7 @@ gst_d3d11_av1_dec_get_output_view_from_picture (GstD3D11AV1Dec * self,
}
view =
- gst_d3d11_decoder_get_output_view_from_buffer (self->d3d11_decoder,
+ gst_d3d11_decoder_get_output_view_from_buffer (inner->d3d11_decoder,
view_buffer, view_id);
if (!view) {
GST_DEBUG_OBJECT (self, "current picture does not have output view handle");
@@ -773,10 +769,11 @@ gst_d3d11_av1_dec_start_picture (GstAV1Decoder * decoder,
GstAV1Picture * picture, GstAV1Dpb * dpb)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
- const GstAV1SequenceHeaderOBU *seq_hdr = &self->seq_hdr;
+ GstD3D11AV1DecInner *inner = self->inner;
+ const GstAV1SequenceHeaderOBU *seq_hdr = &inner->seq_hdr;
const GstAV1FrameHeaderOBU *frame_hdr = &picture->frame_hdr;
ID3D11VideoDecoderOutputView *view;
- GST_DXVA_PicParams_AV1 *pic_params = &self->pic_params;
+ GST_DXVA_PicParams_AV1 *pic_params = &inner->pic_params;
guint8 view_id = 0xff;
guint i, j;
@@ -787,13 +784,6 @@ gst_d3d11_av1_dec_start_picture (GstAV1Decoder * decoder,
return FALSE;
}
- GST_TRACE_OBJECT (self, "Begin frame");
-
- if (!gst_d3d11_decoder_begin_frame (self->d3d11_decoder, view, 0, NULL)) {
- GST_ERROR_OBJECT (self, "Failed to begin frame");
- return FALSE;
- }
-
memset (pic_params, 0, sizeof (GST_DXVA_PicParams_AV1));
pic_params->width = frame_hdr->frame_width;
@@ -1097,7 +1087,10 @@ gst_d3d11_av1_dec_start_picture (GstAV1Decoder * decoder,
pic_params->film_grain.cr_offset = frame_hdr->film_grain_params.cr_offset;
}
- return gst_d3d11_av1_dec_get_bitstream_buffer (self);
+ inner->bitstream_buffer.resize (0);
+ inner->tile_list.resize (0);
+
+ return TRUE;
}
static gboolean
@@ -1105,43 +1098,27 @@ gst_d3d11_av1_dec_decode_tile (GstAV1Decoder * decoder,
GstAV1Picture * picture, GstAV1Tile * tile)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
+ GstD3D11AV1DecInner *inner = self->inner;
GstAV1TileGroupOBU *tile_group = &tile->tile_group;
- ID3D11VideoDecoderOutputView *view;
- guint8 view_id = 0xff;
- guint i;
- view = gst_d3d11_av1_dec_get_output_view_from_picture (self, picture,
- &view_id);
- if (!view) {
- GST_ERROR_OBJECT (self, "current picture does not have output view handle");
- return FALSE;
- }
+ if (tile_group->num_tiles > inner->tile_list.size ())
+ inner->tile_list.resize (tile_group->num_tiles);
- if (tile_group->num_tiles > self->tile_list->len)
- g_array_set_size (self->tile_list, tile_group->num_tiles);
-
- g_assert (tile_group->tg_end < self->tile_list->len);
-
- if (tile->obu.obu_size > self->remaining_buffer_size) {
- GST_ERROR_OBJECT (self, "Too large OBU size");
- return FALSE;
- }
+ g_assert (tile_group->tg_end < inner->tile_list.size ());
GST_LOG_OBJECT (self, "Decode tile, tile count %d (start: %d - end: %d)",
tile_group->num_tiles, tile_group->tg_start, tile_group->tg_end);
- for (i = tile_group->tg_start; i <= tile_group->tg_end; i++) {
- GST_DXVA_Tile_AV1 *dxva_tile =
- &g_array_index (self->tile_list, GST_DXVA_Tile_AV1, i);
+ for (guint i = tile_group->tg_start; i <= tile_group->tg_end; i++) {
+ GST_DXVA_Tile_AV1 *dxva_tile = &inner->tile_list[i];
GST_TRACE_OBJECT (self,
- "Written size %d, Tile offset %d, size %d, row %d, col %d",
- self->written_buffer_size,
+ "Tile offset %d, size %d, row %d, col %d",
tile_group->entry[i].tile_offset, tile_group->entry[i].tile_size,
tile_group->entry[i].tile_row, tile_group->entry[i].tile_col);
- dxva_tile->DataOffset =
- self->written_buffer_size + tile_group->entry[i].tile_offset;
+ dxva_tile->DataOffset = inner->bitstream_buffer.size () +
+ tile_group->entry[i].tile_offset;
dxva_tile->DataSize = tile_group->entry[i].tile_size;
dxva_tile->row = tile_group->entry[i].tile_row;
dxva_tile->column = tile_group->entry[i].tile_col;
@@ -1151,10 +1128,11 @@ gst_d3d11_av1_dec_decode_tile (GstAV1Decoder * decoder,
GST_TRACE_OBJECT (self, "OBU size %d", tile->obu.obu_size);
- memcpy (self->bitstream_buffer_data, tile->obu.data, tile->obu.obu_size);
- self->remaining_buffer_size -= tile->obu.obu_size;
- self->bitstream_buffer_data += tile->obu.obu_size;
- self->written_buffer_size += tile->obu.obu_size;
+ size_t pos = inner->bitstream_buffer.size ();
+ inner->bitstream_buffer.resize (pos + tile->obu.obu_size);
+
+ memcpy (&inner->bitstream_buffer[0] + pos,
+ tile->obu.data, tile->obu.obu_size);
return TRUE;
}
@@ -1163,112 +1141,52 @@ static gboolean
gst_d3d11_av1_dec_end_picture (GstAV1Decoder * decoder, GstAV1Picture * picture)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
- guint d3d11_buffer_size;
- gpointer d3d11_buffer;
- guint padding;
- D3D11_VIDEO_DECODER_BUFFER_DESC buffer_desc[3];
- guint i;
- guint8 *data;
- gsize offset = 0;
-
- GST_TRACE_OBJECT (self, "Getting picture params buffer");
- if (!gst_d3d11_decoder_get_decoder_buffer (self->d3d11_decoder,
- D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS, &d3d11_buffer_size,
- &d3d11_buffer)) {
- GST_ERROR_OBJECT (self,
- "Failed to get decoder buffer for picture parameters");
- return FALSE;
- }
-
- if (d3d11_buffer_size < sizeof (GST_DXVA_PicParams_AV1)) {
- GST_ERROR_OBJECT (self,
- "Too small picture param buffer %d", d3d11_buffer_size);
-
- gst_d3d11_decoder_release_decoder_buffer (self->d3d11_decoder,
- D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS);
- return FALSE;
- }
-
- memcpy (d3d11_buffer, &self->pic_params, sizeof (GST_DXVA_PicParams_AV1));
-
- GST_TRACE_OBJECT (self, "Release picture param decoder buffer");
-
- if (!gst_d3d11_decoder_release_decoder_buffer (self->d3d11_decoder,
- D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS)) {
- GST_ERROR_OBJECT (self, "Failed to release decoder buffer");
- return FALSE;
- }
-
- GST_TRACE_OBJECT (self, "Getting slice control buffer");
-
- if (!gst_d3d11_decoder_get_decoder_buffer (self->d3d11_decoder,
- D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL, &d3d11_buffer_size,
- &d3d11_buffer)) {
- GST_ERROR_OBJECT (self, "Couldn't get slice control buffer");
- return FALSE;
- }
+ GstD3D11AV1DecInner *inner = self->inner;
+ ID3D11VideoDecoderOutputView *view;
+ guint8 view_id = 0xff;
+ size_t bitstream_buffer_size;
+ size_t bitstream_pos;
+ GstD3D11DecodeInputStreamArgs input_args;
- if (d3d11_buffer_size < sizeof (GST_DXVA_Tile_AV1) * self->tile_list->len) {
- GST_ERROR_OBJECT (self, "Too small slice control buffer %d",
- d3d11_buffer_size);
- gst_d3d11_decoder_release_decoder_buffer (self->d3d11_decoder,
- D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL);
+ if (inner->bitstream_buffer.empty () || inner->tile_list.empty ()) {
+ GST_ERROR_OBJECT (self, "No bitstream buffer to submit");
return FALSE;
}
- data = (guint8 *) d3d11_buffer;
- for (i = 0; i < self->tile_list->len; i++) {
- GST_DXVA_Tile_AV1 *dxva_tile =
- &g_array_index (self->tile_list, GST_DXVA_Tile_AV1, i);
-
- memcpy (data + offset, dxva_tile, sizeof (GST_DXVA_Tile_AV1));
- offset += sizeof (GST_DXVA_Tile_AV1);
- }
-
- if (!gst_d3d11_decoder_release_decoder_buffer (self->d3d11_decoder,
- D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL)) {
- GST_ERROR_OBJECT (self, "Failed to release slice control buffer");
+ view = gst_d3d11_av1_dec_get_output_view_from_picture (self, picture,
+ &view_id);
+ if (!view) {
+ GST_ERROR_OBJECT (self, "current picture does not have output view handle");
return FALSE;
}
- padding = MIN (GST_ROUND_UP_128 (self->written_buffer_size) -
- self->written_buffer_size, self->remaining_buffer_size);
- if (padding) {
- memset (self->bitstream_buffer_data, 0, padding);
- self->written_buffer_size += padding;
- }
+ memset (&input_args, 0, sizeof (GstD3D11DecodeInputStreamArgs));
- if (!gst_d3d11_decoder_release_decoder_buffer (self->d3d11_decoder,
- D3D11_VIDEO_DECODER_BUFFER_BITSTREAM)) {
- GST_ERROR_OBJECT (self, "Failed to release bitstream buffer");
+ bitstream_pos = inner->bitstream_buffer.size ();
+ bitstream_buffer_size = GST_ROUND_UP_128 (bitstream_pos);
- return FALSE;
- }
+ if (bitstream_buffer_size > bitstream_pos) {
+ size_t padding = bitstream_buffer_size - bitstream_pos;
- buffer_desc[0].BufferType = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS;
- buffer_desc[0].DataOffset = 0;
- buffer_desc[0].DataSize = sizeof (GST_DXVA_PicParams_AV1);
+ /* As per DXVA spec, total amount of bitstream buffer size should be
+ * 128 bytes aligned. If actual data is not multiple of 128 bytes,
+ * the last slice data needs to be zero-padded */
+ inner->bitstream_buffer.resize (bitstream_buffer_size, 0);
- buffer_desc[1].BufferType = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
- buffer_desc[1].DataOffset = 0;
- buffer_desc[1].DataSize = sizeof (GST_DXVA_Tile_AV1) * self->tile_list->len;
-
- buffer_desc[2].BufferType = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
- buffer_desc[2].DataOffset = 0;
- buffer_desc[2].DataSize = self->written_buffer_size;
-
- if (!gst_d3d11_decoder_submit_decoder_buffers (self->d3d11_decoder,
- 3, buffer_desc)) {
- GST_ERROR_OBJECT (self, "Couldn't submit decoder buffers");
- return FALSE;
+ GST_DXVA_Tile_AV1 & tile = inner->tile_list.back ();
+ tile.DataSize += padding;
}
- if (!gst_d3d11_decoder_end_frame (self->d3d11_decoder)) {
- GST_ERROR_OBJECT (self, "Failed to EndFrame");
- return FALSE;
- }
+ input_args.picture_params = &inner->pic_params;
+ input_args.picture_params_size = sizeof (GST_DXVA_PicParams_AV1);
+ input_args.slice_control = &inner->tile_list[0];
+ input_args.slice_control_size =
+ sizeof (GST_DXVA_Tile_AV1) * inner->tile_list.size ();
+ input_args.bitstream = &inner->bitstream_buffer[0];
+ input_args.bitstream_size = inner->bitstream_buffer.size ();
- return TRUE;
+ return gst_d3d11_decoder_decode_frame (inner->d3d11_decoder,
+ view, &input_args);
}
static GstFlowReturn
@@ -1276,6 +1194,7 @@ gst_d3d11_av1_dec_output_picture (GstAV1Decoder * decoder,
GstVideoCodecFrame * frame, GstAV1Picture * picture)
{
GstD3D11AV1Dec *self = GST_D3D11_AV1_DEC (decoder);
+ GstD3D11AV1DecInner *inner = self->inner;
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
GstBuffer *view_buffer;
@@ -1289,7 +1208,7 @@ gst_d3d11_av1_dec_output_picture (GstAV1Decoder * decoder,
goto error;
}
- if (!gst_d3d11_decoder_process_output (self->d3d11_decoder, vdec,
+ if (!gst_d3d11_decoder_process_output (inner->d3d11_decoder, vdec,
picture->frame_hdr.render_width, picture->frame_hdr.render_height,
view_buffer, &frame->output_buffer)) {
GST_ERROR_OBJECT (self, "Failed to copy buffer");
@@ -1302,20 +1221,14 @@ gst_d3d11_av1_dec_output_picture (GstAV1Decoder * decoder,
error:
gst_av1_picture_unref (picture);
- gst_video_decoder_drop_frame (vdec, frame);
+ gst_video_decoder_release_frame (vdec, frame);
return GST_FLOW_ERROR;
}
-typedef struct
-{
- guint width;
- guint height;
-} GstD3D11AV1DecResolution;
-
void
gst_d3d11_av1_dec_register (GstPlugin * plugin, GstD3D11Device * device,
- GstD3D11Decoder * decoder, guint rank)
+ guint rank)
{
GType type;
gchar *type_name;
@@ -1334,10 +1247,6 @@ gst_d3d11_av1_dec_register (GstPlugin * plugin, GstD3D11Device * device,
(GInstanceInitFunc) gst_d3d11_av1_dec_init,
};
const GUID *profile_guid = NULL;
- /* values were taken from chromium. See supported_profile_helper.cc */
- GstD3D11AV1DecResolution resolutions_to_check[] = {
- {4096, 2160}, {4096, 2304}, {7680, 4320}, {8192, 4320}, {8192, 8192}
- };
GstCaps *sink_caps = NULL;
GstCaps *src_caps = NULL;
guint max_width = 0;
@@ -1347,29 +1256,29 @@ gst_d3d11_av1_dec_register (GstPlugin * plugin, GstD3D11Device * device,
gboolean have_gray = FALSE;
gboolean have_gray10 = FALSE;
- if (!gst_d3d11_decoder_get_supported_decoder_profile (decoder,
- GST_D3D11_CODEC_AV1, GST_VIDEO_FORMAT_NV12, &profile_guid)) {
+ if (!gst_d3d11_decoder_get_supported_decoder_profile (device,
+ GST_DXVA_CODEC_AV1, GST_VIDEO_FORMAT_NV12, &profile_guid)) {
GST_INFO_OBJECT (device, "device does not support VP8 decoding");
return;
}
- have_p010 = gst_d3d11_decoder_supports_format (decoder,
+ have_p010 = gst_d3d11_decoder_supports_format (device,
profile_guid, DXGI_FORMAT_P010);
- have_gray = gst_d3d11_decoder_supports_format (decoder,
+ have_gray = gst_d3d11_decoder_supports_format (device,
profile_guid, DXGI_FORMAT_R8_UNORM);
- have_gray10 = gst_d3d11_decoder_supports_format (decoder,
+ have_gray10 = gst_d3d11_decoder_supports_format (device,
profile_guid, DXGI_FORMAT_R16_UNORM);
GST_INFO_OBJECT (device, "Decoder support P010: %d, R8: %d, R16: %d",
have_p010, have_gray, have_gray10);
/* TODO: add test monochrome formats */
- for (i = 0; i < G_N_ELEMENTS (resolutions_to_check); i++) {
- if (gst_d3d11_decoder_supports_resolution (decoder, profile_guid,
- DXGI_FORMAT_NV12, resolutions_to_check[i].width,
- resolutions_to_check[i].height)) {
- max_width = resolutions_to_check[i].width;
- max_height = resolutions_to_check[i].height;
+ for (i = 0; i < G_N_ELEMENTS (gst_dxva_resolutions); i++) {
+ if (gst_d3d11_decoder_supports_resolution (device, profile_guid,
+ DXGI_FORMAT_NV12, gst_dxva_resolutions[i].width,
+ gst_dxva_resolutions[i].height)) {
+ max_width = gst_dxva_resolutions[i].width;
+ max_height = gst_dxva_resolutions[i].height;
GST_DEBUG_OBJECT (device,
"device support resolution %dx%d", max_width, max_height);
@@ -1419,7 +1328,7 @@ gst_d3d11_av1_dec_register (GstPlugin * plugin, GstD3D11Device * device,
"height", GST_TYPE_INT_RANGE, 1, resolution, NULL);
type_info.class_data =
- gst_d3d11_decoder_class_data_new (device, GST_D3D11_CODEC_AV1,
+ gst_d3d11_decoder_class_data_new (device, GST_DXVA_CODEC_AV1,
sink_caps, src_caps);
type_name = g_strdup ("GstD3D11AV1Dec");