msdk: dec: Add non-packetized stream handling support

The gst-msdk decoders prefer packetized streams as input
and in this case we can avoid unnecessary input bitstream copy
to mfxBitstream. This works fine for codecs like h264 where
we only support byte-stream with au alignment. Other format
conversions should be done thorugh parsers. But this won't work
for codecs like vc1 where we don't have an autoplugged parser.
Even the parser is not capable to do format conversions.

Packetizing through base decoders parse() routine will bring a
lot of uncecessary of complexities and codecparser libraray dependency.
So we just use an interal gst_adaper to keep track of bitstream
which is not consumed by msdk durig AsynchronusDecoding.
This adapter will get used only if subclass implementations
set the "is_packetized" to FALSE for msdk base encoder.

https://bugzilla.gnome.org/show_bug.cgi?id=792589
This commit is contained in:
Sreerenj Balachandran 2018-02-13 14:41:20 -09:00
parent 760e6e54a7
commit 55c0d7205d
2 changed files with 34 additions and 3 deletions

View file

@ -224,6 +224,7 @@ gst_msdkdec_close_decoder (GstMsdkDec * thiz)
memset (&thiz->param, 0, sizeof (thiz->param));
thiz->initialized = FALSE;
gst_adapter_clear (thiz->adapter);
}
static void
@ -625,6 +626,7 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
mfxStatus status;
GstMapInfo map_info;
guint i;
gsize data_size;
if (!thiz->initialized)
gst_video_decoder_negotiate (decoder);
@ -633,9 +635,25 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
return GST_FLOW_ERROR;
memset (&bitstream, 0, sizeof (bitstream));
bitstream.Data = map_info.data;
bitstream.DataLength = map_info.size;
bitstream.MaxLength = map_info.size;
if (thiz->is_packetized) {
/* Packetized stream: We prefer to have a parser as connected upstream
* element to the decoder */
bitstream.Data = map_info.data;
bitstream.DataLength = map_info.size;
bitstream.MaxLength = map_info.size;
} else {
/* Non packetized streams: eg: vc1 advanced profile with per buffer bdu */
gst_adapter_push (thiz->adapter, gst_buffer_ref (frame->input_buffer));
data_size = gst_adapter_available (thiz->adapter);
bitstream.Data = (mfxU8 *) gst_adapter_map (thiz->adapter, data_size);
bitstream.DataLength = (mfxU32) data_size;
bitstream.MaxLength = bitstream.DataLength;
}
GST_INFO_OBJECT (thiz,
"mfxBitStream=> DataLength:%d DataOffset:%d MaxLength:%d",
bitstream.DataLength, bitstream.DataOffset, bitstream.MaxLength);
session = gst_msdk_context_get_session (thiz->context);
for (;;) {
@ -708,6 +726,12 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
}
}
if (!thiz->is_packetized) {
/* flush out the data which is already consumed by msdk */
gst_adapter_flush (thiz->adapter, bitstream.DataOffset);
flow = GST_FLOW_OK;
}
exit:
if (surface)
free_surface (thiz, surface);
@ -1064,6 +1088,7 @@ gst_msdkdec_finalize (GObject * object)
g_array_unref (thiz->tasks);
g_ptr_array_unref (thiz->extra_params);
g_object_unref (thiz->adapter);
}
static void
@ -1116,4 +1141,6 @@ gst_msdkdec_init (GstMsdkDec * thiz)
thiz->tasks = g_array_new (FALSE, TRUE, sizeof (MsdkDecTask));
thiz->hardware = PROP_HARDWARE_DEFAULT;
thiz->async_depth = PROP_ASYNC_DEPTH_DEFAULT;
thiz->is_packetized = TRUE;
thiz->adapter = gst_adapter_new ();
}

View file

@ -69,6 +69,10 @@ struct _GstMsdkDec
gboolean use_video_memory;
gboolean initialized;
/* for packetization */
GstAdapter *adapter;
gboolean is_packetized;
/* MFX context */
GstMsdkContext *context;
mfxVideoParam param;