mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 04:56:24 +00:00
d3d11decoder: Move zero-copy decision logic into decoder object
Get rid of all duplicated code for zero-copy decision and output buffer allocation Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2117>
This commit is contained in:
parent
03f1ff2042
commit
bcdd2c4984
7 changed files with 130 additions and 298 deletions
|
@ -137,12 +137,16 @@ struct _GstD3D11Decoder
|
||||||
ID3D11VideoDecoder *decoder_handle;
|
ID3D11VideoDecoder *decoder_handle;
|
||||||
|
|
||||||
GstVideoInfo info;
|
GstVideoInfo info;
|
||||||
|
GstVideoInfo output_info;
|
||||||
GstD3D11Codec codec;
|
GstD3D11Codec codec;
|
||||||
gint coded_width;
|
gint coded_width;
|
||||||
gint coded_height;
|
gint coded_height;
|
||||||
DXGI_FORMAT decoder_format;
|
DXGI_FORMAT decoder_format;
|
||||||
gboolean downstream_supports_d3d11;
|
gboolean downstream_supports_d3d11;
|
||||||
|
|
||||||
|
GstVideoCodecState *input_state;
|
||||||
|
GstVideoCodecState *output_state;
|
||||||
|
|
||||||
GstBufferPool *internal_pool;
|
GstBufferPool *internal_pool;
|
||||||
/* Internal pool params */
|
/* Internal pool params */
|
||||||
gint aligned_width;
|
gint aligned_width;
|
||||||
|
@ -176,6 +180,9 @@ static void gst_d3d11_decoder_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
static void gst_d3d11_decoder_dispose (GObject * obj);
|
static void gst_d3d11_decoder_dispose (GObject * obj);
|
||||||
static void gst_d3d11_decoder_finalize (GObject * obj);
|
static void gst_d3d11_decoder_finalize (GObject * obj);
|
||||||
|
static gboolean gst_d3d11_decoder_can_direct_render (GstD3D11Decoder * decoder,
|
||||||
|
GstVideoDecoder * videodec, GstBuffer * view_buffer,
|
||||||
|
gint display_width, gint display_height);
|
||||||
|
|
||||||
#define parent_class gst_d3d11_decoder_parent_class
|
#define parent_class gst_d3d11_decoder_parent_class
|
||||||
G_DEFINE_TYPE (GstD3D11Decoder, gst_d3d11_decoder, GST_TYPE_OBJECT);
|
G_DEFINE_TYPE (GstD3D11Decoder, gst_d3d11_decoder, GST_TYPE_OBJECT);
|
||||||
|
@ -301,6 +308,9 @@ gst_d3d11_decoder_reset (GstD3D11Decoder * self)
|
||||||
|
|
||||||
self->use_array_of_texture = FALSE;
|
self->use_array_of_texture = FALSE;
|
||||||
self->downstream_supports_d3d11 = FALSE;
|
self->downstream_supports_d3d11 = FALSE;
|
||||||
|
|
||||||
|
g_clear_pointer (&self->output_state, gst_video_codec_state_unref);
|
||||||
|
g_clear_pointer (&self->input_state, gst_video_codec_state_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -645,7 +655,8 @@ gst_d3d11_decoder_get_supported_decoder_profile (GstD3D11Decoder * decoder,
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_d3d11_decoder_configure (GstD3D11Decoder * decoder, GstD3D11Codec codec,
|
gst_d3d11_decoder_configure (GstD3D11Decoder * decoder, GstD3D11Codec codec,
|
||||||
GstVideoInfo * info, gint coded_width, gint coded_height, guint dpb_size)
|
GstVideoCodecState * input_state, GstVideoInfo * info, gint coded_width,
|
||||||
|
gint coded_height, guint dpb_size)
|
||||||
{
|
{
|
||||||
const GstD3D11Format *d3d11_format;
|
const GstD3D11Format *d3d11_format;
|
||||||
|
|
||||||
|
@ -653,6 +664,7 @@ gst_d3d11_decoder_configure (GstD3D11Decoder * decoder, GstD3D11Codec codec,
|
||||||
g_return_val_if_fail (codec > GST_D3D11_CODEC_NONE, FALSE);
|
g_return_val_if_fail (codec > GST_D3D11_CODEC_NONE, FALSE);
|
||||||
g_return_val_if_fail (codec < GST_D3D11_CODEC_LAST, FALSE);
|
g_return_val_if_fail (codec < GST_D3D11_CODEC_LAST, FALSE);
|
||||||
g_return_val_if_fail (info != NULL, FALSE);
|
g_return_val_if_fail (info != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (input_state != NULL, FALSE);
|
||||||
g_return_val_if_fail (coded_width >= GST_VIDEO_INFO_WIDTH (info), FALSE);
|
g_return_val_if_fail (coded_width >= GST_VIDEO_INFO_WIDTH (info), FALSE);
|
||||||
g_return_val_if_fail (coded_height >= GST_VIDEO_INFO_HEIGHT (info), FALSE);
|
g_return_val_if_fail (coded_height >= GST_VIDEO_INFO_HEIGHT (info), FALSE);
|
||||||
g_return_val_if_fail (dpb_size > 0, FALSE);
|
g_return_val_if_fail (dpb_size > 0, FALSE);
|
||||||
|
@ -668,7 +680,8 @@ gst_d3d11_decoder_configure (GstD3D11Decoder * decoder, GstD3D11Codec codec,
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder->codec = codec;
|
decoder->codec = codec;
|
||||||
decoder->info = *info;
|
decoder->input_state = gst_video_codec_state_ref (input_state);
|
||||||
|
decoder->info = decoder->output_info = *info;
|
||||||
decoder->coded_width = coded_width;
|
decoder->coded_width = coded_width;
|
||||||
decoder->coded_height = coded_height;
|
decoder->coded_height = coded_height;
|
||||||
decoder->dpb_size = dpb_size;
|
decoder->dpb_size = dpb_size;
|
||||||
|
@ -1192,10 +1205,11 @@ gst_d3d11_decoder_get_output_view_from_buffer (GstD3D11Decoder * decoder,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
copy_to_system (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width,
|
copy_to_system (GstD3D11Decoder * self, GstBuffer * decoder_buffer,
|
||||||
gint display_height, GstBuffer * decoder_buffer, GstBuffer * output)
|
GstBuffer * output)
|
||||||
{
|
{
|
||||||
GstVideoFrame out_frame;
|
GstVideoFrame out_frame;
|
||||||
|
GstVideoInfo *info = &self->output_info;
|
||||||
guint i;
|
guint i;
|
||||||
GstD3D11Memory *in_mem;
|
GstD3D11Memory *in_mem;
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
|
@ -1272,9 +1286,10 @@ copy_to_system (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
copy_to_d3d11 (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width,
|
copy_to_d3d11 (GstD3D11Decoder * self, GstBuffer * decoder_buffer,
|
||||||
gint display_height, GstBuffer * decoder_buffer, GstBuffer * output)
|
GstBuffer * output)
|
||||||
{
|
{
|
||||||
|
GstVideoInfo *info = &self->output_info;
|
||||||
GstD3D11Memory *in_mem;
|
GstD3D11Memory *in_mem;
|
||||||
GstD3D11Memory *out_mem;
|
GstD3D11Memory *out_mem;
|
||||||
GstMapInfo out_map;
|
GstMapInfo out_map;
|
||||||
|
@ -1302,8 +1317,8 @@ copy_to_d3d11 (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width,
|
||||||
src_box.front = 0;
|
src_box.front = 0;
|
||||||
src_box.back = 1;
|
src_box.back = 1;
|
||||||
|
|
||||||
src_box.right = GST_ROUND_UP_2 (GST_VIDEO_INFO_WIDTH (&self->info));
|
src_box.right = GST_ROUND_UP_2 (GST_VIDEO_INFO_WIDTH (info));
|
||||||
src_box.bottom = GST_ROUND_UP_2 (GST_VIDEO_INFO_HEIGHT (&self->info));
|
src_box.bottom = GST_ROUND_UP_2 (GST_VIDEO_INFO_HEIGHT (info));
|
||||||
|
|
||||||
out_subresource_index = gst_d3d11_memory_get_subresource_index (out_mem);
|
out_subresource_index = gst_d3d11_memory_get_subresource_index (out_mem);
|
||||||
device_context->CopySubresourceRegion ((ID3D11Resource *) out_map.data,
|
device_context->CopySubresourceRegion ((ID3D11Resource *) out_map.data,
|
||||||
|
@ -1318,26 +1333,57 @@ copy_to_d3d11 (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width,
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_d3d11_decoder_process_output (GstD3D11Decoder * decoder,
|
gst_d3d11_decoder_process_output (GstD3D11Decoder * decoder,
|
||||||
GstVideoInfo * info, gint display_width, gint display_height,
|
GstVideoDecoder * videodec, gint display_width, gint display_height,
|
||||||
GstBuffer * decoder_buffer, GstBuffer * output)
|
GstBuffer * decoder_buffer, GstBuffer ** output)
|
||||||
{
|
{
|
||||||
gboolean can_device_copy = TRUE;
|
gboolean can_device_copy = TRUE;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
|
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
|
||||||
|
g_return_val_if_fail (GST_IS_VIDEO_DECODER (videodec), FALSE);
|
||||||
g_return_val_if_fail (GST_IS_BUFFER (decoder_buffer), FALSE);
|
g_return_val_if_fail (GST_IS_BUFFER (decoder_buffer), FALSE);
|
||||||
g_return_val_if_fail (GST_IS_BUFFER (output), FALSE);
|
g_return_val_if_fail (output != NULL, FALSE);
|
||||||
|
|
||||||
|
if (display_width != GST_VIDEO_INFO_WIDTH (&decoder->output_info) ||
|
||||||
|
display_height != GST_VIDEO_INFO_HEIGHT (&decoder->output_info)) {
|
||||||
|
GST_INFO_OBJECT (videodec, "Frame size changed, do renegotiate");
|
||||||
|
|
||||||
|
gst_video_info_set_format (&decoder->output_info,
|
||||||
|
GST_VIDEO_INFO_FORMAT (&decoder->info),
|
||||||
|
display_width, display_height);
|
||||||
|
GST_VIDEO_INFO_INTERLACE_MODE (&decoder->output_info) =
|
||||||
|
GST_VIDEO_INFO_INTERLACE_MODE (&decoder->info);
|
||||||
|
|
||||||
|
if (!gst_video_decoder_negotiate (videodec)) {
|
||||||
|
GST_ERROR_OBJECT (videodec, "Failed to re-negotiate with new frame size");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_d3d11_decoder_can_direct_render (decoder, videodec, decoder_buffer,
|
||||||
|
display_width, display_height)) {
|
||||||
|
GstMemory *mem;
|
||||||
|
|
||||||
|
mem = gst_buffer_peek_memory (decoder_buffer, 0);
|
||||||
|
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
||||||
|
|
||||||
|
*output = gst_buffer_ref (decoder_buffer);
|
||||||
|
|
||||||
/* if decoder buffer is intended to be outputted and we don't need to
|
|
||||||
* do post processing, do nothing here */
|
|
||||||
if (decoder_buffer == output)
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*output = gst_video_decoder_allocate_output_buffer (videodec);
|
||||||
|
if (*output == NULL) {
|
||||||
|
GST_ERROR_OBJECT (videodec, "Couldn't allocate output buffer");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* decoder buffer must have single memory */
|
/* decoder buffer must have single memory */
|
||||||
if (gst_buffer_n_memory (decoder_buffer) == gst_buffer_n_memory (output)) {
|
if (gst_buffer_n_memory (decoder_buffer) == gst_buffer_n_memory (*output)) {
|
||||||
GstMemory *mem;
|
GstMemory *mem;
|
||||||
GstD3D11Memory *dmem;
|
GstD3D11Memory *dmem;
|
||||||
|
|
||||||
mem = gst_buffer_peek_memory (output, 0);
|
mem = gst_buffer_peek_memory (*output, 0);
|
||||||
if (!gst_is_d3d11_memory (mem)) {
|
if (!gst_is_d3d11_memory (mem)) {
|
||||||
can_device_copy = FALSE;
|
can_device_copy = FALSE;
|
||||||
goto do_process;
|
goto do_process;
|
||||||
|
@ -1352,32 +1398,29 @@ gst_d3d11_decoder_process_output (GstD3D11Decoder * decoder,
|
||||||
|
|
||||||
do_process:
|
do_process:
|
||||||
if (can_device_copy) {
|
if (can_device_copy) {
|
||||||
return copy_to_d3d11 (decoder, info, display_width, display_height,
|
return copy_to_d3d11 (decoder, decoder_buffer, *output);
|
||||||
decoder_buffer, output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return copy_to_system (decoder, info, display_width, display_height,
|
return copy_to_system (decoder, decoder_buffer, *output);
|
||||||
decoder_buffer, output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_d3d11_decoder_negotiate (GstD3D11Decoder * decoder,
|
gst_d3d11_decoder_negotiate (GstD3D11Decoder * decoder,
|
||||||
GstVideoDecoder * videodec, GstVideoCodecState * input_state,
|
GstVideoDecoder * videodec)
|
||||||
GstVideoCodecState ** output_state)
|
|
||||||
{
|
{
|
||||||
|
GstVideoInfo *info;
|
||||||
GstCaps *peer_caps;
|
GstCaps *peer_caps;
|
||||||
GstVideoCodecState *state = NULL;
|
GstVideoCodecState *state = NULL;
|
||||||
gboolean alternate_interlaced;
|
gboolean alternate_interlaced;
|
||||||
gboolean alternate_supported = FALSE;
|
gboolean alternate_supported = FALSE;
|
||||||
gboolean d3d11_supported = FALSE;
|
gboolean d3d11_supported = FALSE;
|
||||||
GstVideoInfo *info;
|
GstVideoCodecState *input_state;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
|
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
|
||||||
g_return_val_if_fail (GST_IS_VIDEO_DECODER (videodec), FALSE);
|
g_return_val_if_fail (GST_IS_VIDEO_DECODER (videodec), FALSE);
|
||||||
g_return_val_if_fail (input_state != NULL, FALSE);
|
|
||||||
g_return_val_if_fail (output_state != NULL, FALSE);
|
|
||||||
|
|
||||||
info = &decoder->info;
|
info = &decoder->output_info;
|
||||||
|
input_state = decoder->input_state;
|
||||||
|
|
||||||
alternate_interlaced =
|
alternate_interlaced =
|
||||||
(GST_VIDEO_INFO_INTERLACE_MODE (info) ==
|
(GST_VIDEO_INFO_INTERLACE_MODE (info) ==
|
||||||
|
@ -1463,9 +1506,8 @@ gst_d3d11_decoder_negotiate (GstD3D11Decoder * decoder,
|
||||||
|
|
||||||
state->caps = gst_video_info_to_caps (&state->info);
|
state->caps = gst_video_info_to_caps (&state->info);
|
||||||
|
|
||||||
if (*output_state)
|
g_clear_pointer (&decoder->output_state, gst_video_codec_state_unref);
|
||||||
gst_video_codec_state_unref (*output_state);
|
decoder->output_state = state;
|
||||||
*output_state = state;
|
|
||||||
|
|
||||||
if (d3d11_supported) {
|
if (d3d11_supported) {
|
||||||
gst_caps_set_features (state->caps, 0,
|
gst_caps_set_features (state->caps, 0,
|
||||||
|
@ -1632,20 +1674,28 @@ gst_d3d11_decoder_flush (GstD3D11Decoder * decoder, GstVideoDecoder * videodec)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
static gboolean
|
||||||
gst_d3d11_decoder_can_direct_render (GstD3D11Decoder * decoder,
|
gst_d3d11_decoder_can_direct_render (GstD3D11Decoder * decoder,
|
||||||
GstBuffer * view_buffer, GstMiniObject * picture)
|
GstVideoDecoder * videodec, GstBuffer * view_buffer,
|
||||||
|
gint display_width, gint display_height)
|
||||||
{
|
{
|
||||||
GstMemory *mem;
|
GstMemory *mem;
|
||||||
GstD3D11PoolAllocator *alloc;
|
GstD3D11PoolAllocator *alloc;
|
||||||
guint max_size = 0, outstanding_size = 0;
|
guint max_size = 0, outstanding_size = 0;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
|
/* We don't support direct render for reverse playback */
|
||||||
g_return_val_if_fail (GST_IS_BUFFER (view_buffer), FALSE);
|
if (videodec->input_segment.rate < 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (!decoder->can_direct_rendering || !decoder->downstream_supports_d3d11)
|
if (!decoder->can_direct_rendering || !decoder->downstream_supports_d3d11)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* different size, need copy */
|
||||||
|
/* TODO: crop meta */
|
||||||
|
if (display_width != GST_VIDEO_INFO_WIDTH (&decoder->info) ||
|
||||||
|
display_height != GST_VIDEO_INFO_HEIGHT (&decoder->info))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* we can do direct render in this case, since there is no DPB pool size
|
/* we can do direct render in this case, since there is no DPB pool size
|
||||||
* limit */
|
* limit */
|
||||||
if (decoder->use_array_of_texture)
|
if (decoder->use_array_of_texture)
|
||||||
|
|
|
@ -61,6 +61,7 @@ gboolean gst_d3d11_decoder_is_configured (GstD3D11Decoder * decoder);
|
||||||
|
|
||||||
gboolean gst_d3d11_decoder_configure (GstD3D11Decoder * decoder,
|
gboolean gst_d3d11_decoder_configure (GstD3D11Decoder * decoder,
|
||||||
GstD3D11Codec codec,
|
GstD3D11Codec codec,
|
||||||
|
GstVideoCodecState * input_state,
|
||||||
GstVideoInfo * info,
|
GstVideoInfo * info,
|
||||||
gint coded_width,
|
gint coded_width,
|
||||||
gint coded_height,
|
gint coded_height,
|
||||||
|
@ -93,16 +94,14 @@ ID3D11VideoDecoderOutputView * gst_d3d11_decoder_get_output_view_from_buffer (Gs
|
||||||
guint8 * view_id);
|
guint8 * view_id);
|
||||||
|
|
||||||
gboolean gst_d3d11_decoder_process_output (GstD3D11Decoder * decoder,
|
gboolean gst_d3d11_decoder_process_output (GstD3D11Decoder * decoder,
|
||||||
GstVideoInfo * info,
|
GstVideoDecoder * videodec,
|
||||||
gint display_width,
|
gint display_width,
|
||||||
gint display_height,
|
gint display_height,
|
||||||
GstBuffer * decoder_buffer,
|
GstBuffer * decoder_buffer,
|
||||||
GstBuffer * output);
|
GstBuffer ** output);
|
||||||
|
|
||||||
gboolean gst_d3d11_decoder_negotiate (GstD3D11Decoder * decoder,
|
gboolean gst_d3d11_decoder_negotiate (GstD3D11Decoder * decoder,
|
||||||
GstVideoDecoder * videodec,
|
GstVideoDecoder * videodec);
|
||||||
GstVideoCodecState * input_state,
|
|
||||||
GstVideoCodecState ** output_state);
|
|
||||||
|
|
||||||
gboolean gst_d3d11_decoder_decide_allocation (GstD3D11Decoder * decoder,
|
gboolean gst_d3d11_decoder_decide_allocation (GstD3D11Decoder * decoder,
|
||||||
GstVideoDecoder * videodec,
|
GstVideoDecoder * videodec,
|
||||||
|
@ -111,10 +110,6 @@ gboolean gst_d3d11_decoder_decide_allocation (GstD3D11Decoder * decod
|
||||||
gboolean gst_d3d11_decoder_flush (GstD3D11Decoder * decoder,
|
gboolean gst_d3d11_decoder_flush (GstD3D11Decoder * decoder,
|
||||||
GstVideoDecoder * videodec);
|
GstVideoDecoder * videodec);
|
||||||
|
|
||||||
gboolean gst_d3d11_decoder_can_direct_render (GstD3D11Decoder * decoder,
|
|
||||||
GstBuffer * view_buffer,
|
|
||||||
GstMiniObject * picture);
|
|
||||||
|
|
||||||
/* Utils for class registration */
|
/* Utils for class registration */
|
||||||
gboolean gst_d3d11_decoder_util_is_legacy_device (GstD3D11Device * device);
|
gboolean gst_d3d11_decoder_util_is_legacy_device (GstD3D11Device * device);
|
||||||
|
|
||||||
|
|
|
@ -100,8 +100,6 @@ typedef struct _GstD3D11H264Dec
|
||||||
{
|
{
|
||||||
GstH264Decoder parent;
|
GstH264Decoder parent;
|
||||||
|
|
||||||
GstVideoCodecState *output_state;
|
|
||||||
|
|
||||||
GstD3D11Device *device;
|
GstD3D11Device *device;
|
||||||
|
|
||||||
gint width, height;
|
gint width, height;
|
||||||
|
@ -352,10 +350,6 @@ gst_d3d11_h264_dec_close (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
|
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
|
||||||
|
|
||||||
if (self->output_state)
|
|
||||||
gst_video_codec_state_unref (self->output_state);
|
|
||||||
self->output_state = NULL;
|
|
||||||
|
|
||||||
gst_clear_object (&self->d3d11_decoder);
|
gst_clear_object (&self->d3d11_decoder);
|
||||||
gst_clear_object (&self->device);
|
gst_clear_object (&self->device);
|
||||||
|
|
||||||
|
@ -366,12 +360,9 @@ static gboolean
|
||||||
gst_d3d11_h264_dec_negotiate (GstVideoDecoder * decoder)
|
gst_d3d11_h264_dec_negotiate (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
|
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
|
||||||
GstH264Decoder *h264dec = GST_H264_DECODER (decoder);
|
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder,
|
if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder))
|
||||||
h264dec->input_state, &self->output_state)) {
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
||||||
}
|
}
|
||||||
|
@ -506,7 +497,7 @@ gst_d3d11_h264_dec_new_sequence (GstH264Decoder * decoder,
|
||||||
*/
|
*/
|
||||||
self->max_dpb_size = max_dpb_size;
|
self->max_dpb_size = max_dpb_size;
|
||||||
if (!gst_d3d11_decoder_configure (self->d3d11_decoder, GST_D3D11_CODEC_H264,
|
if (!gst_d3d11_decoder_configure (self->d3d11_decoder, GST_D3D11_CODEC_H264,
|
||||||
&info, self->coded_width, self->coded_height,
|
decoder->input_state, &info, self->coded_width, self->coded_height,
|
||||||
/* Additional 4 views margin for zero-copy rendering */
|
/* Additional 4 views margin for zero-copy rendering */
|
||||||
max_dpb_size + 4)) {
|
max_dpb_size + 4)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to create decoder");
|
GST_ERROR_OBJECT (self, "Failed to create decoder");
|
||||||
|
@ -825,9 +816,7 @@ gst_d3d11_h264_dec_output_picture (GstH264Decoder * decoder,
|
||||||
{
|
{
|
||||||
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
|
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
|
||||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||||
GstBuffer *output_buffer = NULL;
|
|
||||||
GstBuffer *view_buffer;
|
GstBuffer *view_buffer;
|
||||||
gboolean direct_rendering = FALSE;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (self,
|
GST_LOG_OBJECT (self,
|
||||||
"Outputting picture %p (poc %d)", picture, picture->pic_order_cnt);
|
"Outputting picture %p (poc %d)", picture, picture->pic_order_cnt);
|
||||||
|
@ -839,37 +828,8 @@ gst_d3d11_h264_dec_output_picture (GstH264Decoder * decoder,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if downstream is d3d11 element and forward playback case,
|
if (!gst_d3d11_decoder_process_output (self->d3d11_decoder, vdec,
|
||||||
* expose our decoder view without copy. In case of reverse playback, however,
|
self->width, self->height, view_buffer, &frame->output_buffer)) {
|
||||||
* we cannot do that since baseclass will store the decoded buffer
|
|
||||||
* up to gop size but our dpb pool cannot be increased */
|
|
||||||
if (GST_VIDEO_DECODER (self)->input_segment.rate > 0
|
|
||||||
&& gst_d3d11_decoder_can_direct_render (self->d3d11_decoder, view_buffer,
|
|
||||||
GST_MINI_OBJECT_CAST (picture))) {
|
|
||||||
direct_rendering = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (direct_rendering) {
|
|
||||||
GstMemory *mem;
|
|
||||||
output_buffer = gst_buffer_ref (view_buffer);
|
|
||||||
mem = gst_buffer_peek_memory (output_buffer, 0);
|
|
||||||
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
|
||||||
} else {
|
|
||||||
output_buffer = gst_video_decoder_allocate_output_buffer (vdec);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!output_buffer) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't allocate output buffer");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->output_buffer = output_buffer;
|
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_process_output (self->d3d11_decoder,
|
|
||||||
&self->output_state->info,
|
|
||||||
GST_VIDEO_INFO_WIDTH (&self->output_state->info),
|
|
||||||
GST_VIDEO_INFO_HEIGHT (&self->output_state->info),
|
|
||||||
view_buffer, output_buffer)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,8 +70,6 @@ typedef struct _GstD3D11H265Dec
|
||||||
{
|
{
|
||||||
GstH265Decoder parent;
|
GstH265Decoder parent;
|
||||||
|
|
||||||
GstVideoCodecState *output_state;
|
|
||||||
|
|
||||||
GstD3D11Device *device;
|
GstD3D11Device *device;
|
||||||
|
|
||||||
gint width, height;
|
gint width, height;
|
||||||
|
@ -307,10 +305,6 @@ gst_d3d11_h265_dec_close (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
|
GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
|
||||||
|
|
||||||
if (self->output_state)
|
|
||||||
gst_video_codec_state_unref (self->output_state);
|
|
||||||
self->output_state = NULL;
|
|
||||||
|
|
||||||
gst_clear_object (&self->d3d11_decoder);
|
gst_clear_object (&self->d3d11_decoder);
|
||||||
gst_clear_object (&self->device);
|
gst_clear_object (&self->device);
|
||||||
|
|
||||||
|
@ -321,12 +315,9 @@ static gboolean
|
||||||
gst_d3d11_h265_dec_negotiate (GstVideoDecoder * decoder)
|
gst_d3d11_h265_dec_negotiate (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
|
GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
|
||||||
GstH265Decoder *h265dec = GST_H265_DECODER (decoder);
|
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder,
|
if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder))
|
||||||
h265dec->input_state, &self->output_state)) {
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
||||||
}
|
}
|
||||||
|
@ -466,7 +457,7 @@ gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder,
|
||||||
GST_VIDEO_INFO_INTERLACE_MODE (&info) = self->interlace_mode;
|
GST_VIDEO_INFO_INTERLACE_MODE (&info) = self->interlace_mode;
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_configure (self->d3d11_decoder, GST_D3D11_CODEC_H265,
|
if (!gst_d3d11_decoder_configure (self->d3d11_decoder, GST_D3D11_CODEC_H265,
|
||||||
&info, self->coded_width, self->coded_height,
|
decoder->input_state, &info, self->coded_width, self->coded_height,
|
||||||
/* Additional 4 views margin for zero-copy rendering */
|
/* Additional 4 views margin for zero-copy rendering */
|
||||||
max_dpb_size + 4)) {
|
max_dpb_size + 4)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to create decoder");
|
GST_ERROR_OBJECT (self, "Failed to create decoder");
|
||||||
|
@ -799,9 +790,7 @@ gst_d3d11_h265_dec_output_picture (GstH265Decoder * decoder,
|
||||||
{
|
{
|
||||||
GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
|
GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder);
|
||||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||||
GstBuffer *output_buffer = NULL;
|
|
||||||
GstBuffer *view_buffer;
|
GstBuffer *view_buffer;
|
||||||
gboolean direct_rendering = FALSE;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (self, "Outputting picture %p, poc %d, picture_struct %d, "
|
GST_LOG_OBJECT (self, "Outputting picture %p, poc %d, picture_struct %d, "
|
||||||
"buffer flags 0x%x", picture, picture->pic_order_cnt, picture->pic_struct,
|
"buffer flags 0x%x", picture, picture->pic_order_cnt, picture->pic_struct,
|
||||||
|
@ -814,41 +803,9 @@ gst_d3d11_h265_dec_output_picture (GstH265Decoder * decoder,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if downstream is d3d11 element and forward playback case,
|
if (!gst_d3d11_decoder_process_output (self->d3d11_decoder, vdec,
|
||||||
* expose our decoder view without copy. In case of reverse playback, however,
|
self->width, self->height, view_buffer, &frame->output_buffer)) {
|
||||||
* we cannot do that since baseclass will store the decoded buffer
|
|
||||||
* up to gop size but our dpb pool cannot be increased */
|
|
||||||
if (GST_VIDEO_DECODER (self)->input_segment.rate > 0
|
|
||||||
&& gst_d3d11_decoder_can_direct_render (self->d3d11_decoder, view_buffer,
|
|
||||||
GST_MINI_OBJECT_CAST (picture))) {
|
|
||||||
direct_rendering = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (direct_rendering) {
|
|
||||||
GstMemory *mem;
|
|
||||||
|
|
||||||
output_buffer = gst_buffer_ref (view_buffer);
|
|
||||||
mem = gst_buffer_peek_memory (output_buffer, 0);
|
|
||||||
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
|
||||||
} else {
|
|
||||||
output_buffer =
|
|
||||||
gst_video_decoder_allocate_output_buffer (GST_VIDEO_DECODER (self));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!output_buffer) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't allocate output buffer");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->output_buffer = output_buffer;
|
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_process_output (self->d3d11_decoder,
|
|
||||||
&self->output_state->info,
|
|
||||||
GST_VIDEO_INFO_WIDTH (&self->output_state->info),
|
|
||||||
GST_VIDEO_INFO_HEIGHT (&self->output_state->info),
|
|
||||||
view_buffer, output_buffer)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
||||||
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,6 @@ typedef struct _GstD3D11Mpeg2Dec
|
||||||
{
|
{
|
||||||
GstMpeg2Decoder parent;
|
GstMpeg2Decoder parent;
|
||||||
|
|
||||||
GstVideoCodecState *output_state;
|
|
||||||
GstD3D11Device *device;
|
GstD3D11Device *device;
|
||||||
GstD3D11Decoder *d3d11_decoder;
|
GstD3D11Decoder *d3d11_decoder;
|
||||||
|
|
||||||
|
@ -308,12 +307,9 @@ static gboolean
|
||||||
gst_d3d11_mpeg2_dec_negotiate (GstVideoDecoder * decoder)
|
gst_d3d11_mpeg2_dec_negotiate (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstD3D11Mpeg2Dec *self = GST_D3D11_MPEG2_DEC (decoder);
|
GstD3D11Mpeg2Dec *self = GST_D3D11_MPEG2_DEC (decoder);
|
||||||
GstMpeg2Decoder *mpeg2dec = GST_MPEG2_DECODER (decoder);
|
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder,
|
if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder))
|
||||||
mpeg2dec->input_state, &self->output_state)) {
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
||||||
}
|
}
|
||||||
|
@ -431,8 +427,8 @@ gst_d3d11_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
|
||||||
GST_VIDEO_INFO_INTERLACE_MODE (&info) = GST_VIDEO_INTERLACE_MODE_MIXED;
|
GST_VIDEO_INFO_INTERLACE_MODE (&info) = GST_VIDEO_INTERLACE_MODE_MIXED;
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_configure (self->d3d11_decoder,
|
if (!gst_d3d11_decoder_configure (self->d3d11_decoder,
|
||||||
GST_D3D11_CODEC_MPEG2, &info, self->width, self->height,
|
GST_D3D11_CODEC_MPEG2, decoder->input_state, &info,
|
||||||
NUM_OUTPUT_VIEW)) {
|
self->width, self->height, NUM_OUTPUT_VIEW)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to create decoder");
|
GST_ERROR_OBJECT (self, "Failed to create decoder");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -886,9 +882,7 @@ gst_d3d11_mpeg2_dec_output_picture (GstMpeg2Decoder * decoder,
|
||||||
{
|
{
|
||||||
GstD3D11Mpeg2Dec *self = GST_D3D11_MPEG2_DEC (decoder);
|
GstD3D11Mpeg2Dec *self = GST_D3D11_MPEG2_DEC (decoder);
|
||||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||||
GstBuffer *output_buffer = NULL;
|
|
||||||
GstBuffer *view_buffer;
|
GstBuffer *view_buffer;
|
||||||
gboolean direct_rendering = FALSE;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (self, "Outputting picture %p", picture);
|
GST_LOG_OBJECT (self, "Outputting picture %p", picture);
|
||||||
|
|
||||||
|
@ -899,38 +893,8 @@ gst_d3d11_mpeg2_dec_output_picture (GstMpeg2Decoder * decoder,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if downstream is d3d11 element and forward playback case,
|
if (!gst_d3d11_decoder_process_output (self->d3d11_decoder, vdec,
|
||||||
* expose our decoder view without copy. In case of reverse playback, however,
|
self->width, self->height, view_buffer, &frame->output_buffer)) {
|
||||||
* we cannot do that since baseclass will store the decoded buffer
|
|
||||||
* up to gop size but our dpb pool cannot be increased */
|
|
||||||
if (GST_VIDEO_DECODER (self)->input_segment.rate > 0
|
|
||||||
&& gst_d3d11_decoder_can_direct_render (self->d3d11_decoder, view_buffer,
|
|
||||||
GST_MINI_OBJECT_CAST (picture))) {
|
|
||||||
direct_rendering = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (direct_rendering) {
|
|
||||||
GstMemory *mem;
|
|
||||||
|
|
||||||
output_buffer = gst_buffer_ref (view_buffer);
|
|
||||||
mem = gst_buffer_peek_memory (output_buffer, 0);
|
|
||||||
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
|
||||||
} else {
|
|
||||||
output_buffer = gst_video_decoder_allocate_output_buffer (vdec);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!output_buffer) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't allocate output buffer");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->output_buffer = output_buffer;
|
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_process_output (self->d3d11_decoder,
|
|
||||||
&self->output_state->info,
|
|
||||||
GST_VIDEO_INFO_WIDTH (&self->output_state->info),
|
|
||||||
GST_VIDEO_INFO_HEIGHT (&self->output_state->info),
|
|
||||||
view_buffer, output_buffer)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,6 @@ typedef struct _GstD3D11Vp8Dec
|
||||||
{
|
{
|
||||||
GstVp8Decoder parent;
|
GstVp8Decoder parent;
|
||||||
|
|
||||||
GstVideoCodecState *output_state;
|
|
||||||
GstD3D11Device *device;
|
GstD3D11Device *device;
|
||||||
GstD3D11Decoder *d3d11_decoder;
|
GstD3D11Decoder *d3d11_decoder;
|
||||||
|
|
||||||
|
@ -272,12 +271,9 @@ static gboolean
|
||||||
gst_d3d11_vp8_dec_negotiate (GstVideoDecoder * decoder)
|
gst_d3d11_vp8_dec_negotiate (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
|
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
|
||||||
GstVp8Decoder *vp8dec = GST_VP8_DECODER (decoder);
|
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder,
|
if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder))
|
||||||
decoder, vp8dec->input_state, &self->output_state)) {
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
||||||
}
|
}
|
||||||
|
@ -345,7 +341,8 @@ gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
|
||||||
self->out_format, self->width, self->height);
|
self->out_format, self->width, self->height);
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_configure (self->d3d11_decoder, GST_D3D11_CODEC_VP8,
|
if (!gst_d3d11_decoder_configure (self->d3d11_decoder, GST_D3D11_CODEC_VP8,
|
||||||
&info, self->width, self->height, NUM_OUTPUT_VIEW)) {
|
decoder->input_state, &info, self->width, self->height,
|
||||||
|
NUM_OUTPUT_VIEW)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to create decoder");
|
GST_ERROR_OBJECT (self, "Failed to create decoder");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -388,9 +385,7 @@ gst_d3d11_vp8_dec_output_picture (GstVp8Decoder * decoder,
|
||||||
{
|
{
|
||||||
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
|
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
|
||||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||||
GstBuffer *output_buffer = NULL;
|
|
||||||
GstBuffer *view_buffer;
|
GstBuffer *view_buffer;
|
||||||
gboolean direct_rendering = FALSE;
|
|
||||||
|
|
||||||
g_assert (picture->frame_hdr.show_frame);
|
g_assert (picture->frame_hdr.show_frame);
|
||||||
|
|
||||||
|
@ -403,37 +398,8 @@ gst_d3d11_vp8_dec_output_picture (GstVp8Decoder * decoder,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if downstream is d3d11 element and forward playback case,
|
if (!gst_d3d11_decoder_process_output (self->d3d11_decoder, vdec,
|
||||||
* expose our decoder view without copy. In case of reverse playback, however,
|
self->width, self->height, view_buffer, &frame->output_buffer)) {
|
||||||
* we cannot do that since baseclass will store the decoded buffer
|
|
||||||
* up to gop size but our dpb pool cannot be increased */
|
|
||||||
if (GST_VIDEO_DECODER (self)->input_segment.rate > 0
|
|
||||||
&& gst_d3d11_decoder_can_direct_render (self->d3d11_decoder, view_buffer,
|
|
||||||
GST_MINI_OBJECT_CAST (picture))) {
|
|
||||||
direct_rendering = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (direct_rendering) {
|
|
||||||
GstMemory *mem;
|
|
||||||
|
|
||||||
output_buffer = gst_buffer_ref (view_buffer);
|
|
||||||
mem = gst_buffer_peek_memory (output_buffer, 0);
|
|
||||||
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
|
||||||
} else {
|
|
||||||
output_buffer = gst_video_decoder_allocate_output_buffer (vdec);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!output_buffer) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't allocate output buffer");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->output_buffer = output_buffer;
|
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_process_output (self->d3d11_decoder,
|
|
||||||
&self->output_state->info,
|
|
||||||
picture->frame_hdr.width, picture->frame_hdr.height,
|
|
||||||
view_buffer, output_buffer)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,16 +103,8 @@ typedef struct _GstD3D11Vp9Dec
|
||||||
{
|
{
|
||||||
GstVp9Decoder parent;
|
GstVp9Decoder parent;
|
||||||
|
|
||||||
GstVideoCodecState *output_state;
|
|
||||||
|
|
||||||
GstD3D11Device *device;
|
GstD3D11Device *device;
|
||||||
|
|
||||||
GstD3D11Decoder *d3d11_decoder;
|
GstD3D11Decoder *d3d11_decoder;
|
||||||
|
|
||||||
guint width, height;
|
|
||||||
GstVP9Profile profile;
|
|
||||||
|
|
||||||
GstVideoFormat out_format;
|
|
||||||
} GstD3D11Vp9Dec;
|
} GstD3D11Vp9Dec;
|
||||||
|
|
||||||
typedef struct _GstD3D11Vp9DecClass
|
typedef struct _GstD3D11Vp9DecClass
|
||||||
|
@ -310,12 +302,9 @@ static gboolean
|
||||||
gst_d3d11_vp9_dec_negotiate (GstVideoDecoder * decoder)
|
gst_d3d11_vp9_dec_negotiate (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
|
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
|
||||||
GstVp9Decoder *vp9dec = GST_VP9_DECODER (decoder);
|
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder,
|
if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder))
|
||||||
decoder, vp9dec->input_state, &self->output_state)) {
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
|
||||||
}
|
}
|
||||||
|
@ -370,53 +359,34 @@ gst_d3d11_vp9_dec_new_sequence (GstVp9Decoder * decoder,
|
||||||
const GstVp9Parser * parser, const GstVp9FrameHdr * frame_hdr)
|
const GstVp9Parser * parser, const GstVp9FrameHdr * frame_hdr)
|
||||||
{
|
{
|
||||||
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
|
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
|
||||||
gboolean modified = FALSE;
|
GstVideoInfo info;
|
||||||
|
GstVideoFormat out_format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||||
|
|
||||||
GST_LOG_OBJECT (self, "new sequence");
|
GST_LOG_OBJECT (self, "new sequence");
|
||||||
|
|
||||||
if (self->width < frame_hdr->width || self->height < frame_hdr->height) {
|
if (frame_hdr->profile == GST_VP9_PROFILE_0)
|
||||||
self->width = frame_hdr->width;
|
out_format = GST_VIDEO_FORMAT_NV12;
|
||||||
self->height = frame_hdr->height;
|
else if (frame_hdr->profile == GST_VP9_PROFILE_2)
|
||||||
GST_INFO_OBJECT (self, "resolution changed %dx%d",
|
out_format = GST_VIDEO_FORMAT_P010_10LE;
|
||||||
self->width, self->height);
|
|
||||||
modified = TRUE;
|
if (out_format == GST_VIDEO_FORMAT_UNKNOWN) {
|
||||||
|
GST_ERROR_OBJECT (self, "Could not support profile %d", frame_hdr->profile);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->profile != frame_hdr->profile) {
|
gst_video_info_set_format (&info,
|
||||||
self->profile = (GstVP9Profile) frame_hdr->profile;
|
out_format, frame_hdr->width, frame_hdr->height);
|
||||||
GST_INFO_OBJECT (self, "profile changed %d", self->profile);
|
|
||||||
modified = TRUE;
|
if (!gst_d3d11_decoder_configure (self->d3d11_decoder, GST_D3D11_CODEC_VP9,
|
||||||
|
decoder->input_state, &info, (gint) frame_hdr->width,
|
||||||
|
(gint) frame_hdr->height, NUM_OUTPUT_VIEW)) {
|
||||||
|
GST_ERROR_OBJECT (self, "Failed to create decoder");
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modified || !gst_d3d11_decoder_is_configured (self->d3d11_decoder)) {
|
if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
|
||||||
GstVideoInfo info;
|
GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
|
||||||
|
return FALSE;
|
||||||
self->out_format = GST_VIDEO_FORMAT_UNKNOWN;
|
|
||||||
|
|
||||||
if (self->profile == GST_VP9_PROFILE_0) {
|
|
||||||
self->out_format = GST_VIDEO_FORMAT_NV12;
|
|
||||||
} else if (self->profile == GST_VP9_PROFILE_2) {
|
|
||||||
self->out_format = GST_VIDEO_FORMAT_P010_10LE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->out_format == GST_VIDEO_FORMAT_UNKNOWN) {
|
|
||||||
GST_ERROR_OBJECT (self, "Could not support profile %d", self->profile);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_video_info_set_format (&info,
|
|
||||||
self->out_format, self->width, self->height);
|
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_configure (self->d3d11_decoder, GST_D3D11_CODEC_VP9,
|
|
||||||
&info, self->width, self->height, NUM_OUTPUT_VIEW)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Failed to create decoder");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
|
|
||||||
GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -479,9 +449,7 @@ gst_d3d11_vp9_dec_output_picture (GstVp9Decoder * decoder,
|
||||||
{
|
{
|
||||||
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
|
GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
|
||||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||||
GstBuffer *output_buffer = NULL;
|
|
||||||
GstBuffer *view_buffer;
|
GstBuffer *view_buffer;
|
||||||
gboolean direct_rendering = FALSE;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (self, "Outputting picture %p", picture);
|
GST_LOG_OBJECT (self, "Outputting picture %p", picture);
|
||||||
|
|
||||||
|
@ -492,37 +460,9 @@ gst_d3d11_vp9_dec_output_picture (GstVp9Decoder * decoder,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if downstream is d3d11 element and forward playback case,
|
if (!gst_d3d11_decoder_process_output (self->d3d11_decoder, vdec,
|
||||||
* expose our decoder view without copy. In case of reverse playback, however,
|
picture->frame_hdr.width, picture->frame_hdr.height, view_buffer,
|
||||||
* we cannot do that since baseclass will store the decoded buffer
|
&frame->output_buffer)) {
|
||||||
* up to gop size but our dpb pool cannot be increased */
|
|
||||||
if (GST_VIDEO_DECODER (self)->input_segment.rate > 0
|
|
||||||
&& gst_d3d11_decoder_can_direct_render (self->d3d11_decoder, view_buffer,
|
|
||||||
GST_MINI_OBJECT_CAST (picture))) {
|
|
||||||
direct_rendering = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (direct_rendering) {
|
|
||||||
GstMemory *mem;
|
|
||||||
|
|
||||||
output_buffer = gst_buffer_ref (view_buffer);
|
|
||||||
mem = gst_buffer_peek_memory (output_buffer, 0);
|
|
||||||
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
|
||||||
} else {
|
|
||||||
output_buffer = gst_video_decoder_allocate_output_buffer (vdec);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!output_buffer) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't allocate output buffer");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->output_buffer = output_buffer;
|
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_process_output (self->d3d11_decoder,
|
|
||||||
&self->output_state->info,
|
|
||||||
picture->frame_hdr.width, picture->frame_hdr.height,
|
|
||||||
view_buffer, output_buffer)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue