mirror of
https://github.com/rofafor/vdr-plugin-femon.git
synced 2023-10-10 13:36:53 +02:00
Fixed H.264 bitstream parser.
Added a mutex to receiver class.
This commit is contained in:
parent
453ca7a2a5
commit
e57b36a151
5
HISTORY
5
HISTORY
@ -370,3 +370,8 @@ VDR Plugin 'femon' Revision History
|
||||
- Removed OSD offset and height options.
|
||||
- Added PES assembler.
|
||||
- Added bitstream parsers for all codecs.
|
||||
|
||||
2009-xx-xx: Version 1.7.4
|
||||
|
||||
- Fixed H.264 bitstream parser.
|
||||
- Added a mutex to receiver class.
|
||||
|
2
femon.c
2
femon.c
@ -18,7 +18,7 @@
|
||||
#error "VDR-1.7.0 API version or greater is required!"
|
||||
#endif
|
||||
|
||||
static const char VERSION[] = "1.7.3";
|
||||
static const char VERSION[] = "1.7.4";
|
||||
static const char DESCRIPTION[] = trNOOP("DVB Signal Information Monitor (OSD)");
|
||||
static const char MAINMENUENTRY[] = trNOOP("Signal Information");
|
||||
|
||||
|
347
femonh264.c
347
femonh264.c
@ -58,6 +58,8 @@ cFemonH264::cFemonH264(cFemonVideoIf *videohandler)
|
||||
m_Scan(VIDEO_SCAN_INVALID),
|
||||
m_CpbDpbDelaysPresentFlag(false),
|
||||
m_PicStructPresentFlag(false),
|
||||
m_FrameMbsOnlyFlag(false),
|
||||
m_MbAdaptiveFrameFieldFlag(false),
|
||||
m_TimeOffsetLength(0)
|
||||
{
|
||||
reset();
|
||||
@ -117,7 +119,7 @@ bool cFemonH264::processVideo(const uint8_t *buf, int len)
|
||||
sps_found = true;
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
|
||||
case NAL_SEI:
|
||||
if (!sei_found) {
|
||||
//Dprintf("H.264: Found NAL SEI at offset %d/%d", buf - start, len);
|
||||
@ -127,7 +129,7 @@ bool cFemonH264::processVideo(const uint8_t *buf, int len)
|
||||
sei_found = true;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -141,15 +143,15 @@ bool cFemonH264::processVideo(const uint8_t *buf, int len)
|
||||
if (aud_found) {
|
||||
m_VideoHandler->SetVideoCodec(VIDEO_CODEC_H264);
|
||||
if (sps_found) {
|
||||
//Dprintf("H.264 SPS: -> video size %dx%d, aspect %d format %d", m_Width, m_Height, m_AspectRatio, m_Format);
|
||||
//Dprintf("H.264 SPS: size %dx%d, aspect %d format %d framerate %.2f bitrate %.3f", m_Width, m_Height, m_AspectRatio, m_Format, m_FrameRate, m_BitRate);
|
||||
m_VideoHandler->SetVideoFormat(m_Format);
|
||||
m_VideoHandler->SetVideoSize(m_Width, m_Height);
|
||||
m_VideoHandler->SetVideoAspectRatio(m_AspectRatio);
|
||||
}
|
||||
if (sei_found) {
|
||||
//Dprintf("H.264 SEI: -> stream bitrate %.1f, frame rate %.1f scan %d", m_BitRate, m_FrameRate, m_Scan);
|
||||
m_VideoHandler->SetVideoFramerate(m_FrameRate);
|
||||
m_VideoHandler->SetVideoBitrate(m_BitRate);
|
||||
}
|
||||
if (sei_found) {
|
||||
//Dprintf("H.264 SEI: scan %d", m_Scan);
|
||||
m_VideoHandler->SetVideoScan(m_Scan);
|
||||
}
|
||||
}
|
||||
@ -161,6 +163,8 @@ void cFemonH264::reset()
|
||||
{
|
||||
m_CpbDpbDelaysPresentFlag = false;
|
||||
m_PicStructPresentFlag = false;
|
||||
m_FrameMbsOnlyFlag = false;
|
||||
m_MbAdaptiveFrameFieldFlag = false;
|
||||
m_TimeOffsetLength = 0;
|
||||
}
|
||||
|
||||
@ -197,26 +201,241 @@ int cFemonH264::nalUnescape(uint8_t *dst, const uint8_t *src, int len)
|
||||
|
||||
int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
{
|
||||
int profile_idc, pic_order_cnt_type, frame_mbs_only_flag, i, j;
|
||||
int profile_idc, level_idc, constraint_set3_flag, pic_order_cnt_type, i, j;
|
||||
cBitStream bs(buf, len);
|
||||
|
||||
unsigned int width = m_Width;
|
||||
unsigned int height = m_Height;
|
||||
uint32_t width = m_Width;
|
||||
uint32_t height = m_Height;
|
||||
eVideoAspectRatio aspect_ratio = m_AspectRatio;
|
||||
eVideoFormat format = m_Format;
|
||||
double frame_rate = m_FrameRate;
|
||||
double bit_rate = m_BitRate;
|
||||
bool cpb_dpb_delays_present_flag = m_CpbDpbDelaysPresentFlag;
|
||||
bool pic_struct_present_flag = m_PicStructPresentFlag;
|
||||
unsigned int time_offset_length = m_TimeOffsetLength;
|
||||
bool frame_mbs_only_flag = m_FrameMbsOnlyFlag;
|
||||
bool mb_adaptive_frame_field_flag = m_MbAdaptiveFrameFieldFlag;
|
||||
uint32_t time_offset_length = m_TimeOffsetLength;
|
||||
|
||||
profile_idc = bs.getU8(); // profile_idc
|
||||
//Dprintf("H.264 SPS: profile_idc %d", profile_idc);
|
||||
bs.skipBit(); // constraint_set0_flag
|
||||
bs.skipBit(); // constraint_set1_flag
|
||||
bs.skipBit(); // constraint_set2_flag
|
||||
bs.skipBit(); // constraint_set3_flag
|
||||
constraint_set3_flag = bs.getBit(); // constraint_set3_flag
|
||||
bs.skipBits(4); // reserved_zero_4bits
|
||||
bs.skipBits(8); // level_idc
|
||||
level_idc = bs.getU8(); // level_idc
|
||||
bs.skipUeGolomb(); // seq_parameter_set_id
|
||||
//Dprintf("H.264 SPS: profile_idc %d level_idc %d", profile_idc, level_idc);
|
||||
switch (profile_idc) {
|
||||
case 66: // baseline profile
|
||||
case 77: // main profile
|
||||
case 88: // extended profile
|
||||
switch (level_idc) {
|
||||
case 10: // level 1.0
|
||||
bit_rate = 0.064;
|
||||
break;
|
||||
case 11: // level 1b / 1.1
|
||||
bit_rate = constraint_set3_flag ? 0.128 : 0.192;
|
||||
break;
|
||||
case 12: // level 1.2
|
||||
bit_rate = 0.384;
|
||||
break;
|
||||
case 13: // level 1.3
|
||||
bit_rate = 0.768;
|
||||
break;
|
||||
case 20: // level 2.0
|
||||
bit_rate = 2;
|
||||
break;
|
||||
case 21: // level 2.1
|
||||
bit_rate = 4;
|
||||
break;
|
||||
case 22: // level 2.2
|
||||
bit_rate = 4;
|
||||
break;
|
||||
case 30: // level 3.0
|
||||
bit_rate = 10;
|
||||
break;
|
||||
case 31: // level 3.1
|
||||
bit_rate = 14;
|
||||
break;
|
||||
case 32: // level 3.2
|
||||
bit_rate = 20;
|
||||
break;
|
||||
case 40: // level 4.0
|
||||
bit_rate = 20;
|
||||
break;
|
||||
case 41: // level 4.1
|
||||
bit_rate = 50;
|
||||
break;
|
||||
case 42: // level 4.2
|
||||
bit_rate = 50;
|
||||
break;
|
||||
case 50: // level 5.0
|
||||
bit_rate = 135;
|
||||
break;
|
||||
case 51: // level 5.1
|
||||
bit_rate = 240;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 100: // high profile
|
||||
switch (level_idc) {
|
||||
case 10: // level 1.0
|
||||
bit_rate = 0.080;
|
||||
break;
|
||||
case 11: // level 1b / 1.1
|
||||
bit_rate = constraint_set3_flag ? 0.160 : 0.240;
|
||||
break;
|
||||
case 12: // level 1.2
|
||||
bit_rate = 0.480;
|
||||
break;
|
||||
case 13: // level 1.3
|
||||
bit_rate = 0.960;
|
||||
break;
|
||||
case 20: // level 2.0
|
||||
bit_rate = 2.5;
|
||||
break;
|
||||
case 21: // level 2.1
|
||||
bit_rate = 5;
|
||||
break;
|
||||
case 22: // level 2.2
|
||||
bit_rate = 5;
|
||||
break;
|
||||
case 30: // level 3.0
|
||||
bit_rate = 12.5;
|
||||
break;
|
||||
case 31: // level 3.1
|
||||
bit_rate = 17.5;
|
||||
break;
|
||||
case 32: // level 3.2
|
||||
bit_rate = 25;
|
||||
break;
|
||||
case 40: // level 4.0
|
||||
bit_rate = 25;
|
||||
break;
|
||||
case 41: // level 4.1
|
||||
bit_rate = 62.5;
|
||||
break;
|
||||
case 42: // level 4.2
|
||||
bit_rate = 62.5;
|
||||
break;
|
||||
case 50: // level 5.0
|
||||
bit_rate = 168.75;
|
||||
break;
|
||||
case 51: // level 5.1
|
||||
bit_rate = 300;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 110: // high 10 profile
|
||||
switch (level_idc) {
|
||||
case 10: // level 1.0
|
||||
bit_rate = 0.192;
|
||||
break;
|
||||
case 11: // level 1b / 1.1
|
||||
bit_rate = constraint_set3_flag ? 0.384 : 0.576;
|
||||
break;
|
||||
case 12: // level 1.2
|
||||
bit_rate = 0.1152;
|
||||
break;
|
||||
case 13: // level 1.3
|
||||
bit_rate = 2.304;
|
||||
break;
|
||||
case 20: // level 2.0
|
||||
bit_rate = 6;
|
||||
break;
|
||||
case 21: // level 2.1
|
||||
bit_rate = 12;
|
||||
break;
|
||||
case 22: // level 2.2
|
||||
bit_rate = 12;
|
||||
break;
|
||||
case 30: // level 3.0
|
||||
bit_rate = 30;
|
||||
break;
|
||||
case 31: // level 3.1
|
||||
bit_rate = 42;
|
||||
break;
|
||||
case 32: // level 3.2
|
||||
bit_rate = 60;
|
||||
break;
|
||||
case 40: // level 4.0
|
||||
bit_rate = 60;
|
||||
break;
|
||||
case 41: // level 4.1
|
||||
bit_rate = 150;
|
||||
break;
|
||||
case 42: // level 4.2
|
||||
bit_rate = 150;
|
||||
break;
|
||||
case 50: // level 5.0
|
||||
bit_rate = 405;
|
||||
break;
|
||||
case 51: // level 5.1
|
||||
bit_rate = 720;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 122: // high 4:2:2 profile
|
||||
case 144: // high 4:4:4 profile
|
||||
switch (level_idc) {
|
||||
case 10: // level 1.0
|
||||
bit_rate = 0.256;
|
||||
break;
|
||||
case 11: // level 1b / 1.1
|
||||
bit_rate = constraint_set3_flag ? 0.512 : 0.768;
|
||||
break;
|
||||
case 12: // level 1.2
|
||||
bit_rate = 1.536;
|
||||
break;
|
||||
case 13: // level 1.3
|
||||
bit_rate = 3.072;
|
||||
break;
|
||||
case 20: // level 2.0
|
||||
bit_rate = 8;
|
||||
break;
|
||||
case 21: // level 2.1
|
||||
bit_rate = 16;
|
||||
break;
|
||||
case 22: // level 2.2
|
||||
bit_rate = 16;
|
||||
break;
|
||||
case 30: // level 3.0
|
||||
bit_rate = 40;
|
||||
break;
|
||||
case 31: // level 3.1
|
||||
bit_rate = 56;
|
||||
break;
|
||||
case 32: // level 3.2
|
||||
bit_rate = 80;
|
||||
break;
|
||||
case 40: // level 4.0
|
||||
bit_rate = 80;
|
||||
break;
|
||||
case 41: // level 4.1
|
||||
bit_rate = 200;
|
||||
break;
|
||||
case 42: // level 4.2
|
||||
bit_rate = 200;
|
||||
break;
|
||||
case 50: // level 5.0
|
||||
bit_rate = 540;
|
||||
break;
|
||||
case 51: // level 5.1
|
||||
bit_rate = 960;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
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
|
||||
@ -257,9 +476,9 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
//Dprintf("H.264 SPS: pic_height: %u mbs", height);
|
||||
//Dprintf("H.264 SPS: frame only flag: %d", frame_mbs_only_flag);
|
||||
width *= 16;
|
||||
height *= 16 * (2 - frame_mbs_only_flag);
|
||||
height *= 16 * (frame_mbs_only_flag ? 1 : 2);
|
||||
if (!frame_mbs_only_flag)
|
||||
bs.skipBit(); // mb_adaptive_frame_field_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;
|
||||
@ -288,7 +507,7 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
}
|
||||
else if (aspect_ratio_idc < sizeof(s_AspectRatios) / sizeof(s_AspectRatios[0])) {
|
||||
aspect_ratio = s_AspectRatios[aspect_ratio_idc];
|
||||
//Dprintf("H.264 SPS: -> aspect ratio %d", aspect_ratio);
|
||||
//Dprintf("H.264 SPS: aspect ratio %d", aspect_ratio);
|
||||
}
|
||||
}
|
||||
if (bs.getBit()) // overscan_info_present_flag
|
||||
@ -298,7 +517,7 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
video_format = bs.getBits(3); // video_format
|
||||
if (video_format < sizeof(s_VideoFormats) / sizeof(s_VideoFormats[0])) {
|
||||
format = s_VideoFormats[video_format];
|
||||
//Dprintf("H.264 SPS: -> video format %d", format);
|
||||
//Dprintf("H.264 SPS: video format %d", format);
|
||||
}
|
||||
bs.skipBit(); // video_full_range_flag
|
||||
if (bs.getBit()) { // colour_description_present_flag
|
||||
@ -315,7 +534,8 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
uint32_t num_units_in_tick, time_scale;
|
||||
num_units_in_tick = bs.getU32(); // num_units_in_tick
|
||||
time_scale = bs.getU32(); // time_scale
|
||||
//Dprintf("H.264 SPS: -> num_units_in_tick %d, time_scale %d", num_units_in_tick, time_scale);
|
||||
if (num_units_in_tick > 0)
|
||||
frame_rate = time_scale / num_units_in_tick;
|
||||
bs.skipBit(); // fixed_frame_rate_flag
|
||||
}
|
||||
int nal_hrd_parameters_present_flag = bs.getBit(); // nal_hrd_parameters_present_flag
|
||||
@ -337,18 +557,18 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
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)
|
||||
@ -369,8 +589,12 @@ int cFemonH264::parseSPS(const uint8_t *buf, int len)
|
||||
m_Height = height;
|
||||
m_AspectRatio = aspect_ratio;
|
||||
m_Format = format;
|
||||
m_FrameRate = frame_rate;
|
||||
m_BitRate = bit_rate;
|
||||
m_CpbDpbDelaysPresentFlag = cpb_dpb_delays_present_flag;
|
||||
m_PicStructPresentFlag = pic_struct_present_flag;
|
||||
m_FrameMbsOnlyFlag = frame_mbs_only_flag;
|
||||
m_MbAdaptiveFrameFieldFlag = mb_adaptive_frame_field_flag;
|
||||
m_TimeOffsetLength = time_offset_length;
|
||||
|
||||
return (bs.getIndex() / 8);
|
||||
@ -381,24 +605,20 @@ int cFemonH264::parseSEI(const uint8_t *buf, int len)
|
||||
int num_referenced_subseqs, i;
|
||||
cBitStream bs(buf, len);
|
||||
|
||||
double frame_rate = m_FrameRate;
|
||||
double bit_rate = m_BitRate;
|
||||
eVideoScan scan = m_Scan;
|
||||
|
||||
while ((bs.getIndex() * 8 + 16) < len) { // sei_message
|
||||
int lastByte, payloadSize = 0, payloadType = 0;
|
||||
|
||||
// last_payload_type_byte
|
||||
do {
|
||||
lastByte = bs.getU8() & 0xFF;
|
||||
payloadType += lastByte;
|
||||
} while (lastByte == 0xFF);
|
||||
} while (lastByte == 0xFF); // last_payload_type_byte
|
||||
|
||||
// last_payload_size_byte
|
||||
do {
|
||||
lastByte = bs.getU8() & 0xFF;
|
||||
payloadSize += lastByte;
|
||||
} while (lastByte == 0xFF);
|
||||
} while (lastByte == 0xFF); // last_payload_size_byte
|
||||
|
||||
switch (payloadType) { // sei_payload
|
||||
case 1: // pic_timing
|
||||
@ -406,10 +626,34 @@ int cFemonH264::parseSEI(const uint8_t *buf, int len)
|
||||
bs.skipUeGolomb(); // cpb_removal_delay
|
||||
bs.skipUeGolomb(); // dpb_output_delay
|
||||
}
|
||||
if (m_PicStructPresentFlag) { // pic_struct_present_flag
|
||||
uint32_t pic_struct = bs.getBits(4); // pic_struct
|
||||
if (m_PicStructPresentFlag) { // pic_struct_present_flag
|
||||
uint32_t 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)
|
||||
scan = VIDEO_SCAN_PROGRESSIVE;
|
||||
else {
|
||||
switch (pic_struct) {
|
||||
case 0: // frame
|
||||
case 7: // frame doubling
|
||||
case 8: // frame tripling
|
||||
scan = VIDEO_SCAN_PROGRESSIVE;
|
||||
break;
|
||||
case 1: // top
|
||||
case 2: // bottom
|
||||
case 3: // top bottom
|
||||
case 4: // bottom top
|
||||
case 5: // top bottom top
|
||||
case 6: // bottom top bottom
|
||||
scan = VIDEO_SCAN_INTERLACED;
|
||||
break;
|
||||
default:
|
||||
scan = VIDEO_SCAN_RESERVED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Dprintf("H.264 SEI: pic struct %d scan type %d", pic_struct, scan);
|
||||
for (int i = 0; i < s_SeiNumClockTsTable[pic_struct]; ++i) {
|
||||
if (bs.getBit()) { // clock_timestamp_flag[i]
|
||||
int full_timestamp_flag;
|
||||
@ -427,7 +671,7 @@ int cFemonH264::parseSEI(const uint8_t *buf, int len)
|
||||
scan = VIDEO_SCAN_RESERVED;
|
||||
break;
|
||||
}
|
||||
//Dprintf("\nH.264 SEI: -> scan type %d", scan);
|
||||
//Dprintf("H.264 SEI: scan type %d", scan);
|
||||
bs.skipBit(); // nuit_field_based_flag
|
||||
bs.skipBits(5); // counting_type
|
||||
full_timestamp_flag = bs.getBit(); // full_timestamp_flag
|
||||
@ -456,22 +700,21 @@ int cFemonH264::parseSEI(const uint8_t *buf, int len)
|
||||
}
|
||||
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
|
||||
bit_rate = bs.getU16() / 1048.51; // average_bit_rate (1000 bit/s -> Mbit/s)
|
||||
frame_rate = bs.getU16() / 256.0; // average_frame_rate (frames/256s)
|
||||
//Dprintf("\nH.264 SEI: -> stream bitrate %.1f, frame rate %.1f", bit_rate, frame_rate);
|
||||
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)
|
||||
}
|
||||
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;
|
||||
|
||||
@ -484,8 +727,6 @@ int cFemonH264::parseSEI(const uint8_t *buf, int len)
|
||||
bs.byteAlign();
|
||||
}
|
||||
|
||||
m_FrameRate = frame_rate;
|
||||
m_BitRate = bit_rate;
|
||||
m_Scan = scan;
|
||||
|
||||
return (bs.getIndex() / 8);
|
||||
|
@ -20,8 +20,8 @@ private:
|
||||
};
|
||||
|
||||
cFemonVideoIf *m_VideoHandler;
|
||||
unsigned int m_Width;
|
||||
unsigned int m_Height;
|
||||
uint32_t m_Width;
|
||||
uint32_t m_Height;
|
||||
eVideoAspectRatio m_AspectRatio;
|
||||
eVideoFormat m_Format;
|
||||
double m_FrameRate;
|
||||
@ -29,7 +29,9 @@ private:
|
||||
eVideoScan m_Scan;
|
||||
bool m_CpbDpbDelaysPresentFlag;
|
||||
bool m_PicStructPresentFlag;
|
||||
unsigned int m_TimeOffsetLength;
|
||||
bool m_FrameMbsOnlyFlag;
|
||||
bool m_MbAdaptiveFrameFieldFlag;
|
||||
uint32_t m_TimeOffsetLength;
|
||||
|
||||
void reset();
|
||||
const uint8_t *nextStartCode(const uint8_t *start, const uint8_t *end);
|
||||
|
@ -13,6 +13,7 @@
|
||||
cFemonReceiver::cFemonReceiver(tChannelID ChannelID, int Ca, int Vtype, int Vpid, int Apid[], int Dpid[])
|
||||
: cReceiver(ChannelID, -1, Vpid, Apid, Dpid, NULL),
|
||||
cThread("femon receiver"),
|
||||
m_Mutex(),
|
||||
m_Sleep(),
|
||||
m_Active(false),
|
||||
m_DetectH264(this),
|
||||
|
150
femonreceiver.h
150
femonreceiver.h
@ -21,6 +21,7 @@
|
||||
|
||||
class cFemonReceiver : public cReceiver, public cThread, public cFemonVideoIf, public cFemonAudioIf, public cFemonAC3If {
|
||||
private:
|
||||
cMutex m_Mutex;
|
||||
cCondWait m_Sleep;
|
||||
bool m_Active;
|
||||
|
||||
@ -57,66 +58,115 @@ protected:
|
||||
virtual void Action(void);
|
||||
|
||||
public:
|
||||
virtual void SetVideoCodec(eVideoCodec codec) { m_VideoInfo.codec = codec; }
|
||||
virtual void SetVideoFormat(eVideoFormat format) { m_VideoInfo.format = format; }
|
||||
virtual void SetVideoScan(eVideoScan scan) { m_VideoInfo.scan = scan; }
|
||||
virtual void SetVideoAspectRatio(eVideoAspectRatio aspectratio) { m_VideoInfo.aspectRatio = aspectratio; }
|
||||
virtual void SetVideoSize(int width, int height) { m_VideoInfo.width = width;
|
||||
m_VideoInfo.height = height; }
|
||||
virtual void SetVideoFramerate(double framerate) { m_VideoInfo.frameRate = framerate; }
|
||||
virtual void SetVideoBitrate(double bitrate) { m_VideoInfo.bitrate = bitrate; }
|
||||
virtual void SetVideoCodec(eVideoCodec codec) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_VideoInfo.codec = codec; }
|
||||
virtual void SetVideoFormat(eVideoFormat format) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_VideoInfo.format = format; }
|
||||
virtual void SetVideoScan(eVideoScan scan) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_VideoInfo.scan = scan; }
|
||||
virtual void SetVideoAspectRatio(eVideoAspectRatio aspectratio) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_VideoInfo.aspectRatio = aspectratio; }
|
||||
virtual void SetVideoSize(int width, int height) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_VideoInfo.width = width;
|
||||
m_VideoInfo.height = height; }
|
||||
virtual void SetVideoFramerate(double framerate) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_VideoInfo.frameRate = framerate; }
|
||||
virtual void SetVideoBitrate(double bitrate) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_VideoInfo.bitrate = bitrate; }
|
||||
|
||||
virtual void SetAudioCodec(eAudioCodec codec) { m_AudioInfo.codec = codec; }
|
||||
virtual void SetAudioBitrate(double bitrate) { m_AudioInfo.bitrate = bitrate; }
|
||||
virtual void SetAudioSamplingFrequency(int sampling) { m_AudioInfo.samplingFrequency = sampling; }
|
||||
virtual void SetAudioChannel(eAudioChannelMode mode) { m_AudioInfo.channelMode = mode; }
|
||||
virtual void SetAudioCodec(eAudioCodec codec) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AudioInfo.codec = codec; }
|
||||
virtual void SetAudioBitrate(double bitrate) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AudioInfo.bitrate = bitrate; }
|
||||
virtual void SetAudioSamplingFrequency(int sampling) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AudioInfo.samplingFrequency = sampling; }
|
||||
virtual void SetAudioChannel(eAudioChannelMode mode) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AudioInfo.channelMode = mode; }
|
||||
|
||||
virtual void SetAC3Bitrate(int bitrate) { m_AC3Info.bitrate = bitrate; }
|
||||
virtual void SetAC3SamplingFrequency(int sampling) { m_AC3Info.samplingFrequency = sampling; }
|
||||
virtual void SetAC3Bitstream(int mode) { m_AC3Info.bitstreamMode = mode; }
|
||||
virtual void SetAC3AudioCoding(int mode) { m_AC3Info.audioCodingMode = mode; }
|
||||
virtual void SetAC3DolbySurround(int mode) { m_AC3Info.dolbySurroundMode = mode; }
|
||||
virtual void SetAC3CenterMix(int level) { m_AC3Info.centerMixLevel = level; }
|
||||
virtual void SetAC3SurroundMix(int level) { m_AC3Info.surroundMixLevel = level; }
|
||||
virtual void SetAC3Dialog(int level) { m_AC3Info.dialogLevel = level; }
|
||||
virtual void SetAC3LFE(bool onoff) { m_AC3Info.lfe = onoff; }
|
||||
virtual void SetAC3Bitrate(int bitrate) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AC3Info.bitrate = bitrate; }
|
||||
virtual void SetAC3SamplingFrequency(int sampling) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AC3Info.samplingFrequency = sampling; }
|
||||
virtual void SetAC3Bitstream(int mode) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AC3Info.bitstreamMode = mode; }
|
||||
virtual void SetAC3AudioCoding(int mode) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AC3Info.audioCodingMode = mode; }
|
||||
virtual void SetAC3DolbySurround(int mode) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AC3Info.dolbySurroundMode = mode; }
|
||||
virtual void SetAC3CenterMix(int level) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AC3Info.centerMixLevel = level; }
|
||||
virtual void SetAC3SurroundMix(int level) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AC3Info.surroundMixLevel = level; }
|
||||
virtual void SetAC3Dialog(int level) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AC3Info.dialogLevel = level; }
|
||||
virtual void SetAC3LFE(bool onoff) { cMutexLock MutexLock(&m_Mutex);
|
||||
m_AC3Info.lfe = onoff; }
|
||||
|
||||
public:
|
||||
cFemonReceiver(tChannelID ChannelID, int Ca, int Vtype, int Vpid, int Apid[], int Dpid[]);
|
||||
virtual ~cFemonReceiver();
|
||||
void Deactivate(void);
|
||||
|
||||
bool VideoValid(void) { return m_VideoValid; }; // boolean
|
||||
double VideoBitrate(void) { return m_VideoBitrate; }; // bit/s
|
||||
int VideoCodec(void) { return m_VideoInfo.codec; }; // eVideoCodec
|
||||
int VideoFormat(void) { return m_VideoInfo.format; }; // eVideoFormat
|
||||
int VideoScan(void) { return m_VideoInfo.scan; }; // eVideoScan
|
||||
int VideoAspectRatio(void) { return m_VideoInfo.aspectRatio; }; // eVideoAspectRatio
|
||||
int VideoHorizontalSize(void) { return m_VideoInfo.width; }; // pixels
|
||||
int VideoVerticalSize(void) { return m_VideoInfo.height; }; // pixels
|
||||
double VideoFrameRate(void) { return m_VideoInfo.frameRate; }; // Hz
|
||||
double VideoStreamBitrate(void) { return m_VideoInfo.bitrate; }; // bit/s
|
||||
bool VideoValid(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_VideoValid; }; // boolean
|
||||
double VideoBitrate(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_VideoBitrate; }; // bit/s
|
||||
int VideoCodec(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_VideoInfo.codec; }; // eVideoCodec
|
||||
int VideoFormat(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_VideoInfo.format; }; // eVideoFormat
|
||||
int VideoScan(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_VideoInfo.scan; }; // eVideoScan
|
||||
int VideoAspectRatio(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_VideoInfo.aspectRatio; }; // eVideoAspectRatio
|
||||
int VideoHorizontalSize(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_VideoInfo.width; }; // pixels
|
||||
int VideoVerticalSize(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_VideoInfo.height; }; // pixels
|
||||
double VideoFrameRate(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_VideoInfo.frameRate; }; // Hz
|
||||
double VideoStreamBitrate(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_VideoInfo.bitrate; }; // bit/s
|
||||
|
||||
bool AudioValid(void) { return m_AudioValid; }; // boolean
|
||||
double AudioBitrate(void) { return m_AudioBitrate; }; // bit/s
|
||||
int AudioCodec(void) { return m_AudioInfo.codec; }; // eAudioCodec
|
||||
int AudioChannelMode(void) { return m_AudioInfo.channelMode; }; // eAudioChannelMode
|
||||
double AudioStreamBitrate(void) { return m_AudioInfo.bitrate; }; // bit/s or eAudioBitrate
|
||||
int AudioSamplingFreq(void) { return m_AudioInfo.samplingFrequency; }; // Hz or eAudioSamplingFrequency
|
||||
bool AudioValid(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AudioValid; }; // boolean
|
||||
double AudioBitrate(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AudioBitrate; }; // bit/s
|
||||
int AudioCodec(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AudioInfo.codec; }; // eAudioCodec
|
||||
int AudioChannelMode(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AudioInfo.channelMode; }; // eAudioChannelMode
|
||||
double AudioStreamBitrate(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AudioInfo.bitrate; }; // bit/s or eAudioBitrate
|
||||
int AudioSamplingFreq(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AudioInfo.samplingFrequency; }; // Hz or eAudioSamplingFrequency
|
||||
|
||||
bool AC3Valid(void) { return m_AC3Valid; }; // boolean
|
||||
double AC3Bitrate(void) { return m_AC3Bitrate; }; // bit/s
|
||||
double AC3StreamBitrate(void) { return m_AC3Info.bitrate; }; // bit/s or eAudioBitrate
|
||||
int AC3SamplingFreq(void) { return m_AC3Info.samplingFrequency; }; // Hz or eAudioSamplingFrequency
|
||||
int AC3BitStreamMode(void) { return m_AC3Info.bitstreamMode; }; // 0..7 or eAudioBitstreamMode
|
||||
int AC3AudioCodingMode(void) { return m_AC3Info.audioCodingMode; }; // 0..7 or eAudioCodingMode
|
||||
bool AC3_2_0(void) { return (m_AC3Info.audioCodingMode == AUDIO_CODING_MODE_2_0); }; // boolean
|
||||
bool AC3_5_1(void) { return (m_AC3Info.audioCodingMode == AUDIO_CODING_MODE_3_2); }; // boolean
|
||||
int AC3DolbySurroundMode(void) { return m_AC3Info.dolbySurroundMode; }; // eAudioDolbySurroundMode
|
||||
int AC3CenterMixLevel(void) { return m_AC3Info.centerMixLevel; }; // eAudioCenterMixLevel
|
||||
int AC3SurroundMixLevel(void) { return m_AC3Info.surroundMixLevel; }; // eAudioSurroundMixLevel
|
||||
int AC3DialogLevel(void) { return m_AC3Info.dialogLevel; }; // -dB
|
||||
bool AC3Lfe(void) { return m_AC3Info.lfe; }; // boolean
|
||||
bool AC3Valid(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AC3Valid; }; // boolean
|
||||
double AC3Bitrate(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AC3Bitrate; }; // bit/s
|
||||
double AC3StreamBitrate(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AC3Info.bitrate; }; // bit/s or eAudioBitrate
|
||||
int AC3SamplingFreq(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AC3Info.samplingFrequency; }; // Hz or eAudioSamplingFrequency
|
||||
int AC3BitStreamMode(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AC3Info.bitstreamMode; }; // 0..7 or eAudioBitstreamMode
|
||||
int AC3AudioCodingMode(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AC3Info.audioCodingMode; }; // 0..7 or eAudioCodingMode
|
||||
bool AC3_2_0(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return (m_AC3Info.audioCodingMode == AUDIO_CODING_MODE_2_0); }; // boolean
|
||||
bool AC3_5_1(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return (m_AC3Info.audioCodingMode == AUDIO_CODING_MODE_3_2); }; // boolean
|
||||
int AC3DolbySurroundMode(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AC3Info.dolbySurroundMode; }; // eAudioDolbySurroundMode
|
||||
int AC3CenterMixLevel(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AC3Info.centerMixLevel; }; // eAudioCenterMixLevel
|
||||
int AC3SurroundMixLevel(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AC3Info.surroundMixLevel; }; // eAudioSurroundMixLevel
|
||||
int AC3DialogLevel(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AC3Info.dialogLevel; }; // -dB
|
||||
bool AC3Lfe(void) { cMutexLock MutexLock(&m_Mutex);
|
||||
return m_AC3Info.lfe; }; // boolean
|
||||
};
|
||||
|
||||
#endif //__FEMONRECEIVER_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user