mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
qsvh264dec: Use newly added avcC data parsing API
Use gst_h264_parser_parse_decoder_config_record() method to parse codec_data. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2449>
This commit is contained in:
parent
a1b4c62b35
commit
8e5a4246b9
1 changed files with 31 additions and 67 deletions
|
@ -192,98 +192,62 @@ gst_qsv_h264_dec_parse_codec_data (GstQsvH264Dec * self, const guint8 * data,
|
||||||
gsize size)
|
gsize size)
|
||||||
{
|
{
|
||||||
GstH264NalParser *parser = self->parser;
|
GstH264NalParser *parser = self->parser;
|
||||||
guint num_sps, num_pps;
|
GstH264DecoderConfigRecord *config = nullptr;
|
||||||
guint off;
|
GstH264NalUnit *nalu;
|
||||||
|
GstH264ParserResult pres = GST_H264_PARSER_OK;
|
||||||
|
gboolean ret = TRUE;
|
||||||
guint i;
|
guint i;
|
||||||
GstH264ParserResult pres;
|
|
||||||
GstH264NalUnit nalu;
|
|
||||||
#ifndef GST_DISABLE_GST_DEBUG
|
|
||||||
guint profile;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* parse the avcC data */
|
if (gst_h264_parser_parse_decoder_config_record (parser, data, size,
|
||||||
if (size < 7) { /* when numSPS==0 and numPPS==0, length is 7 bytes */
|
&config) != GST_H264_PARSER_OK) {
|
||||||
|
GST_WARNING_OBJECT (self, "Failed to parse codec-data");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse the version, this must be 1 */
|
self->nal_length_size = config->length_size_minus_one + 1;
|
||||||
if (data[0] != 1) {
|
for (i = 0; i < config->sps->len; i++) {
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
#ifndef GST_DISABLE_GST_DEBUG
|
|
||||||
/* AVCProfileIndication */
|
|
||||||
/* profile_compat */
|
|
||||||
/* AVCLevelIndication */
|
|
||||||
profile = (data[1] << 16) | (data[2] << 8) | data[3];
|
|
||||||
GST_DEBUG_OBJECT (self, "profile %06x", profile);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 6 bits reserved | 2 bits lengthSizeMinusOne */
|
|
||||||
/* this is the number of bytes in front of the NAL units to mark their
|
|
||||||
* length */
|
|
||||||
self->nal_length_size = (data[4] & 0x03) + 1;
|
|
||||||
GST_DEBUG_OBJECT (self, "nal length size %u", self->nal_length_size);
|
|
||||||
|
|
||||||
num_sps = data[5] & 0x1f;
|
|
||||||
off = 6;
|
|
||||||
for (i = 0; i < num_sps; i++) {
|
|
||||||
GstH264SPS sps;
|
GstH264SPS sps;
|
||||||
|
nalu = &g_array_index (config->sps, GstH264NalUnit, i);
|
||||||
|
|
||||||
pres = gst_h264_parser_identify_nalu_avc (parser,
|
if (nalu->type == GST_H264_NAL_SPS)
|
||||||
data, off, size, 2, &nalu);
|
pres = gst_h264_parser_parse_sps (parser, nalu, &sps);
|
||||||
if (pres != GST_H264_PARSER_OK) {
|
else if (nalu->type == GST_H264_NAL_SUBSET_SPS)
|
||||||
GST_WARNING_OBJECT (self, "Failed to identify SPS nalu");
|
pres = gst_h264_parser_parse_subset_sps (parser, nalu, &sps);
|
||||||
return FALSE;
|
else
|
||||||
}
|
continue;
|
||||||
|
|
||||||
if (nalu.type == GST_H264_NAL_SPS) {
|
|
||||||
pres = gst_h264_parser_parse_sps (parser, &nalu, &sps);
|
|
||||||
} else {
|
|
||||||
pres = gst_h264_parser_parse_subset_sps (parser, &nalu, &sps);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pres != GST_H264_PARSER_OK) {
|
if (pres != GST_H264_PARSER_OK) {
|
||||||
GST_WARNING_OBJECT (self, "Failed to parse SPS");
|
GST_WARNING_OBJECT (self, "Failed to parse SPS");
|
||||||
return FALSE;
|
ret = FALSE;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_qsv_h264_dec_store_nal (self,
|
gst_qsv_h264_dec_store_nal (self,
|
||||||
sps.id, (GstH264NalUnitType) nalu.type, &nalu);
|
sps.id, (GstH264NalUnitType) nalu->type, nalu);
|
||||||
gst_h264_sps_clear (&sps);
|
gst_h264_sps_clear (&sps);
|
||||||
|
|
||||||
off = nalu.offset + nalu.size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (off >= size) {
|
for (i = 0; i < config->pps->len; i++) {
|
||||||
GST_WARNING_OBJECT (self, "Too small avcC");
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
num_pps = data[off];
|
|
||||||
off++;
|
|
||||||
|
|
||||||
for (i = 0; i < num_pps; i++) {
|
|
||||||
GstH264PPS pps;
|
GstH264PPS pps;
|
||||||
|
|
||||||
pres = gst_h264_parser_identify_nalu_avc (parser,
|
nalu = &g_array_index (config->pps, GstH264NalUnit, i);
|
||||||
data, off, size, 2, &nalu);
|
if (nalu->type != GST_H264_NAL_PPS)
|
||||||
if (pres != GST_H264_PARSER_OK) {
|
continue;
|
||||||
GST_WARNING_OBJECT (self, "Failed to identify PPS nalu");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pres = gst_h264_parser_parse_pps (parser, &nalu, &pps);
|
pres = gst_h264_parser_parse_pps (parser, nalu, &pps);
|
||||||
if (pres != GST_H264_PARSER_OK) {
|
if (pres != GST_H264_PARSER_OK) {
|
||||||
GST_WARNING_OBJECT (self, "Failed to parse PPS nalu");
|
GST_WARNING_OBJECT (self, "Failed to parse PPS nalu");
|
||||||
return FALSE;
|
ret = FALSE;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_qsv_h264_dec_store_nal (self,
|
gst_qsv_h264_dec_store_nal (self, pps.id, GST_H264_NAL_PPS, nalu);
|
||||||
pps.id, (GstH264NalUnitType) nalu.type, &nalu);
|
|
||||||
gst_h264_pps_clear (&pps);
|
gst_h264_pps_clear (&pps);
|
||||||
off = nalu.offset + nalu.size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
out:
|
||||||
|
gst_h264_decoder_config_record_free (config);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
Loading…
Reference in a new issue