mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +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;
|
||||
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue