diff --git a/sys/d3d11/gstd3d11decoder.cpp b/sys/d3d11/gstd3d11decoder.cpp index c62954392a..636c71cab7 100644 --- a/sys/d3d11/gstd3d11decoder.cpp +++ b/sys/d3d11/gstd3d11decoder.cpp @@ -137,12 +137,16 @@ struct _GstD3D11Decoder ID3D11VideoDecoder *decoder_handle; GstVideoInfo info; + GstVideoInfo output_info; GstD3D11Codec codec; gint coded_width; gint coded_height; DXGI_FORMAT decoder_format; gboolean downstream_supports_d3d11; + GstVideoCodecState *input_state; + GstVideoCodecState *output_state; + GstBufferPool *internal_pool; /* Internal pool params */ gint aligned_width; @@ -176,6 +180,9 @@ static void gst_d3d11_decoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void gst_d3d11_decoder_dispose (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 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->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 @@ -645,7 +655,8 @@ gst_d3d11_decoder_get_supported_decoder_profile (GstD3D11Decoder * decoder, gboolean 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; @@ -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_LAST, 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_height >= GST_VIDEO_INFO_HEIGHT (info), 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->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_height = coded_height; decoder->dpb_size = dpb_size; @@ -1192,10 +1205,11 @@ gst_d3d11_decoder_get_output_view_from_buffer (GstD3D11Decoder * decoder, } static gboolean -copy_to_system (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width, - gint display_height, GstBuffer * decoder_buffer, GstBuffer * output) +copy_to_system (GstD3D11Decoder * self, GstBuffer * decoder_buffer, + GstBuffer * output) { GstVideoFrame out_frame; + GstVideoInfo *info = &self->output_info; guint i; GstD3D11Memory *in_mem; D3D11_MAPPED_SUBRESOURCE map; @@ -1272,9 +1286,10 @@ copy_to_system (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width, } static gboolean -copy_to_d3d11 (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width, - gint display_height, GstBuffer * decoder_buffer, GstBuffer * output) +copy_to_d3d11 (GstD3D11Decoder * self, GstBuffer * decoder_buffer, + GstBuffer * output) { + GstVideoInfo *info = &self->output_info; GstD3D11Memory *in_mem; GstD3D11Memory *out_mem; GstMapInfo out_map; @@ -1302,8 +1317,8 @@ copy_to_d3d11 (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width, src_box.front = 0; src_box.back = 1; - src_box.right = GST_ROUND_UP_2 (GST_VIDEO_INFO_WIDTH (&self->info)); - src_box.bottom = GST_ROUND_UP_2 (GST_VIDEO_INFO_HEIGHT (&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 (info)); out_subresource_index = gst_d3d11_memory_get_subresource_index (out_mem); device_context->CopySubresourceRegion ((ID3D11Resource *) out_map.data, @@ -1318,26 +1333,57 @@ copy_to_d3d11 (GstD3D11Decoder * self, GstVideoInfo * info, gint display_width, gboolean gst_d3d11_decoder_process_output (GstD3D11Decoder * decoder, - GstVideoInfo * info, gint display_width, gint display_height, - GstBuffer * decoder_buffer, GstBuffer * output) + GstVideoDecoder * videodec, gint display_width, gint display_height, + GstBuffer * decoder_buffer, GstBuffer ** output) { gboolean can_device_copy = TRUE; 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 (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; + } + + *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 */ - 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; GstD3D11Memory *dmem; - mem = gst_buffer_peek_memory (output, 0); + mem = gst_buffer_peek_memory (*output, 0); if (!gst_is_d3d11_memory (mem)) { can_device_copy = FALSE; goto do_process; @@ -1352,32 +1398,29 @@ gst_d3d11_decoder_process_output (GstD3D11Decoder * decoder, do_process: if (can_device_copy) { - return copy_to_d3d11 (decoder, info, display_width, display_height, - decoder_buffer, output); + return copy_to_d3d11 (decoder, decoder_buffer, *output); } - return copy_to_system (decoder, info, display_width, display_height, - decoder_buffer, output); + return copy_to_system (decoder, decoder_buffer, *output); } gboolean gst_d3d11_decoder_negotiate (GstD3D11Decoder * decoder, - GstVideoDecoder * videodec, GstVideoCodecState * input_state, - GstVideoCodecState ** output_state) + GstVideoDecoder * videodec) { + GstVideoInfo *info; GstCaps *peer_caps; GstVideoCodecState *state = NULL; gboolean alternate_interlaced; gboolean alternate_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_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 = (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); - if (*output_state) - gst_video_codec_state_unref (*output_state); - *output_state = state; + g_clear_pointer (&decoder->output_state, gst_video_codec_state_unref); + decoder->output_state = state; if (d3d11_supported) { gst_caps_set_features (state->caps, 0, @@ -1632,20 +1674,28 @@ gst_d3d11_decoder_flush (GstD3D11Decoder * decoder, GstVideoDecoder * videodec) return TRUE; } -gboolean +static gboolean 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; GstD3D11PoolAllocator *alloc; guint max_size = 0, outstanding_size = 0; - g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE); - g_return_val_if_fail (GST_IS_BUFFER (view_buffer), FALSE); + /* We don't support direct render for reverse playback */ + if (videodec->input_segment.rate < 0) + return FALSE; if (!decoder->can_direct_rendering || !decoder->downstream_supports_d3d11) 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 * limit */ if (decoder->use_array_of_texture) diff --git a/sys/d3d11/gstd3d11decoder.h b/sys/d3d11/gstd3d11decoder.h index abb4db7c9b..f88a377142 100644 --- a/sys/d3d11/gstd3d11decoder.h +++ b/sys/d3d11/gstd3d11decoder.h @@ -61,6 +61,7 @@ gboolean gst_d3d11_decoder_is_configured (GstD3D11Decoder * decoder); gboolean gst_d3d11_decoder_configure (GstD3D11Decoder * decoder, GstD3D11Codec codec, + GstVideoCodecState * input_state, GstVideoInfo * info, gint coded_width, gint coded_height, @@ -93,16 +94,14 @@ ID3D11VideoDecoderOutputView * gst_d3d11_decoder_get_output_view_from_buffer (Gs guint8 * view_id); gboolean gst_d3d11_decoder_process_output (GstD3D11Decoder * decoder, - GstVideoInfo * info, + GstVideoDecoder * videodec, gint display_width, gint display_height, GstBuffer * decoder_buffer, - GstBuffer * output); + GstBuffer ** output); gboolean gst_d3d11_decoder_negotiate (GstD3D11Decoder * decoder, - GstVideoDecoder * videodec, - GstVideoCodecState * input_state, - GstVideoCodecState ** output_state); + GstVideoDecoder * videodec); gboolean gst_d3d11_decoder_decide_allocation (GstD3D11Decoder * decoder, GstVideoDecoder * videodec, @@ -111,10 +110,6 @@ gboolean gst_d3d11_decoder_decide_allocation (GstD3D11Decoder * decod gboolean gst_d3d11_decoder_flush (GstD3D11Decoder * decoder, GstVideoDecoder * videodec); -gboolean gst_d3d11_decoder_can_direct_render (GstD3D11Decoder * decoder, - GstBuffer * view_buffer, - GstMiniObject * picture); - /* Utils for class registration */ gboolean gst_d3d11_decoder_util_is_legacy_device (GstD3D11Device * device); diff --git a/sys/d3d11/gstd3d11h264dec.cpp b/sys/d3d11/gstd3d11h264dec.cpp index c089718388..f68a5179e6 100644 --- a/sys/d3d11/gstd3d11h264dec.cpp +++ b/sys/d3d11/gstd3d11h264dec.cpp @@ -100,8 +100,6 @@ typedef struct _GstD3D11H264Dec { GstH264Decoder parent; - GstVideoCodecState *output_state; - GstD3D11Device *device; gint width, height; @@ -352,10 +350,6 @@ gst_d3d11_h264_dec_close (GstVideoDecoder * 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->device); @@ -366,12 +360,9 @@ static gboolean gst_d3d11_h264_dec_negotiate (GstVideoDecoder * decoder) { GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder); - GstH264Decoder *h264dec = GST_H264_DECODER (decoder); - if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder, - h264dec->input_state, &self->output_state)) { + if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder)) return FALSE; - } 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; 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 */ max_dpb_size + 4)) { 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); GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder); - GstBuffer *output_buffer = NULL; GstBuffer *view_buffer; - gboolean direct_rendering = FALSE; GST_LOG_OBJECT (self, "Outputting picture %p (poc %d)", picture, picture->pic_order_cnt); @@ -839,37 +828,8 @@ gst_d3d11_h264_dec_output_picture (GstH264Decoder * decoder, goto error; } - /* if downstream is d3d11 element and forward playback case, - * expose our decoder view without copy. In case of reverse playback, however, - * 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)) { + if (!gst_d3d11_decoder_process_output (self->d3d11_decoder, vdec, + self->width, self->height, view_buffer, &frame->output_buffer)) { GST_ERROR_OBJECT (self, "Failed to copy buffer"); goto error; } diff --git a/sys/d3d11/gstd3d11h265dec.cpp b/sys/d3d11/gstd3d11h265dec.cpp index bf2d5ec91e..18fba71a88 100644 --- a/sys/d3d11/gstd3d11h265dec.cpp +++ b/sys/d3d11/gstd3d11h265dec.cpp @@ -70,8 +70,6 @@ typedef struct _GstD3D11H265Dec { GstH265Decoder parent; - GstVideoCodecState *output_state; - GstD3D11Device *device; gint width, height; @@ -307,10 +305,6 @@ gst_d3d11_h265_dec_close (GstVideoDecoder * 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->device); @@ -321,12 +315,9 @@ static gboolean gst_d3d11_h265_dec_negotiate (GstVideoDecoder * decoder) { GstD3D11H265Dec *self = GST_D3D11_H265_DEC (decoder); - GstH265Decoder *h265dec = GST_H265_DECODER (decoder); - if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder, - h265dec->input_state, &self->output_state)) { + if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder)) return FALSE; - } 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; 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 */ max_dpb_size + 4)) { 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); GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder); - GstBuffer *output_buffer = NULL; GstBuffer *view_buffer; - gboolean direct_rendering = FALSE; GST_LOG_OBJECT (self, "Outputting picture %p, poc %d, picture_struct %d, " "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; } - /* if downstream is d3d11 element and forward playback case, - * expose our decoder view without copy. In case of reverse playback, however, - * 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)) { + if (!gst_d3d11_decoder_process_output (self->d3d11_decoder, vdec, + self->width, self->height, view_buffer, &frame->output_buffer)) { GST_ERROR_OBJECT (self, "Failed to copy buffer"); - gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame); goto error; } diff --git a/sys/d3d11/gstd3d11mpeg2dec.cpp b/sys/d3d11/gstd3d11mpeg2dec.cpp index 87d9224a8e..2bb91d0ef4 100644 --- a/sys/d3d11/gstd3d11mpeg2dec.cpp +++ b/sys/d3d11/gstd3d11mpeg2dec.cpp @@ -73,7 +73,6 @@ typedef struct _GstD3D11Mpeg2Dec { GstMpeg2Decoder parent; - GstVideoCodecState *output_state; GstD3D11Device *device; GstD3D11Decoder *d3d11_decoder; @@ -308,12 +307,9 @@ static gboolean gst_d3d11_mpeg2_dec_negotiate (GstVideoDecoder * decoder) { GstD3D11Mpeg2Dec *self = GST_D3D11_MPEG2_DEC (decoder); - GstMpeg2Decoder *mpeg2dec = GST_MPEG2_DECODER (decoder); - if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder, - mpeg2dec->input_state, &self->output_state)) { + if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder)) return FALSE; - } 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; if (!gst_d3d11_decoder_configure (self->d3d11_decoder, - GST_D3D11_CODEC_MPEG2, &info, self->width, self->height, - NUM_OUTPUT_VIEW)) { + GST_D3D11_CODEC_MPEG2, decoder->input_state, &info, + self->width, self->height, NUM_OUTPUT_VIEW)) { GST_ERROR_OBJECT (self, "Failed to create decoder"); return FALSE; } @@ -886,9 +882,7 @@ gst_d3d11_mpeg2_dec_output_picture (GstMpeg2Decoder * decoder, { GstD3D11Mpeg2Dec *self = GST_D3D11_MPEG2_DEC (decoder); GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder); - GstBuffer *output_buffer = NULL; GstBuffer *view_buffer; - gboolean direct_rendering = FALSE; GST_LOG_OBJECT (self, "Outputting picture %p", picture); @@ -899,38 +893,8 @@ gst_d3d11_mpeg2_dec_output_picture (GstMpeg2Decoder * decoder, goto error; } - /* if downstream is d3d11 element and forward playback case, - * expose our decoder view without copy. In case of reverse playback, however, - * 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)) { + if (!gst_d3d11_decoder_process_output (self->d3d11_decoder, vdec, + self->width, self->height, view_buffer, &frame->output_buffer)) { GST_ERROR_OBJECT (self, "Failed to copy buffer"); goto error; } diff --git a/sys/d3d11/gstd3d11vp8dec.cpp b/sys/d3d11/gstd3d11vp8dec.cpp index 126d1eaf8c..04356f2d68 100644 --- a/sys/d3d11/gstd3d11vp8dec.cpp +++ b/sys/d3d11/gstd3d11vp8dec.cpp @@ -73,7 +73,6 @@ typedef struct _GstD3D11Vp8Dec { GstVp8Decoder parent; - GstVideoCodecState *output_state; GstD3D11Device *device; GstD3D11Decoder *d3d11_decoder; @@ -272,12 +271,9 @@ static gboolean gst_d3d11_vp8_dec_negotiate (GstVideoDecoder * decoder) { GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder); - GstVp8Decoder *vp8dec = GST_VP8_DECODER (decoder); - if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, - decoder, vp8dec->input_state, &self->output_state)) { + if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder)) return FALSE; - } 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); 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"); return FALSE; } @@ -388,9 +385,7 @@ gst_d3d11_vp8_dec_output_picture (GstVp8Decoder * decoder, { GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder); GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder); - GstBuffer *output_buffer = NULL; GstBuffer *view_buffer; - gboolean direct_rendering = FALSE; g_assert (picture->frame_hdr.show_frame); @@ -403,37 +398,8 @@ gst_d3d11_vp8_dec_output_picture (GstVp8Decoder * decoder, goto error; } - /* if downstream is d3d11 element and forward playback case, - * expose our decoder view without copy. In case of reverse playback, however, - * 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)) { + if (!gst_d3d11_decoder_process_output (self->d3d11_decoder, vdec, + self->width, self->height, view_buffer, &frame->output_buffer)) { GST_ERROR_OBJECT (self, "Failed to copy buffer"); goto error; } diff --git a/sys/d3d11/gstd3d11vp9dec.cpp b/sys/d3d11/gstd3d11vp9dec.cpp index 60c4b1ac13..4a5645890e 100644 --- a/sys/d3d11/gstd3d11vp9dec.cpp +++ b/sys/d3d11/gstd3d11vp9dec.cpp @@ -103,16 +103,8 @@ typedef struct _GstD3D11Vp9Dec { GstVp9Decoder parent; - GstVideoCodecState *output_state; - GstD3D11Device *device; - GstD3D11Decoder *d3d11_decoder; - - guint width, height; - GstVP9Profile profile; - - GstVideoFormat out_format; } GstD3D11Vp9Dec; typedef struct _GstD3D11Vp9DecClass @@ -310,12 +302,9 @@ static gboolean gst_d3d11_vp9_dec_negotiate (GstVideoDecoder * decoder) { GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder); - GstVp9Decoder *vp9dec = GST_VP9_DECODER (decoder); - if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, - decoder, vp9dec->input_state, &self->output_state)) { + if (!gst_d3d11_decoder_negotiate (self->d3d11_decoder, decoder)) return FALSE; - } 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) { 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"); - if (self->width < frame_hdr->width || self->height < frame_hdr->height) { - self->width = frame_hdr->width; - self->height = frame_hdr->height; - GST_INFO_OBJECT (self, "resolution changed %dx%d", - self->width, self->height); - modified = TRUE; + if (frame_hdr->profile == GST_VP9_PROFILE_0) + out_format = GST_VIDEO_FORMAT_NV12; + else if (frame_hdr->profile == GST_VP9_PROFILE_2) + out_format = GST_VIDEO_FORMAT_P010_10LE; + + 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) { - self->profile = (GstVP9Profile) frame_hdr->profile; - GST_INFO_OBJECT (self, "profile changed %d", self->profile); - modified = TRUE; + gst_video_info_set_format (&info, + out_format, frame_hdr->width, frame_hdr->height); + + 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)) { - GstVideoInfo info; - - 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; - } + if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) { + GST_ERROR_OBJECT (self, "Failed to negotiate with downstream"); + return FALSE; } return TRUE; @@ -479,9 +449,7 @@ gst_d3d11_vp9_dec_output_picture (GstVp9Decoder * decoder, { GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder); GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder); - GstBuffer *output_buffer = NULL; GstBuffer *view_buffer; - gboolean direct_rendering = FALSE; GST_LOG_OBJECT (self, "Outputting picture %p", picture); @@ -492,37 +460,9 @@ gst_d3d11_vp9_dec_output_picture (GstVp9Decoder * decoder, goto error; } - /* if downstream is d3d11 element and forward playback case, - * expose our decoder view without copy. In case of reverse playback, however, - * 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)) { + if (!gst_d3d11_decoder_process_output (self->d3d11_decoder, vdec, + picture->frame_hdr.width, picture->frame_hdr.height, view_buffer, + &frame->output_buffer)) { GST_ERROR_OBJECT (self, "Failed to copy buffer"); goto error; }