GstH264NalParser *parser;
guint parser_state;
guint decoder_state;
+ GstVaapiStreamAlignH264 stream_alignment;
GstVaapiPictureH264 *current_picture;
GstVaapiParserInfoH264 *sps[GST_H264_MAX_SPS_COUNT];
GstVaapiParserInfoH264 *active_sps;
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
return status;
- size = gst_adapter_available(adapter);
+ switch (priv->stream_alignment) {
+ case GST_VAAPI_STREAM_ALIGN_H264_NALU:
+ size = gst_adapter_available_fast(adapter);
+ break;
+ default:
+ size = gst_adapter_available(adapter);
+ break;
+ }
if (priv->is_avcC) {
if (size < priv->nal_length_size)
if (size < 4)
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
- ofs = scan_for_start_code(adapter, 0, size, NULL);
- if (ofs < 0)
- return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
-
- if (ofs > 0) {
- gst_adapter_flush(adapter, ofs);
- size -= ofs;
- }
+ if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H264_NALU)
+ buf_size = size;
+ else {
+ ofs = scan_for_start_code(adapter, 0, size, NULL);
+ if (ofs < 0)
+ return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
- ofs2 = ps->input_offset2 - ofs - 4;
- if (ofs2 < 4)
- ofs2 = 4;
+ if (ofs > 0) {
+ gst_adapter_flush(adapter, ofs);
+ size -= ofs;
+ }
- ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 :
- scan_for_start_code(adapter, ofs2, size - ofs2, NULL);
- if (ofs < 0) {
- // Assume the whole NAL unit is present if end-of-stream
- if (!at_eos) {
- ps->input_offset2 = size;
- return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
+ ofs2 = ps->input_offset2 - ofs - 4;
+ if (ofs2 < 4)
+ ofs2 = 4;
+
+ ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 :
+ scan_for_start_code(adapter, ofs2, size - ofs2, NULL);
+ if (ofs < 0) {
+ // Assume the whole NAL unit is present if end-of-stream
+ if (!at_eos) {
+ ps->input_offset2 = size;
+ return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
+ }
+ ofs = size;
}
- ofs = size;
+ buf_size = ofs;
}
- buf_size = ofs;
}
ps->input_offset2 = 0;
}
/**
+ * gst_vaapi_decoder_h264_set_alignment:
+ * @decoder: a #GstVaapiDecoderH264
+ * @alignment: the #GstVaapiStreamAlignH264
+ *
+ * Specifies how stream buffers are aligned / fed, i.e. the boundaries
+ * of each buffer that is supplied to the decoder. This could be no
+ * specific alignment, NAL unit boundaries, or access unit boundaries.
+ */
+void
+gst_vaapi_decoder_h264_set_alignment(GstVaapiDecoderH264 *decoder,
+ GstVaapiStreamAlignH264 alignment)
+{
+ g_return_if_fail(decoder != NULL);
+
+ decoder->priv.stream_alignment = alignment;
+}
+
+/**
* gst_vaapi_decoder_h264_new:
* @display: a #GstVaapiDisplay
* @caps: a #GstCaps holding codec information
G_BEGIN_DECLS
+#define GST_VAAPI_DECODER_H264(decoder) \
+ ((GstVaapiDecoderH264 *)(decoder))
+
typedef struct _GstVaapiDecoderH264 GstVaapiDecoderH264;
+/**
+ * GstVaapiStreamAlignH264:
+ * @GST_VAAPI_STREAM_ALIGN_H264_NONE: Generic H.264 stream buffers
+ * @GST_VAAPI_STREAM_ALIGN_H264_NALU: H.264 stream buffers aligned NAL
+ * unit boundaries
+ * @GST_VAAPI_STREAM_ALIGN_H264_AU: H.264 stream buffers aligned on
+ * access unit boundaries
+ *
+ * Set of possible buffer alignments for H.264 streams.
+ */
+typedef enum {
+ GST_VAAPI_STREAM_ALIGN_H264_NONE,
+ GST_VAAPI_STREAM_ALIGN_H264_NALU,
+ GST_VAAPI_STREAM_ALIGN_H264_AU
+} GstVaapiStreamAlignH264;
+
GstVaapiDecoder *
gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps);
+void
+gst_vaapi_decoder_h264_set_alignment(GstVaapiDecoderH264 *decoder,
+ GstVaapiStreamAlignH264 alignment);
+
G_END_DECLS
#endif /* GST_VAAPI_DECODER_H264_H */
break;
case GST_VAAPI_CODEC_H264:
decode->decoder = gst_vaapi_decoder_h264_new(dpy, caps);
+
+ /* Set the stream buffer alignment for better optimizations */
+ if (decode->decoder && caps) {
+ GstStructure * const structure = gst_caps_get_structure(caps, 0);
+ const gchar *str = NULL;
+
+ if ((str = gst_structure_get_string(structure, "alignment"))) {
+ GstVaapiStreamAlignH264 alignment;
+ if (g_strcmp0(str, "au") == 0)
+ alignment = GST_VAAPI_STREAM_ALIGN_H264_AU;
+ else if (g_strcmp0(str, "nal") == 0)
+ alignment = GST_VAAPI_STREAM_ALIGN_H264_NALU;
+ else
+ alignment = GST_VAAPI_STREAM_ALIGN_H264_NONE;
+ gst_vaapi_decoder_h264_set_alignment(
+ GST_VAAPI_DECODER_H264(decode->decoder), alignment);
+ }
+ }
break;
case GST_VAAPI_CODEC_WMV3:
case GST_VAAPI_CODEC_VC1: