99 lines
2.7 KiB
C
99 lines
2.7 KiB
C
|
#include "mpeg-types.h"
|
||
|
#include "mpeg-util.h"
|
||
|
#include "mpeg-proto.h"
|
||
|
#include <assert.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#define H266_NAL_IDR_W_RADL 7
|
||
|
#define H266_NAL_RSV_IRAP 11
|
||
|
#define H266_NAL_OPI 12
|
||
|
#define H266_NAL_DCI 13
|
||
|
#define H266_NAL_VPS 14
|
||
|
#define H266_NAL_SPS 15
|
||
|
#define H266_NAL_PPS 16
|
||
|
#define H266_PREFIX_APS_NUT 17
|
||
|
#define H266_SUFFIX_APS_NUT 18
|
||
|
#define H266_PH_NUT 19
|
||
|
#define H266_NAL_AUD 20
|
||
|
#define H266_NAL_PREFIX_SEI 23
|
||
|
#define H266_NAL_SUFFIX_SEI 24
|
||
|
|
||
|
/// @return 0-not find, 1-find ok
|
||
|
int mpeg_h266_start_with_access_unit_delimiter(const uint8_t* p, size_t bytes)
|
||
|
{
|
||
|
int i;
|
||
|
uint8_t nalu;
|
||
|
i = mpeg_h264_find_nalu(p, bytes, NULL);
|
||
|
if (-1 == i)
|
||
|
return 0;
|
||
|
|
||
|
assert(i > 0);
|
||
|
nalu = (p[i + 1] >> 3) & 0x1f;
|
||
|
return H266_NAL_AUD == nalu ? 1 : 0;
|
||
|
}
|
||
|
|
||
|
static int mpeg_h266_is_new_access_unit(const uint8_t* nalu, size_t bytes)
|
||
|
{
|
||
|
uint8_t nal_type;
|
||
|
uint8_t nuh_layer_id;
|
||
|
|
||
|
if (bytes < 3)
|
||
|
return 0;
|
||
|
|
||
|
nal_type = (nalu[1] >> 3) & 0x1f;
|
||
|
nuh_layer_id = nalu[0] & 0x3F;
|
||
|
|
||
|
// 7.4.2.4.3 Order of PUs and their association to AUs
|
||
|
if (H266_NAL_AUD == nal_type || H266_NAL_OPI == nal_type || H266_NAL_DCI == nal_type || H266_NAL_VPS == nal_type || H266_NAL_SPS == nal_type || H266_NAL_PPS == nal_type ||
|
||
|
(nuh_layer_id == 0 && (H266_PREFIX_APS_NUT == nal_type || H266_PH_NUT == nal_type || H266_NAL_PREFIX_SEI == nal_type ||
|
||
|
26 == nal_type || (28 <= nal_type && nal_type <= 29))))
|
||
|
return 1;
|
||
|
|
||
|
// 7.4.2.4.4 Order of NAL units and coded pictures and their association to PUs
|
||
|
if (nal_type < H266_NAL_OPI)
|
||
|
{
|
||
|
//sh_picture_header_in_slice_header_flag == 1
|
||
|
return (nalu[2] & 0x80) ? 1 : 0;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int mpeg_h266_find_new_access_unit(const uint8_t* data, size_t bytes, int* vcl)
|
||
|
{
|
||
|
int n;
|
||
|
size_t leading;
|
||
|
uint8_t nal_type;
|
||
|
const uint8_t* p, * end;
|
||
|
|
||
|
end = data + bytes;
|
||
|
for (p = data; p && p < end; p += n)
|
||
|
{
|
||
|
n = mpeg_h264_find_nalu(p, end - p, &leading);
|
||
|
if (n < 1)
|
||
|
return -1;
|
||
|
|
||
|
nal_type = (p[n+1] >> 3) & 0x1f;
|
||
|
if (*vcl > 0 && mpeg_h266_is_new_access_unit(p + n, end - p - n))
|
||
|
{
|
||
|
return (int)(p - data + n - leading);
|
||
|
}
|
||
|
else if (nal_type < H266_NAL_OPI)
|
||
|
{
|
||
|
*vcl = (H266_NAL_IDR_W_RADL <= nal_type && nal_type <= H266_NAL_RSV_IRAP) ? MPEG_VCL_IDR : MPEG_VCL_P;
|
||
|
}
|
||
|
else if (PES_SID_START == p[n])
|
||
|
{
|
||
|
// pes data loss ???
|
||
|
*vcl = MPEG_VCL_CORRUPT; // for assert
|
||
|
return (int)(p - data + n - leading);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// nothing to do
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|