Skip to content

Commit

Permalink
minivideo: work on H.26x parameter sets
Browse files Browse the repository at this point in the history
  • Loading branch information
emericg committed Jun 26, 2024
1 parent a6b27fa commit c0b5527
Show file tree
Hide file tree
Showing 9 changed files with 203 additions and 73 deletions.
6 changes: 3 additions & 3 deletions minivideo/src/decoder/h264/h264.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ int h264_decode_nalu(DecodingContext_t *dc, const int64_t nalu_offset, const int
dc->errorCounter++;
}
break;

/*
case NALU_TYPE_SEI: ////////////////////////////////////////
{
h264_nalu_clean_sample(dc->bitstr);
Expand All @@ -380,7 +380,7 @@ int h264_decode_nalu(DecodingContext_t *dc, const int64_t nalu_offset, const int
dc->active_sei = (h264_sei_t*)calloc(1, sizeof(h264_sei_t));
if (dc->active_sei)
{
if (decodeSEI(dc->bitstr, dc->active_sei))
if (decodeSEI(dc->bitstr, dc->active_sei, 0))
{
retcode = SUCCESS;
printSEI(NULL);
Expand All @@ -390,7 +390,7 @@ int h264_decode_nalu(DecodingContext_t *dc, const int64_t nalu_offset, const int
}
}
break;

*/
case NALU_TYPE_SPS: ////////////////////////////////////////
{
h264_nalu_clean_sample(dc->bitstr);
Expand Down
122 changes: 76 additions & 46 deletions minivideo/src/decoder/h264/h264_parameterset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,7 @@ int decodePPS(Bitstream_t *bitstr, h264_pps_t *pps, h264_sps_t **sps_array)
pps->redundant_pic_cnt_present_flag = read_bit(bitstr);

if (h264_more_rbsp_data(bitstr) == true &&
sps_array &&
sps_array[pps->seq_parameter_set_id] &&
sps_array[pps->seq_parameter_set_id]->profile_idc >= HIGHP)
{
Expand Down Expand Up @@ -1012,7 +1013,10 @@ int decodePPS(Bitstream_t *bitstr, h264_pps_t *pps, h264_sps_t **sps_array)
retcode = h264_rbsp_trailing_bits(bitstr);

#if ENABLE_DEBUG
checkPPS(pps, sps_array[pps->seq_parameter_set_id]);
if (sps_array && sps_array[pps->seq_parameter_set_id])
checkPPS(pps, sps_array[pps->seq_parameter_set_id]);
else
checkPPS(pps, nullptr);
#endif
}

Expand Down Expand Up @@ -1206,10 +1210,10 @@ void printPPS(h264_pps_t *pps, h264_sps_t **sps_array)
TRACE_1(PARAM, " - pic_scaling_matrix_present_flag = %i", pps->pic_scaling_matrix_present_flag);
if (pps->pic_scaling_matrix_present_flag)
{
for (i = 0; i < ((sps_array[pps->seq_parameter_set_id]->ChromaArrayType != 3) ? 8 : 12); i++)
{
TRACE_1(PARAM, " - pic_scaling_list_present_flag[%i]= %i", i, pps->pic_scaling_list_present_flag[i]);
}
for (i = 0; i < ((sps_array[pps->seq_parameter_set_id]->ChromaArrayType != 3) ? 8 : 12); i++)
{
TRACE_1(PARAM, " - pic_scaling_list_present_flag[%i]= %i", i, pps->pic_scaling_list_present_flag[i]);
}
}
TRACE_1(PARAM, " - second_chroma_qp_index_offset = %i", pps->second_chroma_qp_index_offset);
#endif // ENABLE_DEBUG
Expand All @@ -1219,7 +1223,7 @@ void printPPS(h264_pps_t *pps, h264_sps_t **sps_array)

void mapPPS(h264_pps_t *pps, h264_sps_t **sps, int64_t offset, int64_t size, FILE *xml)
{
if (pps && sps && xml)
if (pps && xml)
{
fprintf(xml, " <a tt=\"PPS\" add=\"private\" tp=\"data\" off=\"%" PRId64 "\" sz=\"%" PRId64 "\">\n",
offset, size);
Expand Down Expand Up @@ -1283,7 +1287,7 @@ void mapPPS(h264_pps_t *pps, h264_sps_t **sps, int64_t offset, int64_t size, FIL

fprintf(xml, " <transform_8x8_mode_flag>%u</transform_8x8_mode_flag>\n", pps->transform_8x8_mode_flag);
fprintf(xml, " <pic_scaling_matrix_present_flag>%u</pic_scaling_matrix_present_flag>\n", pps->pic_scaling_matrix_present_flag);
if (pps->pic_scaling_matrix_present_flag)
if (pps->pic_scaling_matrix_present_flag && sps)
{
for (unsigned i = 0; i < ((sps[pps->seq_parameter_set_id]->ChromaArrayType != 3) ? 8 : 12); i++)
{
Expand Down Expand Up @@ -1329,6 +1333,8 @@ int decodeAUD(Bitstream_t *bitstr, h264_aud_t *aud)
return retcode;
}

/* ************************************************************************** */

void mapAUD(h264_aud_t *aud, int64_t offset, int64_t size, FILE *xml)
{
if (!aud || !xml) return;
Expand All @@ -1343,6 +1349,8 @@ void mapAUD(h264_aud_t *aud, int64_t offset, int64_t size, FILE *xml)
fprintf(xml, " </a>\n");
}

/* ************************************************************************** */

void freeAUD(h264_aud_t **aud_ptr)
{
if (*aud_ptr != NULL)
Expand All @@ -1358,8 +1366,9 @@ void freeAUD(h264_aud_t **aud_ptr)
/* ************************************************************************** */

/*!
* \param *bitstr:
* \param *sei:
* \param *bitstr: our bitstream reader.
* \param *sei: SEI structure.
* \param size: size of the SEI, if known.
* \return 1 if SEI seems consistent, 0 otherwise.
*
* From 'ITU-T H.264' recommendation:
Expand All @@ -1368,7 +1377,7 @@ void freeAUD(h264_aud_t **aud_ptr)
* D.1 SEI payload syntax.
* D.1 SEI payload semantics.
*/
int decodeSEI(Bitstream_t *bitstr, h264_sei_t *sei)
int decodeSEI(Bitstream_t *bitstr, h264_sei_t *sei, int64_t size)
{
TRACE_INFO(PARAM, "<> " BLD_GREEN "decodeSEI()" CLR_RESET);
int retcode = SUCCESS;
Expand All @@ -1383,7 +1392,11 @@ int decodeSEI(Bitstream_t *bitstr, h264_sei_t *sei)
// SEI decoding
////////////////////////////////////////////////////////////////////////

while (h264_more_rbsp_data(bitstr) == true)
int64_t startpos = bitstream_get_absolute_byte_offset(bitstr);
int64_t currentpos = startpos;

//while (h264_more_rbsp_data(bitstr) == true)
while (currentpos < (startpos + size))
{
// SEI payload header
unsigned int payloadType = 0;
Expand All @@ -1408,45 +1421,43 @@ int decodeSEI(Bitstream_t *bitstr, h264_sei_t *sei)
payloadSize += last_payload_size_byte;

// SEI payload
//sei_payload( payloadType, payloadSize )
}
if (payloadType == 4)
{
// user_data_registered_itu_t_t35

// SEI check
////////////////////////////////////////////////////////////////////////
sei->itu_t_t35_country_code = read_bits(bitstr, 8);
sei->itu_t_t35_country_code_extension_byte = read_bits(bitstr, 8);

if (retcode == SUCCESS)
{
retcode = checkSEI(sei);
}
}

return retcode;
}
if (payloadSize > 2)
{
sei->itu_t_t35_payload = (char *)malloc(payloadSize-2+1);
}
}
else if (payloadType == 5)
{
// user_data_unregistered

/* ************************************************************************** */
for (int i = 0; i < 16; i++)
{
sei->uuid_iso_iec_11578[i] = read_bits(bitstr, 8);
}

/*!
* \param *dc The current DecodingContext.
* \param *sei (supplemental_enhancement_information) data structure.
* \return 1 if SEI seems consistent, 0 otherwise.
*
* Check parsed values (and not derived ones) for inconsistencies.
*/
static int checkSEI(h264_sei_t *sei)
{
TRACE_INFO(PARAM, "> " BLD_GREEN "checkSEI()" CLR_RESET);
int retcode = SUCCESS;
if (payloadSize > 16)
{
sei->user_data_payload = (char *)malloc(payloadSize-16+1);
for (unsigned i = 0; i < payloadSize-16; i++)
sei->user_data_payload[i] = read_bits(bitstr, 8);
sei->user_data_payload[payloadSize-16+1] = '\0';
}
}
else
{
TRACE_WARNING(PARAM, " Unknown SEI payload type! (type: %i / size: %i)", payloadType, payloadSize);
skip_bits(bitstr, payloadSize*8);
}

// Check SEI structure
if (sei == NULL)
{
TRACE_ERROR(PARAM, " Invalid SEI structure!");
retcode = FAILURE;
}
else // Check SEI values
{
TRACE_WARNING(PARAM, ">>> UNIMPLEMENTED (checkSEI)");
retcode = FAILURE;
currentpos = bitstream_get_absolute_byte_offset(bitstr);
}
}

return retcode;
Expand All @@ -1461,6 +1472,12 @@ void freeSEI(h264_sei_t **sei_ptr)
{
if (*sei_ptr != NULL)
{
if ((*sei_ptr)->itu_t_t35_payload)
free((*sei_ptr)->itu_t_t35_payload);

if ((*sei_ptr)->user_data_payload)
free((*sei_ptr)->user_data_payload);

free(*sei_ptr);
*sei_ptr = NULL;

Expand Down Expand Up @@ -1503,7 +1520,20 @@ void mapSEI(h264_sei_t *sei, int64_t offset, int64_t size, FILE *xml)

xmlSpacer(xml, "Supplemental Enhancement Information", -1);

fprintf(xml, " </a>\n");
if (sei->itu_t_t35_payload)
{
fprintf(xml, " <itu_t_t35_country_code>%i</itu_t_t35_country_code>\n", sei->itu_t_t35_country_code);
fprintf(xml, " <itu_t_t35_country_code_extension_byte>%i</itu_t_t35_country_code_extension_byte>\n", sei->itu_t_t35_country_code_extension_byte);
fprintf(xml, " <itu_t_t35_payload>%s</itu_t_t35_payload>\n", sei->itu_t_t35_payload);
}

if (sei->user_data_payload)
{
fprintf(xml, " <uuid_iso_iec_11578>%s</uuid_iso_iec_11578>\n", sei->uuid_iso_iec_11578);
fprintf(xml, " <user_data_payload>%s</user_data_payload>\n", sei->user_data_payload);
}

fprintf(xml, " </a>\n");
}

/* ************************************************************************** */
Expand Down
2 changes: 1 addition & 1 deletion minivideo/src/decoder/h264/h264_parameterset.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void printPPS(h264_pps_t *pps, h264_sps_t **sps_array);
void mapPPS(h264_pps_t *pps, h264_sps_t **sps, int64_t offset, int64_t size, FILE *xml);
void freePPS(h264_pps_t **pps_ptr);

int decodeSEI(Bitstream_t *bitstr, h264_sei_t *sei);
int decodeSEI(Bitstream_t *bitstr, h264_sei_t *sei, int64_t size);
void printSEI(h264_sei_t *sei);
void mapSEI(h264_sei_t *sei, int64_t offset, int64_t size, FILE *xml);
void freeSEI(h264_sei_t **sei_ptr);
Expand Down
94 changes: 94 additions & 0 deletions minivideo/src/decoder/h265/h265_parameterset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ void profile_tier_level(Bitstream_t *bitstr, h265_ptl_t *ptl,
}
}

/* ************************************************************************** */

void map_ptl(h265_ptl_t *ptl, int64_t offset, int64_t size, FILE *xml)
{
if (!ptl || !xml) return;
Expand Down Expand Up @@ -273,6 +275,8 @@ void map_ptl(h265_ptl_t *ptl, int64_t offset, int64_t size, FILE *xml)
fprintf(xml, " </a>\n");
}

/* ************************************************************************** */

void hrd_parameters(Bitstream_t *bitstr, h265_hrd_t *hrd,
bool profilePresentFlag, uint8_t maxNumSubLayersMinus1)
{
Expand Down Expand Up @@ -508,6 +512,19 @@ void h265_mapVPS(h265_vps_t *vps, int64_t offset, int64_t size, FILE *xml)
fprintf(xml, " </a>\n");
}

/* ************************************************************************** */

void h265_freeVPS(h265_vps_t **vps_ptr)
{
if (*vps_ptr != NULL)
{
free(*vps_ptr);
*vps_ptr = NULL;

TRACE_1(PARAM, ">> VPS freed");
}
}

/* ************************************************************************** */
/* ************************************************************************** */

Expand Down Expand Up @@ -779,6 +796,19 @@ void h265_mapSPS(h265_sps_t *sps, int64_t offset, int64_t size, FILE *xml)
fprintf(xml, " </a>\n");
}

/* ************************************************************************** */

void h265_freeSPS(h265_sps_t **sps_ptr)
{
if (*sps_ptr != NULL)
{
free(*sps_ptr);
*sps_ptr = NULL;

TRACE_1(PARAM, ">> SPS freed");
}
}

/* ************************************************************************** */
/* ************************************************************************** */

Expand Down Expand Up @@ -1018,5 +1048,69 @@ void h265_mapPPS(h265_pps_t *pps, int64_t offset, int64_t size, FILE *xml)
fprintf(xml, " </a>\n");
}

/* ************************************************************************** */

void h265_freePPS(h265_pps_t **pps_ptr)
{
if (*pps_ptr != NULL)
{
free(*pps_ptr);
*pps_ptr = NULL;

TRACE_1(PARAM, ">> PPS freed");
}
}

/* ************************************************************************** */
/* ************************************************************************** */

int h265_decodeAUD(Bitstream_t *bitstr, h265_aud_t *aud)
{
TRACE_INFO(PARAM, "<> " BLD_GREEN "decodeAUD()" CLR_RESET);
int retcode = SUCCESS;

if (aud == NULL)
{
TRACE_ERROR(PARAM, "NULL AUD!");
retcode = FAILURE;
}
else
{
aud->pic_type = read_bits(bitstr, 3);
TRACE_2(PARAM, "<> " BLD_GREEN "pic_type: %i" CLR_RESET, aud->pic_type);
}

return retcode;
}

/* ************************************************************************** */

void h265_mapAUD(h265_aud_t *aud, int64_t offset, int64_t size, FILE *xml)
{
if (!aud || !xml) return;

fprintf(xml, " <a tt=\"AUD\" add=\"private\" tp=\"data\" off=\"%" PRId64 "\" sz=\"%" PRId64 "\">\n",
offset, size);

xmlSpacer(xml, "Access Unit Delimiter", -1);

fprintf(xml, " <pic_type>%i</pic_type>\n", aud->pic_type);

fprintf(xml, " </a>\n");
}

/* ************************************************************************** */

void h265_freeAUD(h265_aud_t **aud_ptr)
{
if (*aud_ptr != NULL)
{
free(*aud_ptr);
*aud_ptr = NULL;

TRACE_1(PARAM, ">> AUD freed");
}
}

/* ************************************************************************** */
/* ************************************************************************** */
Loading

0 comments on commit c0b5527

Please sign in to comment.