📄 hdmi.c
字号:
struct DH_SPDInfoFrame *pSPDInfo){ RMascii Vendor[9], Product[17]; enum DH_source_dev_info sdi; RMuint32 i; for (i = 0; i < 8; i++) Vendor[i] = (RMascii)data[i + 1]; Vendor[8] = '\0'; for (i = 0; i < 16; i++) Product[i] = (RMascii)data[i + 9]; Product[16] = '\0'; sdi = (enum DH_source_dev_info)data[25]; RMDBGLOG((ENABLE, "[hdmi] SPD Info - Vendor: \"%s\", Product: \"%s\" - Category: %s (0x%02X)\n", Vendor, Product, (sdi == DH_source_dev_unknown) ? "unknown" : (sdi == DH_source_dev_DigitalSTB) ? "DigitalSTB" : (sdi == DH_source_dev_DVD) ? "DVD" : (sdi == DH_source_dev_DVHS) ? "DVHS" : (sdi == DH_source_dev_HDDVideo) ? "HDDVideo" : (sdi == DH_source_dev_DVC) ? "DVC" : (sdi == DH_source_dev_DSC) ? "DSC" : (sdi == DH_source_dev_VideoCD) ? "VideoCD" : (sdi == DH_source_dev_Game) ? "Game" : (sdi == DH_source_dev_PC) ? "PC" : (sdi == DH_source_dev_BluRay) ? "BluRay" : (sdi == DH_source_dev_SACD) ? "SACD" : "invalid value!", (RMuint8)sdi)); if (pSPDInfo) { pSPDInfo->Version = header[1]; if (pSPDInfo->VendorName) RMNCopyAscii(pSPDInfo->VendorName, Vendor, 9); if (pSPDInfo->ProductDescription) RMNCopyAscii(pSPDInfo->ProductDescription, Product, 17); pSPDInfo->SDI = sdi; } return RM_OK;}RMstatus cap_hdmi_parse_audio_info_frame( struct cap_hdmi_instance *pHDMI, RMuint8 *header, RMuint8 *data, struct DH_AudioInfoFrame *pAudioInfo){ struct DH_AudioInfoFrame aif; RMDBGLOG((ENABLE, "[hdmi] new Audio InfoFrame\n")); aif.Version = header[1]; aif.CodingType = (enum DH_AudioCodingType)RMunshiftBits(data[1], 4, 4); aif.ChannelCount = (enum DH_AudioChannelCount)RMunshiftBits(data[1], 3, 0); aif.SampleFrequency = (enum DH_AudioSampleFrequency)RMunshiftBits(data[2], 3, 2); aif.SampleSize = (enum DH_AudioSampleSize)RMunshiftBits(data[2], 2, 0); aif.LFE_Ch3_Enable = RMunshiftBool(data[4], 0); aif.FC_Ch4_Enable = RMunshiftBool(data[4], 1); aif.CA = (enum DH_Audio_ChannelAssignment)RMunshiftBits(data[4], 6, 2); aif.DownMixInhibit = RMunshiftBool(data[5], 7); aif.LevelShift = RMunshiftBits(data[5], 4, 3); aif.MaxBitRate = data[3]; // codec dependent RMDBGLOG((ENABLE, "[hdmi] Audio Coding Type: ")); switch (aif.CodingType) { case DH_AudioCodingType_FromStreamHeader: RMDBGPRINT((ENABLE, "Refer to stream header\n")); break; case DH_AudioCodingType_PCM: RMDBGPRINT((ENABLE, "IEC60958 PCM\n")); break; case DH_AudioCodingType_AC3: RMDBGPRINT((ENABLE, "AC-3\n")); break; case DH_AudioCodingType_MPEG1_12: RMDBGPRINT((ENABLE, "MPEG1 Layer 1/2\n")); break; case DH_AudioCodingType_MPEG1_3: RMDBGPRINT((ENABLE, "MPEG1 Layer 3\n")); break; case DH_AudioCodingType_MPEG2: RMDBGPRINT((ENABLE, "MPEG2\n")); break; case DH_AudioCodingType_AAC: RMDBGPRINT((ENABLE, "AAC\n")); break; case DH_AudioCodingType_DTS: RMDBGPRINT((ENABLE, "DTS\n")); break; case DH_AudioCodingType_ATRAC: RMDBGPRINT((ENABLE, "ATRAC\n")); break; case DH_AudioCodingType_OneBit: RMDBGPRINT((ENABLE, "One Bit Audio\n")); break; case DH_AudioCodingType_DDPlus: RMDBGPRINT((ENABLE, "Dolby Digital +\n")); break; case DH_AudioCodingType_DTSHD: RMDBGPRINT((ENABLE, "DTS-HD\n")); break; case DH_AudioCodingType_MLP: RMDBGPRINT((ENABLE, "MAT (MLP)\n")); break; case DH_AudioCodingType_DST: RMDBGPRINT((ENABLE, "DST\n")); break; case DH_AudioCodingType_WMAPro: RMDBGPRINT((ENABLE, "WMA Pro\n")); break; default: RMDBGPRINT((ENABLE, "Unknown!\n")); break; } RMDBGLOG((ENABLE, "[hdmi] Audio Channel Count: ")); switch (aif.ChannelCount) { case DH_AudioChannelCount_FromStreamHeader: RMDBGPRINT((ENABLE, "Refer to stream header\n")); break; case DH_AudioChannelCount_2: case DH_AudioChannelCount_3: case DH_AudioChannelCount_4: case DH_AudioChannelCount_5: case DH_AudioChannelCount_6: case DH_AudioChannelCount_7: case DH_AudioChannelCount_8: RMDBGPRINT((ENABLE, "%u channel\n", 2 + (aif.ChannelCount - DH_AudioChannelCount_2))); break; default: RMDBGPRINT((ENABLE, "Unknown!\n")); break; } RMDBGLOG((ENABLE, "[hdmi] Audio Sample Frequency: ")); switch (aif.SampleFrequency) { case DH_AudioSampleFrequency_FromStreamHeader: RMDBGPRINT((ENABLE, "Refer to stream header\n")); break; case DH_AudioSampleFrequency_32000: RMDBGPRINT((ENABLE, "32 kHz\n")); break; case DH_AudioSampleFrequency_44100: RMDBGPRINT((ENABLE, "44.1 kHz\n")); break; case DH_AudioSampleFrequency_48000: RMDBGPRINT((ENABLE, "48 kHz\n")); break; case DH_AudioSampleFrequency_88200: RMDBGPRINT((ENABLE, "88.2 kHz\n")); break; case DH_AudioSampleFrequency_96000: RMDBGPRINT((ENABLE, "96 kHz\n")); break; case DH_AudioSampleFrequency_176400: RMDBGPRINT((ENABLE, "176.4 kHz\n")); break; case DH_AudioSampleFrequency_192000: RMDBGPRINT((ENABLE, "192 kHz\n")); break; default: RMDBGPRINT((ENABLE, "Unknown!\n")); break; } RMDBGLOG((ENABLE, "[hdmi] Audio Sample Size: ")); switch (aif.SampleSize) { case DH_AudioSampleSize_FromStreamHeader: RMDBGPRINT((ENABLE, "Refer to stream header\n")); break; case DH_AudioSampleSize_16: RMDBGPRINT((ENABLE, "16 bit\n")); break; case DH_AudioSampleSize_20: RMDBGPRINT((ENABLE, "20 bit\n")); break; case DH_AudioSampleSize_24: RMDBGPRINT((ENABLE, "24 bit\n")); break; default: RMDBGPRINT((ENABLE, "Unknown!\n")); break; } RMDBGLOG((ENABLE, "[hdmi] Channel Assignment: ")); switch (aif.CA) { case DH_Audio_CA_none: RMDBGPRINT((ENABLE, "--- --- -- --")); break; case DH_Audio_CA_RC5: RMDBGPRINT((ENABLE, "--- --- -- RC")); break; case DH_Audio_CA_RL5_RR6: RMDBGPRINT((ENABLE, "--- --- RR RL")); break; case DH_Audio_CA_RL5_RR6_RC7: RMDBGPRINT((ENABLE, "--- RC RR RL")); break; case DH_Audio_CA_RL5_RR6_RLC7_RRC8: RMDBGPRINT((ENABLE, "RRC RLC RR RL")); break; case DH_Audio_CA_FLC7_FRC8: RMDBGPRINT((ENABLE, "FRC FLC -- --")); break; case DH_Audio_CA_RC5_FLC7_FRC8: RMDBGPRINT((ENABLE, "FRC FLC -- RC")); break; case DH_Audio_CA_RL5_RR6_FLC7_FRC8: RMDBGPRINT((ENABLE, "FRC FLC RR RL")); break; default: RMDBGPRINT((ENABLE, "XXX XXX XX XX")); break; } RMDBGPRINT((ENABLE, " %s %s FR FL\n", aif.FC_Ch4_Enable ? "FC" : "--", aif.LFE_Ch3_Enable ? "LFE" : "---")); RMDBGLOG((ENABLE, "[hdmi] Level Shift: %lu dB\n", aif.LevelShift)); RMDBGLOG((ENABLE, "[hdmi] Down Mix %s\n", aif.DownMixInhibit ? "Prohibited" : "Permitted")); if ((aif.CodingType >= DH_AudioCodingType_AC3) && (aif.CodingType <= DH_AudioCodingType_ATRAC)) { RMDBGLOG((ENABLE, "[hdmi] Maximum Bit Rate: %lu kHz\n", aif.MaxBitRate * 8)); } if (pAudioInfo) RMMemcpy(pAudioInfo, &aif, sizeof(struct DH_AudioInfoFrame)); return RM_OK;}RMstatus cap_hdmi_parse_mpeg_info_frame( struct cap_hdmi_instance *pHDMI, RMuint8 *header, RMuint8 *data, struct DH_MPEGInfoFrame *pMPEGInfo){ struct DH_MPEGInfoFrame mpeg; RMDBGLOG((ENABLE, "[hdmi] new MPEG InfoFrame\n")); mpeg.Version = header[1]; mpeg.BitRate = 0; RMinsShiftBits(&(mpeg.BitRate), data[1], 8, 0); RMinsShiftBits(&(mpeg.BitRate), data[2], 8, 8); RMinsShiftBits(&(mpeg.BitRate), data[3], 8, 16); RMinsShiftBits(&(mpeg.BitRate), data[4], 8, 24); mpeg.RepeatedField = RMunshiftBool(data[5], 4); mpeg.Frame = (enum DH_MPEG_Frame)RMunshiftBits(data[5], 2, 0); RMDBGLOG((ENABLE, "[hdmi] MPEG Bit Rate: %lu Hz\n", mpeg.BitRate)); RMDBGLOG((ENABLE, "[hdmi] %s Field\n", mpeg.RepeatedField ? "Repeated" : "New")); RMDBGLOG((ENABLE, "[hdmi] MPEG Frame: %s\n", (mpeg.Frame == DH_MPEG_Frame_unknown) ? "Unknown" : (mpeg.Frame == DH_MPEG_Frame_I) ? "I Picture" : (mpeg.Frame == DH_MPEG_Frame_B) ? "B Picture" : (mpeg.Frame == DH_MPEG_Frame_P) ? "P Picture" : "Invalid")); if (pMPEGInfo) RMMemcpy(pMPEGInfo, &mpeg, sizeof(struct DH_MPEGInfoFrame)); return RM_OK;}/*** Interrupt handling functions ***//* Returns RM_OK if cap_hdmi_handle_int() needs to be called */RMstatus cap_hdmi_check_int(struct cap_hdmi_instance *pHDMI){ // Sanity checks if (pHDMI == NULL) return RM_FATALINVALIDPOINTER; switch (pHDMI->pChip->chip) { case cap_chip_SiI9031: return cap_SiI9031_check_int(pHDMI->pChip->instance.pSiI9031); case cap_chip_AD9380: return cap_AD9380_check_int(pHDMI->pChip->instance.pAD9380); default: return RM_ERROR; }}/* check and handle interrupts and/or other changes on the chip, fill in update information to pUpdate */RMstatus cap_hdmi_handle_int( struct cap_hdmi_instance *pHDMI, struct cap_update *pUpdate){ RMstatus err; // Sanity checks if (pHDMI == NULL) return RM_FATALINVALIDPOINTER; switch (pHDMI->pChip->chip) { case cap_chip_SiI9031: err = cap_SiI9031_handle_int(pHDMI->pChip->instance.pSiI9031, pUpdate, &(pHDMI->UpdateHDMI)); break; case cap_chip_AD9380: err = cap_AD9380_handle_int(pHDMI->pChip->instance.pAD9380, pUpdate, &(pHDMI->UpdateHDMI)); break; default: err = RM_ERROR; break; } if (RMFAILED(err)) return err; if (pHDMI->UpdateHDMI.AudioCPPacketUpdate) { RMuint8 header[3], data[28]; pHDMI->UpdateHDMI.AudioCPPacketUpdate = FALSE; err = cap_hdmi_read_info_frame(pHDMI, 0x04, 0x00, header, data, sizeof(data) / sizeof(RMuint8), TRUE); if (RMFAILED(err)) return err; err = cap_hdmi_parse_audio_cp_packet(pHDMI, header, data, NULL); } if (pHDMI->UpdateHDMI.ISRC1PacketUpdate) { RMuint8 header[3], data[28]; pHDMI->UpdateHDMI.ISRC1PacketUpdate = FALSE; err = cap_hdmi_read_info_frame(pHDMI, 0x05, 0x00, header, data, sizeof(data) / sizeof(RMuint8), TRUE); if (RMFAILED(err)) return err; err = cap_hdmi_parse_isrc1_packet(pHDMI, header, data, NULL, NULL); } if (pHDMI->UpdateHDMI.ISRC2PacketUpdate) { RMuint8 header[3], data[28]; pHDMI->UpdateHDMI.ISRC2PacketUpdate = FALSE; err = cap_hdmi_read_info_frame(pHDMI, 0x06, 0x00, header, data, sizeof(data) / sizeof(RMuint8), TRUE); if (RMFAILED(err)) return err; err = cap_hdmi_parse_isrc2_packet(pHDMI, header, data, NULL, NULL); } if (pHDMI->UpdateHDMI.GamutMetadataPacketUpdate) { RMuint8 header[3], data[28]; pHDMI->UpdateHDMI.GamutMetadataPacketUpdate = FALSE; err = cap_hdmi_read_info_frame(pHDMI, 0x0A, 0x00, header, data, sizeof(data) / sizeof(RMuint8), TRUE); if (RMFAILED(err)) return err; err = cap_hdmi_parse_gamut_packet(pHDMI, header, data, NULL); } if (pHDMI->UpdateHDMI.VendorSpecificInfoFrameUpdate) { RMuint8 header[3], data[28]; pHDMI->UpdateHDMI.VendorSpecificInfoFrameUpdate = FALSE; err = cap_hdmi_read_info_frame(pHDMI, 0x81, 0x00, header, data, sizeof(data) / sizeof(RMuint8), TRUE); if (RMFAILED(err)) return err; err = cap_hdmi_parse_vendor_info_frame(pHDMI, header, data, NULL, NULL, NULL); } if (pHDMI->UpdateHDMI.AVIInfoFrameInvalidate) { pHDMI->UpdateHDMI.AVIInfoFrameInvalidate = FALSE; pHDMI->last_avi.valid = FALSE; } if (pHDMI->UpdateHDMI.AVIInfoFrameUpdate) { RMuint8 header[3], data[16]; struct cap_hdmi_avi_info avi; pHDMI->UpdateHDMI.AVIInfoFrameUpdate = FALSE; err = cap_hdmi_read_info_frame(pHDMI, 0x82, 0x00, header, data, sizeof(data) / sizeof(RMuint8), TRUE); if (RMFAILED(err)) return err; cap_hdmi_parse_avi_struct(data, &avi); err = cap_hdmi_handle_avi_info_frame(pHDMI, &avi, pUpdate); } if (pHDMI->UpdateHDMI.SPDInfoFrameUpdate) { RMuint8 header[3], data[28]; pHDMI->UpdateHDMI.SPDInfoFrameUpdate = FALSE; err = cap_hdmi_read_info_frame(pHDMI, 0x83, 0x00, header, data, sizeof(data) / sizeof(RMuint8), TRUE); if (RMFAILED(err)) return err; err = cap_hdmi_parse_spd_info_frame(pHDMI, header, data, NULL); } if (pHDMI->UpdateHDMI.AudioInfoFrameUpdate) { RMuint8 header[3], data[28]; pHDMI->UpdateHDMI.AudioInfoFrameUpdate = FALSE; err = cap_hdmi_read_info_frame(pHDMI, 0x84, 0x00, header, data, sizeof(data) / sizeof(RMuint8), TRUE); if (RMFAILED(err)) return err; err = cap_hdmi_parse_audio_info_frame(pHDMI, header, data, NULL); } if (pHDMI->UpdateHDMI.MPEGInfoFrameUpdate) { RMuint8 header[3], data[28]; pHDMI->UpdateHDMI.MPEGInfoFrameUpdate = FALSE; err = cap_hdmi_read_info_frame(pHDMI, 0x85, 0x00, header, data, sizeof(data) / sizeof(RMuint8), TRUE); if (RMFAILED(err)) return err; err = cap_hdmi_parse_mpeg_info_frame(pHDMI, header, data, NULL); } return err;}// TODO has to go into main or common/* helper function to deduct probablt picture aspect ratio from video standard */void cap_get_aspect_ratio_from_video_mode( enum EMhwlibTVStandard TVStandard, struct EMhwlibTVFormatDigital *pTVFormat, RMbool wide, // ambiguous modes (SDTV,EDTV): FALSE=4:3, TRUE=16:9 anamorphic RMuint32 *asp_x, RMuint32 *asp_y){ if (!asp_x || !asp_y) return; // determine aspect ratio from video mode switch (TVStandard) { case EMhwlibTVStandard_Custom: if (pTVFormat) { *asp_x = pTVFormat->ActiveWidth; *asp_y = pTVFormat->ActiveHeight; cap_reduce_aspect_ratio(asp_x, asp_y, 0); } else { *asp_x = 4; *asp_y = 3; } break; case EMhwlibTVStandard_HDMI_720p59: case EMhwlibTVStandard_HDMI_720p60: case EMhwlibTVStandard_HDMI_1080i59: case EMhwlibTVStandard_HDMI_1080i60: case EMhwlibTVStandard_HDMI_1080p59: case EMhwlibTVStandard_HDMI_1080p60: case EMhwlibTVStandard_HDMI_720p50: case EMhwlibTVStandard_HDMI_1080i50: case EMhwlibTVStandard_HDMI_1080p50: case EMhwlibTVStandard_HDMI_1080p23: case EMhwlibTVStandard_HDMI_1080p24: case EMhwlibTVStandard_HDMI_1080p25: case EMhwlibTVStandard_HDMI_1080p29: case EMhwlibTVStandard_HDMI_1080p30: case EMhwlibTVStandard_HDMI_1080i50_1250: case EMhwlibTVStandard_HDMI_1080i100: case EMhwlibTVStandard_HDMI_720p100: case EMhwlibTVStandard_HDMI_1080i119: case EMhwlibTVStandard_HDMI_1080i120: case EMhwlibTVStandard_HDMI_720p119: case EMhwlibTVStandard_HDMI_720p120: case EMhwlibTVStandard_1080p60: case EMhwlibTVStandard_1080p59: case EMhwlibTVStandard_1080p50: case EMhwlibTVStandard_1080i60: case EMhwlibTVStandard_1080i59: case EMhwlibTVStandard_1080i50: case EMhwlibTVStandard_1080i48: case EMhwlibTVStandard_1080i47: case EMhwlibTVStandard_1080p30: case EMhwlibTVStandard_1080p29: case EMhwlibTVStandard_1080p25: case EMhwlibTVStandard_1080p24: case EMhwlibTVStandard_1080p23: case EMhwlibTVStandard_1080i50_1250: case EMhwlibTVStandard_1080p50_1250: case EMhwlibTVStandard_720p60: case EMhwlibTVStandard_720p59: case EMhwlibTVStandard_720p50: case EMhwlibTVStandard_720p30: case EMhwlibTVStandard_720p29: case EMhwlibTVStandard_720p25: case EMhwlibTVStandard_720p24: case EMhwlibTVStandard_720p23: case EMhwlibTVStandard_VESA_1360x768x60: case EMhwlibTVStandard_VESA_1280x720x60: case EMhwlibTVStandard_VESA_1280x720x75: case EMhwlibTVStandard_VESA_1920x1080x60i: *asp_x = 16; *asp_y = 9; break; case EMhwlibTVStandard_VESA_1280x768x60RB: case EMhwlibTVStandard_VESA_1280x768x6
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -