d3d11decoder: Directly access ID3D11VideoDecoderOutputView for decoding

Decoder output view is stored in GstD3D11Memory object instead of
wrapper struct now. So qdata is no more required.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1712>
This commit is contained in:
Seungha Yang 2020-10-20 17:31:17 +09:00
parent a4f324d668
commit f615677051
6 changed files with 72 additions and 138 deletions

View file

@ -105,20 +105,6 @@ struct _GstD3D11DecoderPrivate
guint num_resource_views;
};
#define OUTPUT_VIEW_QUARK _decoder_output_view_get()
static GQuark
_decoder_output_view_get (void)
{
static volatile gsize g_quark = 0;
if (g_once_init_enter (&g_quark)) {
gsize quark =
(gsize) g_quark_from_static_string ("GstD3D11DecoderOutputView");
g_once_init_leave (&g_quark, quark);
}
return (GQuark) g_quark;
}
static void gst_d3d11_decoder_constructed (GObject * object);
static void gst_d3d11_decoder_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
@ -363,76 +349,21 @@ gst_d3d11_decoder_new (GstD3D11Device * device)
return decoder;
}
static void
gst_d3d11_decoder_output_view_free (GstD3D11DecoderOutputView * view)
{
GST_LOG_OBJECT (view->device, "Free view %p, view id: %d", view,
view->view_id);
if (view->handle) {
gst_d3d11_device_lock (view->device);
ID3D11VideoDecoderOutputView_Release (view->handle);
gst_d3d11_device_unlock (view->device);
}
gst_object_unref (view->device);
g_free (view);
}
static gboolean
gst_d3d11_decoder_ensure_output_view (GstD3D11Decoder * self,
GstBuffer * buffer)
{
GstD3D11DecoderPrivate *priv = self->priv;
D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC view_desc = { 0, };
GstD3D11Memory *mem;
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view_handle;
HRESULT hr;
guint view_id = 0;
mem = (GstD3D11Memory *) gst_buffer_peek_memory (buffer, 0);
if (!gst_d3d11_memory_ensure_decoder_output_view (mem, priv->video_device,
&priv->decoder_profile)) {
view = (GstD3D11DecoderOutputView *)
gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (mem), OUTPUT_VIEW_QUARK);
if (view) {
GST_TRACE_OBJECT (self, "Reuse view id %d", view->view_id);
return TRUE;
}
view_desc.DecodeProfile = priv->decoder_profile;
view_desc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D;
view_desc.Texture2D.ArraySlice = mem->subresource_index;
if (priv->use_array_of_texture) {
view_id = priv->next_view_id;
priv->next_view_id++;
/* valid view range is [0, 126] */
priv->next_view_id %= 127;
} else {
view_id = mem->subresource_index;
}
GST_LOG_OBJECT (self, "Create decoder output view with index %d", view_id);
hr = ID3D11VideoDevice_CreateVideoDecoderOutputView (priv->video_device,
(ID3D11Resource *) mem->texture, &view_desc, &view_handle);
if (!gst_d3d11_result (hr, priv->device)) {
GST_ERROR_OBJECT (self,
"Could not create decoder output view index %d, hr: 0x%x",
view_id, (guint) hr);
GST_ERROR_OBJECT (self, "Decoder output view is unavailable");
return FALSE;
}
view = g_new0 (GstD3D11DecoderOutputView, 1);
view->device = gst_object_ref (priv->device);
view->handle = view_handle;
view->view_id = view_id;
gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (mem), OUTPUT_VIEW_QUARK,
view, (GDestroyNotify) gst_d3d11_decoder_output_view_free);
return TRUE;
}
@ -964,7 +895,7 @@ error:
gboolean
gst_d3d11_decoder_begin_frame (GstD3D11Decoder * decoder,
GstD3D11DecoderOutputView * output_view, guint content_key_size,
ID3D11VideoDecoderOutputView * output_view, guint content_key_size,
gconstpointer content_key)
{
GstD3D11DecoderPrivate *priv;
@ -973,7 +904,6 @@ gst_d3d11_decoder_begin_frame (GstD3D11Decoder * decoder,
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
g_return_val_if_fail (output_view != NULL, FALSE);
g_return_val_if_fail (output_view->handle != NULL, FALSE);
priv = decoder->priv;
@ -981,7 +911,7 @@ gst_d3d11_decoder_begin_frame (GstD3D11Decoder * decoder,
GST_LOG_OBJECT (decoder, "Try begin frame, retry count %d", retry_count);
gst_d3d11_device_lock (priv->device);
hr = ID3D11VideoContext_DecoderBeginFrame (priv->video_context,
priv->decoder, output_view->handle, content_key_size, content_key);
priv->decoder, output_view, content_key_size, content_key);
gst_d3d11_device_unlock (priv->device);
if (hr == E_PENDING && retry_count < 50) {
@ -1139,39 +1069,38 @@ gst_d3d11_decoder_get_output_view_buffer (GstD3D11Decoder * decoder)
return buf;
}
GstD3D11DecoderOutputView *
ID3D11VideoDecoderOutputView *
gst_d3d11_decoder_get_output_view_from_buffer (GstD3D11Decoder * decoder,
GstBuffer * buffer)
{
GstMemory *mem;
GstD3D11DecoderOutputView *view;
GstD3D11Memory *dmem;
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), NULL);
g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
mem = gst_buffer_peek_memory (buffer, 0);
if (!gst_is_d3d11_memory (mem)) {
GST_WARNING_OBJECT (decoder, "nemory is not d3d11 memory");
GST_WARNING_OBJECT (decoder, "Not a d3d11 memory");
return NULL;
}
view = (GstD3D11DecoderOutputView *)
gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (mem), OUTPUT_VIEW_QUARK);
dmem = (GstD3D11Memory *) mem;
if (!view) {
if (!dmem->decoder_output_view) {
GST_WARNING_OBJECT (decoder, "memory does not have output view");
return NULL;
}
return view;
return dmem->decoder_output_view;
}
guint
gst_d3d11_decoder_get_output_view_index (GstD3D11Decoder * decoder,
ID3D11VideoDecoderOutputView * view_handle)
guint8
gst_d3d11_decoder_get_output_view_index (ID3D11VideoDecoderOutputView *
view_handle)
{
D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC view_desc;
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), 0xff);
g_return_val_if_fail (view_handle != NULL, 0xff);
ID3D11VideoDecoderOutputView_GetDesc (view_handle, &view_desc);

View file

@ -33,14 +33,6 @@ G_DECLARE_FINAL_TYPE (GstD3D11Decoder,
gst_d3d11_decoder, GST, D3D11_DECODER, GstObject);
typedef struct _GstD3D11DecoderPrivate GstD3D11DecoderPrivate;
typedef struct _GstD3D11DecoderOutputView GstD3D11DecoderOutputView;
struct _GstD3D11DecoderOutputView
{
GstD3D11Device *device;
ID3D11VideoDecoderOutputView *handle;
guint view_id;
};
typedef enum
{
@ -90,7 +82,7 @@ gboolean gst_d3d11_decoder_open (GstD3D11Decoder * decoder,
void gst_d3d11_decoder_reset (GstD3D11Decoder * decoder);
gboolean gst_d3d11_decoder_begin_frame (GstD3D11Decoder * decoder,
GstD3D11DecoderOutputView * output_view,
ID3D11VideoDecoderOutputView * output_view,
guint content_key_size,
gconstpointer content_key);
@ -110,11 +102,10 @@ gboolean gst_d3d11_decoder_submit_decoder_buffers (GstD3D11Decoder * de
GstBuffer * gst_d3d11_decoder_get_output_view_buffer (GstD3D11Decoder * decoder);
GstD3D11DecoderOutputView * gst_d3d11_decoder_get_output_view_from_buffer (GstD3D11Decoder * decoder,
GstBuffer * buffer);
ID3D11VideoDecoderOutputView * gst_d3d11_decoder_get_output_view_from_buffer (GstD3D11Decoder * decoder,
GstBuffer * buffer);
guint gst_d3d11_decoder_get_output_view_index (GstD3D11Decoder * decoder,
ID3D11VideoDecoderOutputView * view_handle);
guint8 gst_d3d11_decoder_get_output_view_index (ID3D11VideoDecoderOutputView * view_handle);
gboolean gst_d3d11_decoder_process_output (GstD3D11Decoder * decoder,
GstVideoInfo * info,

View file

@ -490,12 +490,12 @@ gst_d3d11_h264_dec_get_bitstream_buffer (GstD3D11H264Dec * self)
return TRUE;
}
static GstD3D11DecoderOutputView *
static ID3D11VideoDecoderOutputView *
gst_d3d11_h264_dec_get_output_view_from_picture (GstD3D11H264Dec * self,
GstH264Picture * picture)
{
GstBuffer *view_buffer;
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
view_buffer = (GstBuffer *) gst_h264_picture_get_user_data (picture);
if (!view_buffer) {
@ -518,7 +518,7 @@ gst_d3d11_h264_dec_start_picture (GstH264Decoder * decoder,
GstH264Picture * picture, GstH264Slice * slice, GstH264Dpb * dpb)
{
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
gint i;
GArray *dpb_array;
@ -549,7 +549,7 @@ gst_d3d11_h264_dec_start_picture (GstH264Decoder * decoder,
for (i = 0; i < dpb_array->len; i++) {
guint ref = 3;
GstH264Picture *other = g_array_index (dpb_array, GstH264Picture *, i);
GstD3D11DecoderOutputView *other_view;
ID3D11VideoDecoderOutputView *other_view;
gint id = 0xff;
if (!other->ref)
@ -558,7 +558,7 @@ gst_d3d11_h264_dec_start_picture (GstH264Decoder * decoder,
other_view = gst_d3d11_h264_dec_get_output_view_from_picture (self, other);
if (other_view)
id = other_view->view_id;
id = gst_d3d11_decoder_get_output_view_index (other_view);
self->ref_frame_list[i].Index7Bits = id;
self->ref_frame_list[i].AssociatedFlag = other->long_term;
@ -901,7 +901,7 @@ gst_d3d11_h264_dec_decode_slice (GstH264Decoder * decoder,
guint d3d11_buffer_size = 0;
gpointer d3d11_buffer = NULL;
gint i, j;
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
pps = slice->header.pps;
sps = pps->sequence;
@ -915,7 +915,8 @@ gst_d3d11_h264_dec_decode_slice (GstH264Decoder * decoder,
gst_d3d11_h264_dec_fill_picture_params (self, &slice->header, &pic_params);
pic_params.CurrPic.Index7Bits = view->view_id;
pic_params.CurrPic.Index7Bits =
gst_d3d11_decoder_get_output_view_index (view);
pic_params.RefPicFlag = picture->ref;
pic_params.frame_num = picture->frame_num;

View file

@ -458,12 +458,12 @@ gst_d3d11_h265_dec_get_bitstream_buffer (GstD3D11H265Dec * self)
return TRUE;
}
static GstD3D11DecoderOutputView *
static ID3D11VideoDecoderOutputView *
gst_d3d11_h265_dec_get_output_view_from_picture (GstD3D11H265Dec * self,
GstH265Picture * picture)
{
GstBuffer *view_buffer;
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
view_buffer = (GstBuffer *) gst_h265_picture_get_user_data (picture);
if (!view_buffer) {
@ -498,7 +498,7 @@ gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb)
{
GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
gint i, j;
GArray *dpb_array;
@ -532,7 +532,7 @@ gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
for (i = 0; i < dpb_array->len && i < G_N_ELEMENTS (self->ref_pic_list); i++) {
GstH265Picture *other = g_array_index (dpb_array, GstH265Picture *, i);
GstD3D11DecoderOutputView *other_view;
ID3D11VideoDecoderOutputView *other_view;
gint id = 0xff;
if (!other->ref) {
@ -543,7 +543,7 @@ gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
other_view = gst_d3d11_h265_dec_get_output_view_from_picture (self, other);
if (other_view)
id = other_view->view_id;
id = gst_d3d11_decoder_get_output_view_index (other_view);
self->ref_pic_list[i].Index7Bits = id;
self->ref_pic_list[i].AssociatedFlag = other->long_term;
@ -558,13 +558,15 @@ gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
other = decoder->RefPicSetStCurrBefore[j++];
if (other) {
GstD3D11DecoderOutputView *other_view;
ID3D11VideoDecoderOutputView *other_view;
other_view =
gst_d3d11_h265_dec_get_output_view_from_picture (self, other);
if (other_view)
id = gst_d3d11_h265_dec_get_ref_index (self, other_view->view_id);
if (other_view) {
id = gst_d3d11_h265_dec_get_ref_index (self,
gst_d3d11_decoder_get_output_view_index (other_view));
}
}
self->ref_pic_set_st_curr_before[i] = id;
@ -578,13 +580,15 @@ gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
other = decoder->RefPicSetStCurrAfter[j++];
if (other) {
GstD3D11DecoderOutputView *other_view;
ID3D11VideoDecoderOutputView *other_view;
other_view =
gst_d3d11_h265_dec_get_output_view_from_picture (self, other);
if (other_view)
id = gst_d3d11_h265_dec_get_ref_index (self, other_view->view_id);
if (other_view) {
id = gst_d3d11_h265_dec_get_ref_index (self,
gst_d3d11_decoder_get_output_view_index (other_view));
}
}
self->ref_pic_set_st_curr_after[i] = id;
@ -598,13 +602,15 @@ gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
other = decoder->RefPicSetLtCurr[j++];
if (other) {
GstD3D11DecoderOutputView *other_view;
ID3D11VideoDecoderOutputView *other_view;
other_view =
gst_d3d11_h265_dec_get_output_view_from_picture (self, other);
if (other_view)
id = gst_d3d11_h265_dec_get_ref_index (self, other_view->view_id);
if (other_view) {
id = gst_d3d11_h265_dec_get_ref_index (self,
gst_d3d11_decoder_get_output_view_index (other_view));
}
}
self->ref_pic_set_lt_curr[i] = id;
@ -1120,7 +1126,7 @@ gst_d3d11_h265_dec_decode_slice (GstH265Decoder * decoder,
guint d3d11_buffer_size = 0;
gpointer d3d11_buffer = NULL;
gint i;
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
GstH265ScalingList *scaling_list = NULL;
pps = slice->header.pps;
@ -1135,7 +1141,8 @@ gst_d3d11_h265_dec_decode_slice (GstH265Decoder * decoder,
gst_d3d11_h265_dec_fill_picture_params (self, &slice->header, &pic_params);
pic_params.CurrPic.Index7Bits = view->view_id;
pic_params.CurrPic.Index7Bits =
gst_d3d11_decoder_get_output_view_index (view);
pic_params.IrapPicFlag = GST_H265_IS_NAL_TYPE_IRAP (slice->nalu.type);
pic_params.IdrPicFlag = GST_H265_IS_NAL_TYPE_IDR (slice->nalu.type);
pic_params.IntraPicFlag = GST_H265_IS_NAL_TYPE_IRAP (slice->nalu.type);

View file

@ -423,12 +423,12 @@ error:
return GST_FLOW_ERROR;
}
static GstD3D11DecoderOutputView *
static ID3D11VideoDecoderOutputView *
gst_d3d11_vp8_dec_get_output_view_from_picture (GstD3D11Vp8Dec * self,
GstVp8Picture * picture)
{
GstBuffer *view_buffer;
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
view_buffer = (GstBuffer *) gst_vp8_picture_get_user_data (picture);
if (!view_buffer) {
@ -452,7 +452,7 @@ gst_d3d11_vp8_dec_start_picture (GstVp8Decoder * decoder,
GstVp8Picture * picture)
{
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
view = gst_d3d11_vp8_dec_get_output_view_from_picture (self, picture);
if (!view) {
@ -529,7 +529,7 @@ gst_d3d11_vp8_dec_copy_reference_frames (GstD3D11Vp8Dec * self,
DXVA_PicParams_VP8 * params)
{
GstVp8Decoder *decoder = GST_VP8_DECODER (self);
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
if (decoder->alt_ref_picture) {
view = gst_d3d11_vp8_dec_get_output_view_from_picture (self,
@ -539,7 +539,8 @@ gst_d3d11_vp8_dec_copy_reference_frames (GstD3D11Vp8Dec * self,
return;
}
params->alt_fb_idx.Index7Bits = view->view_id;
params->alt_fb_idx.Index7Bits =
gst_d3d11_decoder_get_output_view_index (view);
} else {
params->alt_fb_idx.bPicEntry = 0xff;
}
@ -552,7 +553,8 @@ gst_d3d11_vp8_dec_copy_reference_frames (GstD3D11Vp8Dec * self,
return;
}
params->gld_fb_idx.Index7Bits = view->view_id;
params->gld_fb_idx.Index7Bits =
gst_d3d11_decoder_get_output_view_index (view);
} else {
params->gld_fb_idx.bPicEntry = 0xff;
}
@ -565,7 +567,8 @@ gst_d3d11_vp8_dec_copy_reference_frames (GstD3D11Vp8Dec * self,
return;
}
params->lst_fb_idx.Index7Bits = view->view_id;
params->lst_fb_idx.Index7Bits =
gst_d3d11_decoder_get_output_view_index (view);
} else {
params->lst_fb_idx.bPicEntry = 0xff;
}
@ -779,7 +782,7 @@ gst_d3d11_vp8_dec_decode_picture (GstVp8Decoder * decoder,
{
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
DXVA_PicParams_VP8 pic_params = { 0, };
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
const GstVp8FrameHdr *frame_hdr = &picture->frame_hdr;
view = gst_d3d11_vp8_dec_get_output_view_from_picture (self, picture);
@ -791,7 +794,8 @@ gst_d3d11_vp8_dec_decode_picture (GstVp8Decoder * decoder,
pic_params.first_part_size = frame_hdr->first_part_size;
pic_params.width = self->width;
pic_params.height = self->height;
pic_params.CurrPic.Index7Bits = view->view_id;
pic_params.CurrPic.Index7Bits =
gst_d3d11_decoder_get_output_view_index (view);
pic_params.StatusReportFeedbackNumber = 1;
gst_d3d11_vp8_dec_copy_frame_params (self, picture, parser, &pic_params);

View file

@ -529,12 +529,12 @@ error:
return GST_FLOW_ERROR;
}
static GstD3D11DecoderOutputView *
static ID3D11VideoDecoderOutputView *
gst_d3d11_vp9_dec_get_output_view_from_picture (GstD3D11Vp9Dec * self,
GstVp9Picture * picture)
{
GstBuffer *view_buffer;
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
view_buffer = (GstBuffer *) gst_vp9_picture_get_user_data (picture);
if (!view_buffer) {
@ -558,7 +558,7 @@ gst_d3d11_vp9_dec_start_picture (GstVp9Decoder * decoder,
GstVp9Picture * picture)
{
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
view = gst_d3d11_vp9_dec_get_output_view_from_picture (self, picture);
if (!view) {
@ -657,7 +657,7 @@ gst_d3d11_vp9_dec_copy_reference_frames (GstD3D11Vp9Dec * self,
for (i = 0; i < GST_VP9_REF_FRAMES; i++) {
if (dpb->pic_list[i]) {
GstVp9Picture *other_pic = dpb->pic_list[i];
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
view = gst_d3d11_vp9_dec_get_output_view_from_picture (self, other_pic);
if (!view) {
@ -665,7 +665,8 @@ gst_d3d11_vp9_dec_copy_reference_frames (GstD3D11Vp9Dec * self,
return;
}
params->ref_frame_map[i].Index7Bits = view->view_id;
params->ref_frame_map[i].Index7Bits =
gst_d3d11_decoder_get_output_view_index (view);
params->ref_frame_coded_width[i] = picture->frame_hdr.width;
params->ref_frame_coded_height[i] = picture->frame_hdr.height;
} else {
@ -1019,7 +1020,7 @@ gst_d3d11_vp9_dec_decode_picture (GstVp9Decoder * decoder,
{
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
DXVA_PicParams_VP9 pic_params = { 0, };
GstD3D11DecoderOutputView *view;
ID3D11VideoDecoderOutputView *view;
view = gst_d3d11_vp9_dec_get_output_view_from_picture (self, picture);
if (!view) {
@ -1027,7 +1028,8 @@ gst_d3d11_vp9_dec_decode_picture (GstVp9Decoder * decoder,
return FALSE;
}
pic_params.CurrPic.Index7Bits = view->view_id;
pic_params.CurrPic.Index7Bits =
gst_d3d11_decoder_get_output_view_index (view);
pic_params.uncompressed_header_size_byte_aligned =
picture->frame_hdr.frame_header_length_in_bytes;
pic_params.first_partition_size = picture->frame_hdr.first_partition_size;