mirror of
https://github.com/rofafor/vdr-plugin-femon.git
synced 2023-10-10 13:36:53 +02:00
Refactored bitstream code.
This commit is contained in:
parent
5003faabc4
commit
ac4d414597
3
HISTORY
3
HISTORY
@ -417,6 +417,7 @@ VDR Plugin 'femon' Revision History
|
||||
|
||||
2011-xx-xx: Version 1.7.11
|
||||
|
||||
- Updated for vdr-1.7.19: New API functions for signal strength
|
||||
- Updated for vdr-1.7.22: New API functions for signal strength
|
||||
and quality used to provide information for the OSD.
|
||||
- Added cppcheck target into Makefile.
|
||||
- Refactored bitstream code.
|
||||
|
20
femonaac.c
20
femonaac.c
@ -26,7 +26,7 @@ cFemonAAC::~cFemonAAC()
|
||||
|
||||
bool cFemonAAC::processAudio(const uint8_t *buf, int len)
|
||||
{
|
||||
cBitStream bs(buf, len * 8);
|
||||
cFemonBitStream bs(buf, len * 8);
|
||||
|
||||
if (!m_AudioHandler)
|
||||
return false;
|
||||
@ -48,23 +48,23 @@ bool cFemonAAC::processAudio(const uint8_t *buf, int len)
|
||||
// skip PES header
|
||||
if (!PesLongEnough(len))
|
||||
return false;
|
||||
bs.skipBits(8 * PesPayloadOffset(buf));
|
||||
bs.SkipBits(8 * PesPayloadOffset(buf));
|
||||
|
||||
// HE-AAC audio detection
|
||||
if (bs.getBits(12) != 0xFFF) // syncword
|
||||
if (bs.GetBits(12) != 0xFFF) // syncword
|
||||
return false;
|
||||
|
||||
bs.skipBit(); // id
|
||||
bs.SkipBit(); // id
|
||||
|
||||
// layer must be 0
|
||||
if (bs.getBits(2)) // layer
|
||||
if (bs.GetBits(2)) // layer
|
||||
return false;
|
||||
|
||||
bs.skipBit(); // protection_absent
|
||||
bs.skipBits(2); // profile
|
||||
int sampling_frequency_index = bs.getBits(4); // sampling_frequency_index
|
||||
bs.skipBit(); // private pid
|
||||
int channel_configuration = bs.getBits(3); // channel_configuration
|
||||
bs.SkipBit(); // protection_absent
|
||||
bs.SkipBits(2); // profile
|
||||
int sampling_frequency_index = bs.GetBits(4); // sampling_frequency_index
|
||||
bs.SkipBit(); // private pid
|
||||
int channel_configuration = bs.GetBits(3); // channel_configuration
|
||||
|
||||
m_AudioHandler->SetAudioCodec(AUDIO_CODEC_HEAAC);
|
||||
m_AudioHandler->SetAudioBitrate(AUDIO_BITRATE_RESERVED);
|
||||
|
28
femonac3.c
28
femonac3.c
@ -41,7 +41,7 @@ bool cFemonAC3::processAudio(const uint8_t *buf, int len)
|
||||
int centermixlevel = AUDIO_CENTER_MIX_LEVEL_INVALID;
|
||||
int surroundmixlevel = AUDIO_SURROUND_MIX_LEVEL_INVALID;
|
||||
int dolbysurroundmode = AUDIO_DOLBY_SURROUND_MODE_INVALID;
|
||||
cBitStream bs(buf, len * 8);
|
||||
cFemonBitStream bs(buf, len * 8);
|
||||
|
||||
if (!m_AudioHandler)
|
||||
return false;
|
||||
@ -49,34 +49,34 @@ bool cFemonAC3::processAudio(const uint8_t *buf, int len)
|
||||
// skip PES header
|
||||
if (!PesLongEnough(len))
|
||||
return false;
|
||||
bs.skipBits(8 * PesPayloadOffset(buf));
|
||||
bs.SkipBits(8 * PesPayloadOffset(buf));
|
||||
|
||||
// http://rmworkshop.com/dvd_info/related_info/ac3hdr.htm
|
||||
|
||||
// AC3 audio detection
|
||||
if (bs.getU16() != 0x0B77) // syncword
|
||||
if (bs.GetBits(16) != 0x0B77) // syncword
|
||||
return false;
|
||||
|
||||
bs.skipBits(16); // CRC1
|
||||
bs.SkipBits(16); // CRC1
|
||||
|
||||
fscod = bs.getBits(2); // sampling rate values
|
||||
frmsizcod = bs.getBits(6); // frame size code
|
||||
fscod = bs.GetBits(2); // sampling rate values
|
||||
frmsizcod = bs.GetBits(6); // frame size code
|
||||
|
||||
bs.skipBits(5); // bitstream id
|
||||
bsmod = bs.getBits(3); // bitstream mode
|
||||
acmod = bs.getBits(3); // audio coding mode
|
||||
bs.SkipBits(5); // bitstream id
|
||||
bsmod = bs.GetBits(3); // bitstream mode
|
||||
acmod = bs.GetBits(3); // audio coding mode
|
||||
|
||||
// 3 front channels
|
||||
if ((acmod & 0x01) && (acmod != 0x01))
|
||||
centermixlevel = bs.getBits(2);
|
||||
centermixlevel = bs.GetBits(2);
|
||||
|
||||
// if a surround channel exists
|
||||
if (acmod & 0x04)
|
||||
surroundmixlevel = bs.getBits(2);
|
||||
surroundmixlevel = bs.GetBits(2);
|
||||
|
||||
// if in 2/0 mode
|
||||
if (acmod == 0x02)
|
||||
dolbysurroundmode = bs.getBits(2);
|
||||
dolbysurroundmode = bs.GetBits(2);
|
||||
|
||||
m_AudioHandler->SetAC3Bitrate(1000 * s_Bitrates[frmsizcod >> 1]);
|
||||
m_AudioHandler->SetAC3SamplingFrequency(100 * s_Frequencies[fscod]);
|
||||
@ -86,8 +86,8 @@ bool cFemonAC3::processAudio(const uint8_t *buf, int len)
|
||||
m_AudioHandler->SetAC3SurroundMix(surroundmixlevel);
|
||||
m_AudioHandler->SetAC3DolbySurround(dolbysurroundmode);
|
||||
|
||||
m_AudioHandler->SetAC3LFE(bs.getBit()); // low frequency effects on
|
||||
m_AudioHandler->SetAC3Dialog(bs.getBits(5)); // dialog normalization
|
||||
m_AudioHandler->SetAC3LFE(bs.GetBit()); // low frequency effects on
|
||||
m_AudioHandler->SetAC3Dialog(bs.GetBits(5)); // dialog normalization
|
||||
|
||||
return true;
|
||||
}
|
||||
|
262
femonh264.c
262
femonh264.c
@ -222,7 +222,7 @@ int cFemonH264::nalUnescape(uint8_t *dst, const uint8_t *src, int len)
|
||||
int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
{
|
||||
int profile_idc, level_idc, constraint_set3_flag, pic_order_cnt_type, i, j;
|
||||
cBitStream bs(buf, len);
|
||||
cFemonBitStream bs(buf, len);
|
||||
|
||||
uint32_t width = m_Width;
|
||||
uint32_t height = m_Height;
|
||||
@ -236,14 +236,14 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
bool mb_adaptive_frame_field_flag = m_MbAdaptiveFrameFieldFlag;
|
||||
uint32_t time_offset_length = m_TimeOffsetLength;
|
||||
|
||||
profile_idc = bs.getU8(); // profile_idc
|
||||
bs.skipBit(); // constraint_set0_flag
|
||||
bs.skipBit(); // constraint_set1_flag
|
||||
bs.skipBit(); // constraint_set2_flag
|
||||
constraint_set3_flag = bs.getBit(); // constraint_set3_flag
|
||||
bs.skipBits(4); // reserved_zero_4bits
|
||||
level_idc = bs.getU8(); // level_idc
|
||||
bs.skipUeGolomb(); // seq_parameter_set_id
|
||||
profile_idc = bs.GetBits(8); // profile_idc
|
||||
bs.SkipBit(); // constraint_set0_flag
|
||||
bs.SkipBit(); // constraint_set1_flag
|
||||
bs.SkipBit(); // constraint_set2_flag
|
||||
constraint_set3_flag = bs.GetBit(); // constraint_set3_flag
|
||||
bs.SkipBits(4); // reserved_zero_4bits
|
||||
level_idc = bs.GetBits(8); // level_idc
|
||||
bs.SkipUeGolomb(); // seq_parameter_set_id
|
||||
//debug("H.264 SPS: profile_idc %d level_idc %d\n", profile_idc, level_idc);
|
||||
switch (profile_idc) {
|
||||
case 66: // baseline profile
|
||||
@ -457,55 +457,55 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
break;
|
||||
}
|
||||
if ((profile_idc == 100) || (profile_idc == 110) || (profile_idc == 122) || (profile_idc == 144)) {
|
||||
if (bs.getUeGolomb() == 3) // chroma_format_idc
|
||||
bs.skipBit(); // residual_colour_transform_flag
|
||||
bs.skipUeGolomb(); // bit_depth_luma_minus8
|
||||
bs.skipUeGolomb(); // bit_depth_chroma_minus8
|
||||
bs.skipBit(); // qpprime_y_zero_transform_bypass_flag
|
||||
if (bs.getBit()) { // seq_scaling_matrix_present_flag
|
||||
if (bs.GetUeGolomb() == 3) // chroma_format_idc
|
||||
bs.SkipBit(); // residual_colour_transform_flag
|
||||
bs.SkipUeGolomb(); // bit_depth_luma_minus8
|
||||
bs.SkipUeGolomb(); // bit_depth_chroma_minus8
|
||||
bs.SkipBit(); // qpprime_y_zero_transform_bypass_flag
|
||||
if (bs.GetBit()) { // seq_scaling_matrix_present_flag
|
||||
for (i = 0; i < 8; ++i) {
|
||||
if (bs.getBit()) { // seq_scaling_list_present_flag[i]
|
||||
if (bs.GetBit()) { // seq_scaling_list_present_flag[i]
|
||||
int last = 8, next = 8, size = (i < 6) ? 16 : 64;
|
||||
for (j = 0; j < size; ++j) {
|
||||
if (next)
|
||||
next = (last + bs.getSeGolomb()) & 0xff;
|
||||
next = (last + bs.GetSeGolomb()) & 0xff;
|
||||
last = next ?: last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bs.skipUeGolomb(); // log2_max_frame_num_minus4
|
||||
pic_order_cnt_type = bs.getUeGolomb(); // pic_order_cnt_type
|
||||
bs.SkipUeGolomb(); // log2_max_frame_num_minus4
|
||||
pic_order_cnt_type = bs.GetUeGolomb(); // pic_order_cnt_type
|
||||
if (pic_order_cnt_type == 0)
|
||||
bs.skipUeGolomb(); // log2_max_pic_order_cnt_lsb_minus4
|
||||
bs.SkipUeGolomb(); // log2_max_pic_order_cnt_lsb_minus4
|
||||
else if (pic_order_cnt_type == 1) {
|
||||
bs.skipBit(); // delta_pic_order_always_zero
|
||||
bs.skipSeGolomb(); // offset_for_non_ref_pic
|
||||
bs.skipSeGolomb(); // offset_for_top_to_bottom_field
|
||||
j = bs.getUeGolomb(); // num_ref_frames_in_pic_order_cnt_cycle
|
||||
bs.SkipBit(); // delta_pic_order_always_zero
|
||||
bs.SkipSeGolomb(); // offset_for_non_ref_pic
|
||||
bs.SkipSeGolomb(); // offset_for_top_to_bottom_field
|
||||
j = bs.GetUeGolomb(); // num_ref_frames_in_pic_order_cnt_cycle
|
||||
for (i = 0; i < j; ++i)
|
||||
bs.skipSeGolomb(); // offset_for_ref_frame[i]
|
||||
bs.SkipSeGolomb(); // offset_for_ref_frame[i]
|
||||
}
|
||||
bs.skipUeGolomb(); // num_ref_frames
|
||||
bs.skipBit(); // gaps_in_frame_num_value_allowed_flag
|
||||
width = bs.getUeGolomb() + 1; // pic_width_in_mbs_minus1
|
||||
height = bs.getUeGolomb() + 1; // pic_height_in_mbs_minus1
|
||||
frame_mbs_only_flag = bs.getBit(); // frame_mbs_only_flag
|
||||
bs.SkipUeGolomb(); // num_ref_frames
|
||||
bs.SkipBit(); // gaps_in_frame_num_value_allowed_flag
|
||||
width = bs.GetUeGolomb() + 1; // pic_width_in_mbs_minus1
|
||||
height = bs.GetUeGolomb() + 1; // pic_height_in_mbs_minus1
|
||||
frame_mbs_only_flag = bs.GetBit(); // frame_mbs_only_flag
|
||||
//debug("H.264 SPS: pic_width: %u mbs\n", width);
|
||||
//debug("H.264 SPS: pic_height: %u mbs\n", height);
|
||||
//debug("H.264 SPS: frame only flag: %d\n", frame_mbs_only_flag);
|
||||
width *= 16;
|
||||
height *= 16 * (frame_mbs_only_flag ? 1 : 2);
|
||||
if (!frame_mbs_only_flag)
|
||||
mb_adaptive_frame_field_flag = bs.getBit(); // mb_adaptive_frame_field_flag
|
||||
bs.skipBit(); // direct_8x8_inference_flag
|
||||
if (bs.getBit()) { // frame_cropping_flag
|
||||
mb_adaptive_frame_field_flag = bs.GetBit(); // mb_adaptive_frame_field_flag
|
||||
bs.SkipBit(); // direct_8x8_inference_flag
|
||||
if (bs.GetBit()) { // frame_cropping_flag
|
||||
uint32_t crop_left, crop_right, crop_top, crop_bottom;
|
||||
crop_left = bs.getUeGolomb(); // frame_crop_left_offset
|
||||
crop_right = bs.getUeGolomb(); // frame_crop_rigth_offset
|
||||
crop_top = bs.getUeGolomb(); // frame_crop_top_offset
|
||||
crop_bottom = bs.getUeGolomb(); // frame_crop_bottom_offset
|
||||
crop_left = bs.GetUeGolomb(); // frame_crop_left_offset
|
||||
crop_right = bs.GetUeGolomb(); // frame_crop_rigth_offset
|
||||
crop_top = bs.GetUeGolomb(); // frame_crop_top_offset
|
||||
crop_bottom = bs.GetUeGolomb(); // frame_crop_bottom_offset
|
||||
//debug("H.264 SPS: cropping %d %d %d %d\n", crop_left, crop_top, crop_right, crop_bottom);
|
||||
width -= 2 * (crop_left + crop_right);
|
||||
if (frame_mbs_only_flag)
|
||||
@ -514,14 +514,14 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
height -= 4 * (crop_top + crop_bottom);
|
||||
}
|
||||
// VUI parameters
|
||||
if (bs.getBit()) { // vui_parameters_present_flag
|
||||
if (bs.getBit()) { // aspect_ratio_info_present
|
||||
if (bs.GetBit()) { // vui_parameters_present_flag
|
||||
if (bs.GetBit()) { // aspect_ratio_info_present
|
||||
uint32_t aspect_ratio_idc, sar_width = 0, sar_height = 0;
|
||||
aspect_ratio_idc = bs.getU8(); // aspect_ratio_idc
|
||||
aspect_ratio_idc = bs.GetBits(8); // aspect_ratio_idc
|
||||
//debug("H.264 SPS: aspect_ratio_idc %d\n", aspect_ratio_idc);
|
||||
if (aspect_ratio_idc == 255) { // extended sar
|
||||
sar_width = bs.getU16(); // sar_width
|
||||
sar_height = bs.getU16(); // sar_height
|
||||
sar_width = bs.GetBits(16); // sar_width
|
||||
sar_height = bs.GetBits(16); // sar_height
|
||||
}
|
||||
else if (aspect_ratio_idc < ELEMENTS(s_SAR)) {
|
||||
sar_width = s_SAR[aspect_ratio_idc].w;
|
||||
@ -546,78 +546,78 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
//debug("H.264 SPS: DAR %dx%d (%d)\n", sar_width, sar_height, aspect_ratio);
|
||||
}
|
||||
}
|
||||
if (bs.getBit()) // overscan_info_present_flag
|
||||
bs.skipBit(); // overscan_approriate_flag
|
||||
if (bs.getBit()) { // video_signal_type_present_flag
|
||||
if (bs.GetBit()) // overscan_info_present_flag
|
||||
bs.SkipBit(); // overscan_approriate_flag
|
||||
if (bs.GetBit()) { // video_signal_type_present_flag
|
||||
uint32_t video_format;
|
||||
video_format = bs.getBits(3); // video_format
|
||||
video_format = bs.GetBits(3); // video_format
|
||||
if (video_format < sizeof(s_VideoFormats) / sizeof(s_VideoFormats[0])) {
|
||||
format = s_VideoFormats[video_format];
|
||||
//debug("H.264 SPS: video format %d\n", format);
|
||||
}
|
||||
bs.skipBit(); // video_full_range_flag
|
||||
if (bs.getBit()) { // colour_description_present_flag
|
||||
bs.skipBits(8); // colour_primaries
|
||||
bs.skipBits(8); // transfer_characteristics
|
||||
bs.skipBits(8); // matrix_coefficients
|
||||
bs.SkipBit(); // video_full_range_flag
|
||||
if (bs.GetBit()) { // colour_description_present_flag
|
||||
bs.SkipBits(8); // colour_primaries
|
||||
bs.SkipBits(8); // transfer_characteristics
|
||||
bs.SkipBits(8); // matrix_coefficients
|
||||
}
|
||||
}
|
||||
if (bs.getBit()) { // chroma_loc_info_present_flag
|
||||
bs.skipUeGolomb(); // chroma_sample_loc_type_top_field
|
||||
bs.skipUeGolomb(); // chroma_sample_loc_type_bottom_field
|
||||
if (bs.GetBit()) { // chroma_loc_info_present_flag
|
||||
bs.SkipUeGolomb(); // chroma_sample_loc_type_top_field
|
||||
bs.SkipUeGolomb(); // chroma_sample_loc_type_bottom_field
|
||||
}
|
||||
if (bs.getBit()) { // timing_info_present_flag
|
||||
if (bs.GetBit()) { // timing_info_present_flag
|
||||
uint32_t num_units_in_tick, time_scale;
|
||||
num_units_in_tick = bs.getU32(); // num_units_in_tick
|
||||
time_scale = bs.getU32(); // time_scale
|
||||
num_units_in_tick = bs.GetBits(32); // num_units_in_tick
|
||||
time_scale = bs.GetBits(32); // time_scale
|
||||
if (num_units_in_tick > 0)
|
||||
frame_rate = time_scale / num_units_in_tick;
|
||||
bs.skipBit(); // fixed_frame_rate_flag
|
||||
bs.SkipBit(); // fixed_frame_rate_flag
|
||||
}
|
||||
int nal_hrd_parameters_present_flag = bs.getBit(); // nal_hrd_parameters_present_flag
|
||||
int nal_hrd_parameters_present_flag = bs.GetBit(); // nal_hrd_parameters_present_flag
|
||||
if (nal_hrd_parameters_present_flag) {
|
||||
int cpb_cnt_minus1;
|
||||
cpb_cnt_minus1 = bs.getUeGolomb(); // cpb_cnt_minus1
|
||||
bs.skipBits(4); // bit_rate_scale
|
||||
bs.skipBits(4); // cpb_size_scale
|
||||
cpb_cnt_minus1 = bs.GetUeGolomb(); // cpb_cnt_minus1
|
||||
bs.SkipBits(4); // bit_rate_scale
|
||||
bs.SkipBits(4); // cpb_size_scale
|
||||
for (int i = 0; i < cpb_cnt_minus1; ++i) {
|
||||
bs.skipUeGolomb(); // bit_rate_value_minus1[i]
|
||||
bs.skipUeGolomb(); // cpb_size_value_minus1[i]
|
||||
bs.skipBit(); // cbr_flag[i]
|
||||
bs.SkipUeGolomb(); // bit_rate_value_minus1[i]
|
||||
bs.SkipUeGolomb(); // cpb_size_value_minus1[i]
|
||||
bs.SkipBit(); // cbr_flag[i]
|
||||
}
|
||||
bs.skipBits(5); // initial_cpb_removal_delay_length_minus1
|
||||
bs.skipBits(5); // cpb_removal_delay_length_minus1
|
||||
bs.skipBits(5); // dpb_output_delay_length_minus1
|
||||
time_offset_length = bs.getBits(5); // time_offset_length
|
||||
bs.SkipBits(5); // initial_cpb_removal_delay_length_minus1
|
||||
bs.SkipBits(5); // cpb_removal_delay_length_minus1
|
||||
bs.SkipBits(5); // dpb_output_delay_length_minus1
|
||||
time_offset_length = bs.GetBits(5); // time_offset_length
|
||||
}
|
||||
int vlc_hrd_parameters_present_flag = bs.getBit(); // vlc_hrd_parameters_present_flag
|
||||
int vlc_hrd_parameters_present_flag = bs.GetBit(); // vlc_hrd_parameters_present_flag
|
||||
if (vlc_hrd_parameters_present_flag) {
|
||||
int cpb_cnt_minus1;
|
||||
cpb_cnt_minus1 = bs.getUeGolomb(); // cpb_cnt_minus1
|
||||
bs.skipBits(4); // bit_rate_scale
|
||||
bs.skipBits(4); // cpb_size_scale
|
||||
cpb_cnt_minus1 = bs.GetUeGolomb(); // cpb_cnt_minus1
|
||||
bs.SkipBits(4); // bit_rate_scale
|
||||
bs.SkipBits(4); // cpb_size_scale
|
||||
for (int i = 0; i < cpb_cnt_minus1; ++i) {
|
||||
bs.skipUeGolomb(); // bit_rate_value_minus1[i]
|
||||
bs.skipUeGolomb(); // cpb_size_value_minus1[i]
|
||||
bs.skipBit(); // cbr_flag[i]
|
||||
bs.SkipUeGolomb(); // bit_rate_value_minus1[i]
|
||||
bs.SkipUeGolomb(); // cpb_size_value_minus1[i]
|
||||
bs.SkipBit(); // cbr_flag[i]
|
||||
}
|
||||
bs.skipBits(5); // initial_cpb_removal_delay_length_minus1
|
||||
bs.skipBits(5); // cpb_removal_delay_length_minus1
|
||||
bs.skipBits(5); // dpb_output_delay_length_minus1
|
||||
time_offset_length = bs.getBits(5);// time_offset_length
|
||||
bs.SkipBits(5); // initial_cpb_removal_delay_length_minus1
|
||||
bs.SkipBits(5); // cpb_removal_delay_length_minus1
|
||||
bs.SkipBits(5); // dpb_output_delay_length_minus1
|
||||
time_offset_length = bs.GetBits(5);// time_offset_length
|
||||
}
|
||||
cpb_dpb_delays_present_flag = (nal_hrd_parameters_present_flag | vlc_hrd_parameters_present_flag);
|
||||
if (cpb_dpb_delays_present_flag)
|
||||
bs.skipBit(); // low_delay_hrd_flag
|
||||
pic_struct_present_flag = bs.getBit(); // pic_struct_present_flag
|
||||
if (bs.getBit()) { // bitstream_restriction_flag
|
||||
bs.skipBit(); // motion_vectors_over_pic_boundaries_flag
|
||||
bs.skipUeGolomb(); // max_bytes_per_pic_denom
|
||||
bs.skipUeGolomb(); // max_bits_per_mb_denom
|
||||
bs.skipUeGolomb(); // log2_max_mv_length_horizontal
|
||||
bs.skipUeGolomb(); // log2_max_mv_length_vertical
|
||||
bs.skipUeGolomb(); // num_reorder_frames
|
||||
bs.skipUeGolomb(); // max_dec_frame_buffering
|
||||
bs.SkipBit(); // low_delay_hrd_flag
|
||||
pic_struct_present_flag = bs.GetBit(); // pic_struct_present_flag
|
||||
if (bs.GetBit()) { // bitstream_restriction_flag
|
||||
bs.SkipBit(); // motion_vectors_over_pic_boundaries_flag
|
||||
bs.SkipUeGolomb(); // max_bytes_per_pic_denom
|
||||
bs.SkipUeGolomb(); // max_bits_per_mb_denom
|
||||
bs.SkipUeGolomb(); // log2_max_mv_length_horizontal
|
||||
bs.SkipUeGolomb(); // log2_max_mv_length_vertical
|
||||
bs.SkipUeGolomb(); // num_reorder_frames
|
||||
bs.SkipUeGolomb(); // max_dec_frame_buffering
|
||||
}
|
||||
}
|
||||
|
||||
@ -633,38 +633,38 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
m_MbAdaptiveFrameFieldFlag = mb_adaptive_frame_field_flag;
|
||||
m_TimeOffsetLength = time_offset_length;
|
||||
|
||||
return (bs.getIndex() / 8);
|
||||
return (bs.Index() / 8);
|
||||
}
|
||||
|
||||
int cFemonH264::parseSEI(const uint8_t *buf, int len)
|
||||
{
|
||||
int num_referenced_subseqs, i;
|
||||
cBitStream bs(buf, len);
|
||||
cFemonBitStream bs(buf, len);
|
||||
|
||||
eVideoScan scan = m_Scan;
|
||||
|
||||
while ((bs.getIndex() * 8 + 16) < len) { // sei_message
|
||||
while ((bs.Index() * 8 + 16) < len) { // sei_message
|
||||
int lastByte, payloadSize = 0, payloadType = 0;
|
||||
|
||||
do {
|
||||
lastByte = bs.getU8() & 0xFF;
|
||||
lastByte = bs.GetBits(8) & 0xFF;
|
||||
payloadType += lastByte;
|
||||
} while (lastByte == 0xFF); // last_payload_type_byte
|
||||
|
||||
do {
|
||||
lastByte = bs.getU8() & 0xFF;
|
||||
lastByte = bs.GetBits(8) & 0xFF;
|
||||
payloadSize += lastByte;
|
||||
} while (lastByte == 0xFF); // last_payload_size_byte
|
||||
|
||||
switch (payloadType) { // sei_payload
|
||||
case 1: // pic_timing
|
||||
if (m_CpbDpbDelaysPresentFlag) { // cpb_dpb_delays_present_flag
|
||||
bs.skipUeGolomb(); // cpb_removal_delay
|
||||
bs.skipUeGolomb(); // dpb_output_delay
|
||||
bs.SkipUeGolomb(); // cpb_removal_delay
|
||||
bs.SkipUeGolomb(); // dpb_output_delay
|
||||
}
|
||||
if (m_PicStructPresentFlag) { // pic_struct_present_flag
|
||||
uint32_t pic_struct;
|
||||
pic_struct = bs.getBits(4); // pic_struct
|
||||
pic_struct = bs.GetBits(4); // pic_struct
|
||||
if (pic_struct >= (sizeof(s_SeiNumClockTsTable)) / sizeof(s_SeiNumClockTsTable[0]))
|
||||
return 0;
|
||||
if (m_FrameMbsOnlyFlag && !m_MbAdaptiveFrameFieldFlag)
|
||||
@ -691,9 +691,9 @@ int cFemonH264::parseSEI(const uint8_t *buf, int len)
|
||||
}
|
||||
//debug("H.264 SEI: pic struct %d scan type %d\n", pic_struct, scan);
|
||||
for (int i = 0; i < s_SeiNumClockTsTable[pic_struct]; ++i) {
|
||||
if (bs.getBit()) { // clock_timestamp_flag[i]
|
||||
if (bs.GetBit()) { // clock_timestamp_flag[i]
|
||||
int full_timestamp_flag;
|
||||
switch (bs.getBits(2)) { // ct_type
|
||||
switch (bs.GetBits(2)) { // ct_type
|
||||
case 0:
|
||||
scan = VIDEO_SCAN_PROGRESSIVE;
|
||||
break;
|
||||
@ -708,62 +708,62 @@ int cFemonH264::parseSEI(const uint8_t *buf, int len)
|
||||
break;
|
||||
}
|
||||
//debug("H.264 SEI: scan type %d\n", scan);
|
||||
bs.skipBit(); // nuit_field_based_flag
|
||||
bs.skipBits(5); // counting_type
|
||||
full_timestamp_flag = bs.getBit(); // full_timestamp_flag
|
||||
bs.skipBit(); // discontinuity_flag
|
||||
bs.skipBit(); // cnt_dropped_flag
|
||||
bs.skipBits(8); // n_frames
|
||||
bs.SkipBit(); // nuit_field_based_flag
|
||||
bs.SkipBits(5); // counting_type
|
||||
full_timestamp_flag = bs.GetBit(); // full_timestamp_flag
|
||||
bs.SkipBit(); // discontinuity_flag
|
||||
bs.SkipBit(); // cnt_dropped_flag
|
||||
bs.SkipBits(8); // n_frames
|
||||
if (full_timestamp_flag) {
|
||||
bs.skipBits(6); // seconds_value
|
||||
bs.skipBits(6); // minutes_value
|
||||
bs.skipBits(5); // hours_value
|
||||
bs.SkipBits(6); // seconds_value
|
||||
bs.SkipBits(6); // minutes_value
|
||||
bs.SkipBits(5); // hours_value
|
||||
}
|
||||
else {
|
||||
if (bs.getBit()) { // seconds_flag
|
||||
bs.skipBits(6); // seconds_value
|
||||
if (bs.getBit()) { // minutes_flag
|
||||
bs.skipBits(6); // minutes_value
|
||||
if (bs.getBit()) // hours_flag
|
||||
bs.skipBits(5); // hours_value
|
||||
if (bs.GetBit()) { // seconds_flag
|
||||
bs.SkipBits(6); // seconds_value
|
||||
if (bs.GetBit()) { // minutes_flag
|
||||
bs.SkipBits(6); // minutes_value
|
||||
if (bs.GetBit()) // hours_flag
|
||||
bs.SkipBits(5); // hours_value
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_TimeOffsetLength > 0)
|
||||
bs.skipBits(m_TimeOffsetLength); // time_offset
|
||||
bs.SkipBits(m_TimeOffsetLength); // time_offset
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 12: // sub_seq_characteristics
|
||||
bs.skipUeGolomb(); // sub_seq_layer_num
|
||||
bs.skipUeGolomb(); // sub_seq_id
|
||||
if (bs.getBit()) // duration_flag
|
||||
bs.skipBits(32); // sub_seq_duration
|
||||
if (bs.getBit()) { // average_rate_flag
|
||||
bs.skipBit(); // accurate_statistics_flag
|
||||
bs.skipBits(16); // average_bit_rate (1000 bit/s)
|
||||
bs.skipBits(16); // average_frame_rate (frames per 256s)
|
||||
bs.SkipUeGolomb(); // sub_seq_layer_num
|
||||
bs.SkipUeGolomb(); // sub_seq_id
|
||||
if (bs.GetBit()) // duration_flag
|
||||
bs.SkipBits(32); // sub_seq_duration
|
||||
if (bs.GetBit()) { // average_rate_flag
|
||||
bs.SkipBit(); // accurate_statistics_flag
|
||||
bs.SkipBits(16); // average_bit_rate (1000 bit/s)
|
||||
bs.SkipBits(16); // average_frame_rate (frames per 256s)
|
||||
}
|
||||
num_referenced_subseqs = bs.getUeGolomb(); // num_referenced_subseqs
|
||||
num_referenced_subseqs = bs.GetUeGolomb(); // num_referenced_subseqs
|
||||
for (i = 0; i < num_referenced_subseqs; ++i) {
|
||||
bs.skipUeGolomb(); // ref_sub_seq_layer_num
|
||||
bs.skipUeGolomb(); // ref_sub_seq_id
|
||||
bs.getBit(); // ref_sub_seq_direction
|
||||
bs.SkipUeGolomb(); // ref_sub_seq_layer_num
|
||||
bs.SkipUeGolomb(); // ref_sub_seq_id
|
||||
bs.GetBit(); // ref_sub_seq_direction
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
bs.skipBits(payloadSize * 8);
|
||||
bs.SkipBits(payloadSize * 8);
|
||||
break;
|
||||
}
|
||||
|
||||
// force byte align
|
||||
bs.byteAlign();
|
||||
bs.ByteAlign();
|
||||
}
|
||||
|
||||
m_Scan = scan;
|
||||
|
||||
return (bs.getIndex() / 8);
|
||||
return (bs.Index() / 8);
|
||||
}
|
||||
|
22
femonlatm.c
22
femonlatm.c
@ -31,7 +31,7 @@ cFemonLATM::~cFemonLATM()
|
||||
|
||||
bool cFemonLATM::processAudio(const uint8_t *buf, int len)
|
||||
{
|
||||
cBitStream bs(buf, len * 8);
|
||||
cFemonBitStream bs(buf, len * 8);
|
||||
|
||||
if (!m_AudioHandler)
|
||||
return false;
|
||||
@ -39,23 +39,23 @@ bool cFemonLATM::processAudio(const uint8_t *buf, int len)
|
||||
// skip PES header
|
||||
if (!PesLongEnough(len))
|
||||
return false;
|
||||
bs.skipBits(8 * PesPayloadOffset(buf));
|
||||
bs.SkipBits(8 * PesPayloadOffset(buf));
|
||||
|
||||
// MPEG audio detection
|
||||
if (bs.getBits(12) != 0x56E) // syncword
|
||||
if (bs.GetBits(12) != 0x56E) // syncword
|
||||
return false;
|
||||
|
||||
m_AudioHandler->SetAudioCodec(AUDIO_CODEC_LATM);
|
||||
|
||||
if (bs.getBit() == 0) // id: MPEG-1=1, extension to lower sampling frequencies=0
|
||||
if (bs.GetBit() == 0) // id: MPEG-1=1, extension to lower sampling frequencies=0
|
||||
return true; // @todo: lower sampling frequencies support
|
||||
int layer = 3 - bs.getBits(2); // layer: I=11, II=10, III=01
|
||||
bs.skipBit(); // protection bit
|
||||
int bit_rate_index = bs.getBits(4); // bitrate index
|
||||
int sampling_frequency = bs.getBits(2); // sampling frequency
|
||||
bs.skipBit(); // padding bit
|
||||
bs.skipBit(); // private pid
|
||||
int mode = bs.getBits(2); // mode
|
||||
int layer = 3 - bs.GetBits(2); // layer: I=11, II=10, III=01
|
||||
bs.SkipBit(); // protection bit
|
||||
int bit_rate_index = bs.GetBits(4); // bitrate index
|
||||
int sampling_frequency = bs.GetBits(2); // sampling frequency
|
||||
bs.SkipBit(); // padding bit
|
||||
bs.SkipBit(); // private pid
|
||||
int mode = bs.GetBits(2); // mode
|
||||
|
||||
switch (mode) {
|
||||
case 0:
|
||||
|
84
femonmpeg.c
84
femonmpeg.c
@ -48,7 +48,7 @@ cFemonMPEG::~cFemonMPEG()
|
||||
|
||||
bool cFemonMPEG::processAudio(const uint8_t *buf, int len)
|
||||
{
|
||||
cBitStream bs(buf, len * 8);
|
||||
cFemonBitStream bs(buf, len * 8);
|
||||
|
||||
if (!m_AudioHandler)
|
||||
return false;
|
||||
@ -56,20 +56,20 @@ bool cFemonMPEG::processAudio(const uint8_t *buf, int len)
|
||||
// skip PES header
|
||||
if (!PesLongEnough(len))
|
||||
return false;
|
||||
bs.skipBits(8 * PesPayloadOffset(buf));
|
||||
bs.SkipBits(8 * PesPayloadOffset(buf));
|
||||
|
||||
// MPEG audio detection
|
||||
if (bs.getBits(12) != 0xFFF) // syncword
|
||||
if (bs.GetBits(12) != 0xFFF) // syncword
|
||||
return false;
|
||||
|
||||
int id = bs.getBit(); // id: MPEG-2=0, MPEG-1=1
|
||||
int layer = 3 - bs.getBits(2); // layer: I=11, II=10, III=01
|
||||
bs.skipBit(); // protection bit
|
||||
int bit_rate_index = bs.getBits(4); // bitrate index
|
||||
int sampling_frequency = bs.getBits(2); // sampling frequency
|
||||
bs.skipBit(); // padding bit
|
||||
bs.skipBit(); // private pid
|
||||
int mode = bs.getBits(2); // mode
|
||||
int id = bs.GetBit(); // id: MPEG-2=0, MPEG-1=1
|
||||
int layer = 3 - bs.GetBits(2); // layer: I=11, II=10, III=01
|
||||
bs.SkipBit(); // protection bit
|
||||
int bit_rate_index = bs.GetBits(4); // bitrate index
|
||||
int sampling_frequency = bs.GetBits(2); // sampling frequency
|
||||
bs.SkipBit(); // padding bit
|
||||
bs.SkipBit(); // private pid
|
||||
int mode = bs.GetBits(2); // mode
|
||||
|
||||
m_AudioHandler->SetAudioCodec(s_Formats[id][layer]);
|
||||
|
||||
@ -124,7 +124,7 @@ bool cFemonMPEG::processAudio(const uint8_t *buf, int len)
|
||||
|
||||
bool cFemonMPEG::processVideo(const uint8_t *buf, int len)
|
||||
{
|
||||
cBitStream bs(buf, len * 8);
|
||||
cFemonBitStream bs(buf, len * 8);
|
||||
|
||||
if (!m_VideoHandler)
|
||||
return false;
|
||||
@ -132,20 +132,20 @@ bool cFemonMPEG::processVideo(const uint8_t *buf, int len)
|
||||
// skip PES header
|
||||
if (!PesLongEnough(len))
|
||||
return false;
|
||||
bs.skipBits(8 * PesPayloadOffset(buf));
|
||||
bs.SkipBits(8 * PesPayloadOffset(buf));
|
||||
|
||||
// MPEG-2 video detection, search for start code
|
||||
if (bs.getU32() != 0x000001B3) // sequence header
|
||||
if (bs.GetBits(32) != 0x000001B3) // sequence header
|
||||
return false;
|
||||
|
||||
int scan = VIDEO_SCAN_UNKNOWN;
|
||||
int format = VIDEO_FORMAT_UNKNOWN;
|
||||
int aspect = VIDEO_ASPECT_RATIO_RESERVED;
|
||||
|
||||
int horizontal_size = bs.getBits(12); // horizontal size value
|
||||
int vertical_size = bs.getBits(12); // vertical size value
|
||||
int horizontal_size = bs.GetBits(12); // horizontal size value
|
||||
int vertical_size = bs.GetBits(12); // vertical size value
|
||||
|
||||
switch (bs.getBits(4)) { // aspect ratio information
|
||||
switch (bs.GetBits(4)) { // aspect ratio information
|
||||
case 1:
|
||||
aspect = VIDEO_ASPECT_RATIO_1_1;
|
||||
break;
|
||||
@ -169,7 +169,7 @@ bool cFemonMPEG::processVideo(const uint8_t *buf, int len)
|
||||
}
|
||||
|
||||
double frame_rate = 0;
|
||||
switch (bs.getBits(4)) { // frame rate code
|
||||
switch (bs.GetBits(4)) { // frame rate code
|
||||
case 1:
|
||||
frame_rate = 24000 / 1001.0;
|
||||
format = VIDEO_FORMAT_UNKNOWN;
|
||||
@ -217,34 +217,34 @@ bool cFemonMPEG::processVideo(const uint8_t *buf, int len)
|
||||
break;
|
||||
}
|
||||
|
||||
int bit_rate = bs.getBits(18); // bit rate value
|
||||
int bit_rate = bs.GetBits(18); // bit rate value
|
||||
|
||||
bs.skipBit(); // marker bit
|
||||
bs.skipBits(10); // vbv buffer size value
|
||||
bs.skipBit(); // constrained parameters value
|
||||
if (bs.getBit()) // load intra quantizer matrix
|
||||
bs.skipBits(8 * 64); // intra quantizer matrix
|
||||
if (bs.getBit()) // load non-intra quantizer matrix
|
||||
bs.skipBits(8 * 64); // non-intra quantizer matrix
|
||||
bs.SkipBit(); // marker bit
|
||||
bs.SkipBits(10); // vbv buffer size value
|
||||
bs.SkipBit(); // constrained parameters value
|
||||
if (bs.GetBit()) // load intra quantizer matrix
|
||||
bs.SkipBits(8 * 64); // intra quantizer matrix
|
||||
if (bs.GetBit()) // load non-intra quantizer matrix
|
||||
bs.SkipBits(8 * 64); // non-intra quantizer matrix
|
||||
|
||||
if (bs.getU32() != 0x000001B5) { // extension start
|
||||
bs.skipBits(4); // extension start code identifier
|
||||
bs.skipBits(8); // profile and level indicator
|
||||
scan = bs.getBit() ? VIDEO_SCAN_PROGRESSIVE :
|
||||
if (bs.GetBits(32) != 0x000001B5) { // extension start
|
||||
bs.SkipBits(4); // extension start code identifier
|
||||
bs.SkipBits(8); // profile and level indicator
|
||||
scan = bs.GetBit() ? VIDEO_SCAN_PROGRESSIVE :
|
||||
VIDEO_SCAN_INTERLACED; // progressive sequence
|
||||
bs.skipBits(2); // chroma format
|
||||
horizontal_size |= (bs.getBits(2) << 12); // horizontal size extension
|
||||
vertical_size |= (bs.getBits(2) << 12); // vertical size extension
|
||||
bit_rate |= (bs.getBits(12) << 18); // bit rate extension
|
||||
bs.skipBit(); // marker bit
|
||||
bs.skipBits(8); // vpv buffer size extension
|
||||
bs.skipBit(); // low delay
|
||||
bs.skipBits(2); // frame rate extension n
|
||||
bs.skipBits(5); // frame rate extension d
|
||||
bs.SkipBits(2); // chroma format
|
||||
horizontal_size |= (bs.GetBits(2) << 12); // horizontal size extension
|
||||
vertical_size |= (bs.GetBits(2) << 12); // vertical size extension
|
||||
bit_rate |= (bs.GetBits(12) << 18); // bit rate extension
|
||||
bs.SkipBit(); // marker bit
|
||||
bs.SkipBits(8); // vpv buffer size extension
|
||||
bs.SkipBit(); // low delay
|
||||
bs.SkipBits(2); // frame rate extension n
|
||||
bs.SkipBits(5); // frame rate extension d
|
||||
|
||||
if ((bs.getU32() != 0x000001B5) && // extension start code
|
||||
(bs.getBits(4) == 0x0010)) { // sequence display extension id
|
||||
switch (bs.getBits(3)) { // video format
|
||||
if ((bs.GetBits(32) != 0x000001B5) && // extension start code
|
||||
(bs.GetBits(4) == 0x0010)) { // sequence display extension id
|
||||
switch (bs.GetBits(3)) { // video format
|
||||
case 0x000:
|
||||
format = VIDEO_FORMAT_COMPONENT;
|
||||
break;
|
||||
|
84
femontools.c
84
femontools.c
@ -542,84 +542,70 @@ cString getBitrateKbits(double value)
|
||||
return cString::sprintf("---");
|
||||
}
|
||||
|
||||
cBitStream::cBitStream(const uint8_t *buf, const int len)
|
||||
: data(buf),
|
||||
count(len),
|
||||
index(0)
|
||||
{
|
||||
}
|
||||
// --- cFemonBitStream -------------------------------------------------------
|
||||
|
||||
cBitStream::~cBitStream()
|
||||
int cFemonBitStream::GetBit(void)
|
||||
{
|
||||
}
|
||||
|
||||
int cBitStream::getBit()
|
||||
{
|
||||
if (index >= count)
|
||||
return (1); // -> no infinite colomb's ...
|
||||
|
||||
if (index >= length)
|
||||
return 1;
|
||||
int r = (data[index >> 3] >> (7 - (index & 7))) & 1;
|
||||
++index;
|
||||
|
||||
return (r);
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t cBitStream::getBits(uint32_t n)
|
||||
uint32_t cFemonBitStream::GetBits(int n)
|
||||
{
|
||||
uint32_t r = 0;
|
||||
|
||||
while (n--)
|
||||
r = (r | (getBit() << n));
|
||||
|
||||
return (r);
|
||||
r |= GetBit() << n;
|
||||
return r;
|
||||
}
|
||||
|
||||
void cBitStream::skipBits(uint32_t n)
|
||||
void cFemonBitStream::ByteAlign(void)
|
||||
{
|
||||
index += n;
|
||||
int n = index % 8;
|
||||
if (n > 0)
|
||||
SkipBits(8 - n);
|
||||
}
|
||||
|
||||
uint32_t cBitStream::getUeGolomb()
|
||||
void cFemonBitStream::WordAlign(void)
|
||||
{
|
||||
int n = index % 16;
|
||||
if (n > 0)
|
||||
SkipBits(16 - n);
|
||||
}
|
||||
|
||||
bool cFemonBitStream::SetLength(int Length)
|
||||
{
|
||||
if (Length > length)
|
||||
return false;
|
||||
length = Length;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t cFemonBitStream::GetUeGolomb()
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
while (!getBit() && (n < 32))
|
||||
while (!GetBit() && (n < 32))
|
||||
n++;
|
||||
|
||||
return (n ? ((1 << n) - 1) + getBits(n) : 0);
|
||||
return (n ? ((1 << n) - 1) + GetBits(n) : 0);
|
||||
}
|
||||
|
||||
int32_t cBitStream::getSeGolomb()
|
||||
int32_t cFemonBitStream::GetSeGolomb()
|
||||
{
|
||||
uint32_t r = getUeGolomb() + 1;
|
||||
uint32_t r = GetUeGolomb() + 1;
|
||||
|
||||
return ((r & 1) ? -(r >> 1) : (r >> 1));
|
||||
}
|
||||
|
||||
void cBitStream::skipGolomb()
|
||||
void cFemonBitStream::SkipGolomb()
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
while (!getBit() && (n < 32))
|
||||
while (!GetBit() && (n < 32))
|
||||
n++;
|
||||
|
||||
skipBits(n);
|
||||
}
|
||||
|
||||
void cBitStream::skipUeGolomb()
|
||||
{
|
||||
skipGolomb();
|
||||
}
|
||||
|
||||
void cBitStream::skipSeGolomb()
|
||||
{
|
||||
skipGolomb();
|
||||
}
|
||||
|
||||
void cBitStream::byteAlign()
|
||||
{
|
||||
int n = index % 8;
|
||||
|
||||
if (n > 0)
|
||||
skipBits(8 - n);
|
||||
SkipBits(n);
|
||||
}
|
||||
|
49
femontools.h
49
femontools.h
@ -71,35 +71,32 @@ cString getVideoBitrate(double value, double stream);
|
||||
cString getBitrateMbits(double value);
|
||||
cString getBitrateKbits(double value);
|
||||
|
||||
class cBitStream {
|
||||
class cFemonBitStream {
|
||||
private:
|
||||
const uint8_t *data;
|
||||
int count; // in bits
|
||||
int index; // in bits
|
||||
|
||||
int length; // in bits
|
||||
int index; // in bits
|
||||
public:
|
||||
cBitStream(const uint8_t *buf, const int len);
|
||||
~cBitStream();
|
||||
cFemonBitStream(const uint8_t *Data, int Length) : data(Data), length(Length), index(0) {}
|
||||
~cFemonBitStream() {}
|
||||
int GetBit(void);
|
||||
uint32_t GetBits(int n);
|
||||
void ByteAlign(void);
|
||||
void WordAlign(void);
|
||||
bool SetLength(int Length);
|
||||
void SkipBits(int n) { index += n; }
|
||||
void SkipBit(void) { SkipBits(1); }
|
||||
bool IsEOF(void) const { return index >= length; }
|
||||
void Reset(void) { index = 0; }
|
||||
int Length(void) const { return length; }
|
||||
int Index(void) const { return (IsEOF() ? length : index); }
|
||||
const uint8_t *GetData(void) const { return (IsEOF() ? NULL : data + (index / 8)); }
|
||||
|
||||
int getBit();
|
||||
uint32_t getBits(uint32_t n);
|
||||
void skipBits(uint32_t n);
|
||||
uint32_t getUeGolomb();
|
||||
int32_t getSeGolomb();
|
||||
void skipGolomb();
|
||||
void skipUeGolomb();
|
||||
void skipSeGolomb();
|
||||
void byteAlign();
|
||||
|
||||
void skipBit() { skipBits(1); }
|
||||
uint32_t getU8() { return getBits(8); }
|
||||
uint32_t getU16() { return ((getBits(8) << 8) | getBits(8)); }
|
||||
uint32_t getU24() { return ((getBits(8) << 16) | (getBits(8) << 8) | getBits(8)); }
|
||||
uint32_t getU32() { return ((getBits(8) << 24) | (getBits(8) << 16) | (getBits(8) << 8) | getBits(8)); }
|
||||
bool isEOF() { return (index >= count); }
|
||||
void reset() { index = 0; }
|
||||
int getIndex() { return (isEOF() ? count : index); }
|
||||
const uint8_t *getData() { return (isEOF() ? NULL : data + (index / 8)); }
|
||||
};
|
||||
uint32_t GetUeGolomb();
|
||||
int32_t GetSeGolomb();
|
||||
void SkipGolomb();
|
||||
void SkipUeGolomb() { SkipGolomb(); }
|
||||
void SkipSeGolomb() { SkipGolomb(); }
|
||||
};
|
||||
|
||||
#endif // __FEMONTOOLS_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user