📄 play_capture_hdmi.c
字号:
struct capsam_hdmi_instance *pHDMI, RMuint8 *avi_header, RMuint8 *avi_data, struct capsam_hdmi_avi_info *avi){ RMstatus err; struct capsam_hdmi_avi_info avi_info; RMuint8 header[3], data[16]; RMDBGLOG((FUNCNAME, "%s\n",__func__)); if ((avi_data == NULL) && (avi_header == NULL)) { if (pHDMI == NULL) return RM_FATALINVALIDPOINTER; err = capsam_hdmi_read_info_frame(pHDMI, 0x82, 0x00, header, data, sizeof(data) / sizeof(RMuint8), FALSE); if (RMSUCCEEDED(err)) { avi_data = data; avi_header = header; } else { fprintf(stderr, "Error, can not read AVI info frame from HDMI chip!\n"); return err; } } if (avi == NULL) { avi = &avi_info; capsam_hdmi_parse_avi_struct(avi_data, avi); } //fprintf(stderr, "\017"); //{RMuint32 i;for(i=32;i<256;i++){if((i&15)==0)fprintf(stderr,"%lu: ",i);fprintf(stderr,"%c",(RMascii)i);if((i&15)==15)fprintf(stderr,"\n");}} //fprintf(stderr, "\016"); //fprintf(stderr, "\033)B\033%%@"); fprintf(stderr, "+-----------------------------------------------+\n"); if (avi_header) { fprintf(stderr, "| AVI Info Frame, Type 0x%02X Version 0x%02X Len %2u |\n", avi_header[0], avi_header[1], avi_header[2]); } else { fprintf(stderr, "| AVI Info Frame |\n"); } fprintf(stderr, "+-----+-----+-----+-----+-----+-----+-----+-----+\n"); fprintf(stderr, "| %u | Y=%lu (%s) | A=%u |Bh=%u |Bv=%u |Su=%u |So=%u |\n", (avi_data[1]&0x80)?1:0, avi->color_format, (avi->color_format==0)?"RGB":(avi->color_format==1)?"422":(avi->color_format==2)?"444":"inv", (avi->active_format&0x10)?1:0, avi->h_bar?1:0, avi->v_bar?1:0, (avi->scan_info&0x02)?1:0, (avi->scan_info&0x01)?1:0); //fprintf(stderr, "+-----+-----+-----+-----+-----+-----+-----+-----+\n"); fprintf(stderr, "| C=%lu%-6s | M=%lu%-7s| R=0x%01lX (%s |\n", avi->color_space, (avi->color_space==0)?"(None)":(avi->color_space==1)?" (601)":(avi->color_space==2)?" (709)":" (Ext)", avi->aspect_ratio, (avi->aspect_ratio==0)?"(None)":(avi->aspect_ratio==1)?" (4:3)":(avi->aspect_ratio==2)?"(16:9)":"(Future", avi->active_format&0x0F, ((avi->active_format&0x0F) == DH_af_reserved_0) ? "no info) " : ((avi->active_format&0x0F) == DH_af_16x9_top) ? "16:9top) " : ((avi->active_format&0x0F) == DH_af_14x9_top) ? "14:9top) " : ((avi->active_format&0x0F) == DH_af_64x27_centered) ? "64:27) " : ((avi->active_format&0x0F) == DH_af_same_as_picture) ? "same) " : ((avi->active_format&0x0F) == DH_af_4x3_centered) ? "4:3) " : ((avi->active_format&0x0F) == DH_af_16x9_centered) ? "16:9) " : ((avi->active_format&0x0F) == DH_af_14x9_centered) ? "14:9) " : ((avi->active_format&0x0F) == DH_af_4x3_centered_prot_14x9) ? "4:3/14:9) " : ((avi->active_format&0x0F) == DH_af_16x9_centered_prot_14x9) ? "16:9/14:9)" : ((avi->active_format&0x0F) == DH_af_16x9_centered_prot_4x3) ? "16:9/4:3) " : "unknown) "); //fprintf(stderr, "+-----+-----+-----+-----+-----+-----+-----+-----+\n"); fprintf(stderr, "|ITC=%u| EC=%lu (%s) | Q=%lu (%s) |SCv=%u|SCh=%u|\n", avi->it_content?1:0, avi->ext_col, (avi->ext_col==0)?"xv601":(avi->ext_col==1)?"xv709":"resvd", avi->quantisation, (avi->quantisation==0)?"Def":(avi->quantisation==1)?"Lim":(avi->quantisation==2)?"Ful":"Res", (avi->scaling&0x02)?1:0, (avi->scaling&0x01)?1:0); //fprintf(stderr, "+-----+-----+-----+-----+-----+-----+-----+-----+\n"); fprintf(stderr, "| %u | VIC=%02lu %-19s |\n", (avi_data[4]&0x80)?1:0, avi->vic, CEA861VICNames[avi->vic]); //fprintf(stderr, "+-----+-----+-----+-----+-----+-----+-----+-----+\n"); fprintf(stderr, "| %u | %u | %u | %u | PR=%-2lu |\n", (avi_data[5]&0x80)?1:0, (avi_data[5]&0x40)?1:0, (avi_data[5]&0x20)?1:0, (avi_data[5]&0x10)?1:0, avi->pixel_rep); //fprintf(stderr, "+-----+-----+-----+-----+-----+-----+-----+-----+\n"); fprintf(stderr, "| Top hBar = %-5lu | Bottom hBar = %-5lu |\n", avi->top, avi->bottom); //fprintf(stderr, "+-----+-----+-----+-----+-----+-----+-----+-----+\n"); fprintf(stderr, "| Left vBar = %-5lu | Right vBar = %-5lu |\n", avi->left, avi->right); fprintf(stderr, "+-----+-----+-----+-----+-----+-----+-----+-----+\n"); return RM_OK;}/*** Handling Info Frames ***//* Parses an Audio CP info frame, returns the filled struct */RMstatus capsam_hdmi_parse_audio_cp_packet( struct capsam_hdmi_instance *pHDMI, RMuint8 *header, RMuint8 *data, struct DH_AudioCP_Info *pAudioCP){ RMuint32 Type; fprintf(stderr, "[hdmi] new Audio CP InfoFrame\n"); Type = header[1]; if (pAudioCP) pAudioCP->Type = (enum DH_AudioCP_Type)Type; switch (Type) { case 0: fprintf(stderr, "[hdmi] Generic Audio\n"); break; case 1: fprintf(stderr, "[hdmi] IEC 60958 Audio\n"); break; case 2: { RMuint32 Generation, Transaction, Quality, CopyNumber, CopyPermission; if (pAudioCP) { pAudioCP->DVDAudio_generation = data[0]; pAudioCP->DVDAudio_copy = data[1]; } Generation = data[0]; Transaction = RMunshiftBits(data[1], 1, 0); Quality = RMunshiftBits(data[1], 2, 1); CopyNumber = RMunshiftBits(data[1], 3, 3); CopyPermission = RMunshiftBits(data[1], 2, 6); fprintf(stderr, "[hdmi] DVD Audio, Generation=%lu, Transaction=%lu, Quality=%lu, CopyNumber=%lu, CopyPermission=%lu\n", Generation, Transaction, Quality, CopyNumber, CopyPermission); } break; case 3: { RMuint32 i; if (pAudioCP) { RMMemcpy(pAudioCP->SuperAudioCD_CCI_1, data, 16); } fprintf(stderr, "[hdmi] Super Audio CD, CCI_1 ="); for (i = 0; i < 16; i++) { if (i % 4 == 0) fprintf(stderr, " "); fprintf(stderr, "%02X", data[i]); } fprintf(stderr, "\n"); } break; default: fprintf(stderr, "[hdmi] Unknown AudioCP: %lu\n", Type); } return RM_OK;}/* Parses an ISRC1 info frame, return RM_PENDING if not new If not continued in ISRC2, fills in 16 bytes in pISRC and sets *pISRCSize, otherwise *pISRCSize will be set to 0. */RMstatus capsam_hdmi_parse_isrc1_packet( struct capsam_hdmi_instance *pHDMI, RMuint8 *header, RMuint8 *data, RMuint32 *pISRCSize, RMuint8 *pISRC){ RMuint32 i, Status; RMbool Continued, Valid; // Sanity checks if (pHDMI == NULL) return RM_FATALINVALIDPOINTER; if (pISRCSize) *pISRCSize = 0; if ((header[1] == pHDMI->last_isrc_header) && ! RMMemcmp(&(pHDMI->last_isrc[0]), data, 16)) { return RM_PENDING; } fprintf(stderr, "[hdmi] new ISRC1 InfoFrame\n"); pHDMI->last_isrc_header = header[1]; pHDMI->last_isrc2 = FALSE; RMMemcpy(&(pHDMI->last_isrc[0]), data, 16); RMMemset(&(pHDMI->last_isrc[16]), 0, 16); Status = RMunshiftBits(header[1], 3, 0); Valid = RMunshiftBool(header[1], 6); Continued = RMunshiftBool(header[1], 7); fprintf(stderr, "[hdmi] ISRC Valid: %s, Cont. in ISRC2: %s, %s position\n", Valid ? "yes" : "no", Continued ? "yes" : "no", (Status == 1) ? "starting" : (Status == 2) ? "intermediate" : (Status == 4) ? "ending" : "unknown"); if (! Continued) { fprintf(stderr, "[hdmi] ISRC 0..15 ="); for (i = 0; i < 16; i++) { if (i % 4 == 0) fprintf(stderr, " "); fprintf(stderr, "%02X", data[i]); } fprintf(stderr, "\n"); if (pISRC && pISRCSize) { RMMemcpy(pISRC, data, 16); *pISRCSize = 16; } } return RM_OK;}/* Parses an ISRC2 info frame, return RM_PENDING if not new. otherwise fills in 32 bytes from ISRC1 and ISRC2 into pISRC and sets *pISRCSize */RMstatus capsam_hdmi_parse_isrc2_packet( struct capsam_hdmi_instance *pHDMI, RMuint8 *header, RMuint8 *data, RMuint32 *pISRCSize, RMuint8 *pISRC){ RMuint32 i; // Sanity checks if (pHDMI == NULL) return RM_FATALINVALIDPOINTER; if (pISRCSize) *pISRCSize = 0; if (! RMMemcmp(&(pHDMI->last_isrc[16]), data, 16)) { return RM_PENDING; } fprintf(stderr, "[hdmi] new ISRC2 InfoFrame\n"); pHDMI->last_isrc2 = TRUE; RMMemcpy(&(pHDMI->last_isrc[16]), data, 16); if (pHDMI->last_isrc_header & 0x80) { fprintf(stderr, "[hdmi] ISRC 0..31 ="); for (i = 0; i < 32; i++) { if (i % 4 == 0) fprintf(stderr, " "); fprintf(stderr, "%02X", pHDMI->last_isrc[i]); } fprintf(stderr, "\n"); if (pISRC && pISRCSize) { RMMemcpy(pISRC, pHDMI->last_isrc, 32); *pISRCSize = 32; } } return RM_OK;}/* parses and prints a gamut metadata packet */RMstatus capsam_hdmi_parse_gamut_packet( struct capsam_hdmi_instance *pHDMI, RMuint8 *header, RMuint8 *data, struct DH_GamutMetadata *pGamutMetadata){ RMuint32 GBDProfile, AffSeqNum, PacketSeq, CurrSeqNum; RMbool NextField, NoCurrGBD; RMuint32 i, start, len; fprintf(stderr, "[hdmi] new Gamut InfoFrame\n"); NextField = RMunshiftBool(header[1], 7); GBDProfile = RMunshiftBits(header[1], 3, 4); AffSeqNum = RMunshiftBits(header[1], 4, 0); NoCurrGBD = RMunshiftBool(header[2], 7); PacketSeq = RMunshiftBits(header[2], 2, 4); CurrSeqNum = RMunshiftBits(header[2], 4, 0); fprintf(stderr, "[hdmi] Gamut Boundary Description Profile: P%lu\n", GBDProfile); fprintf(stderr, "[hdmi] Next Field: %s, No Current GBD: %s, Affected Seq.#%lu, Current Seq.#%lu, %s Packet\n", NextField ? "yes" : "no", NoCurrGBD ? "yes" : "no", AffSeqNum, CurrSeqNum, (PacketSeq == 0) ? "Intermediate" : (PacketSeq == 1) ? "First" : (PacketSeq == 2) ? "Last" : (PacketSeq == 3) ? "Only" : "Invalid"); start = 0; len = 28; if ((GBDProfile > 0) && (PacketSeq & 1)) { RMuint32 Length; Length = data[0]; Length = (Length << 8) | data[1]; fprintf(stderr, "[hdmi] GBD Length: %lu, checksum: 0x%02X\n", Length, data[2]); start = 3; len -= start; } fprintf(stderr, "[hdmi] GBD ="); for (i = start; i < len; i++) { if ((i - start) % 4 == 0) fprintf(stderr, " "); fprintf(stderr, "%02X", data[i]); } fprintf(stderr, "\n"); // TODO parse into struct DH_GamutMetadata (TBD), concatenate sequential frames if necessary return RM_OK;}/* parse vendor-specific info frame */RMstatus capsam_hdmi_parse_vendor_info_frame( struct capsam_hdmi_instance *pHDMI, RMuint8 *header, RMuint8 *data, RMuint32 *pVendorID, RMuint8 *pVendorData, RMuint32 *pVendorDataSize){ RMuint32 Version, Length, VendorID; fprintf(stderr, "[hdmi] new Vendor InfoFrame\n"); Version = header[1]; Length = header[2]; VendorID = 0; RMinsShiftBits(&VendorID, data[1], 8, 0); RMinsShiftBits(&VendorID, data[2], 8, 8); RMinsShiftBits(&VendorID, data[3], 8, 16); if (pVendorID) *pVendorID = VendorID; if (pVendorData) RMMemcpy(pVendorData, &(data[4]), Length - 3); if (pVendorDataSize) *pVendorDataSize = Length - 3; fprintf(stderr, "[hdmi] IEEE Vendor ID: 0x%06lX, Version: %lu, Length: %lu\n", VendorID, Version, Length); return RM_OK;}RMstatus capsam_hdmi_handle_avi_info_frame( struct capsam_hdmi_instance *pHDMI, struct capsam_hdmi_avi_info *avi, struct capsam_update *pUpdate){ RMstatus err; RMbool upsample_from_422 = FALSE;// RMbool update_mode = FALSE;// RMbool update_zoom = FALSE; struct EMhwlibAspectRatio avi_asp, asp; RMuint32 x, y, w, h; RMbool force; // force update, even if information is unchanged enum EMhwlibScanInfo scan = EMhwlibScanInfo_NoData; RMDBGLOG((FUNCNAME, "%s\n",__func__)); force = ! pHDMI->last_avi.valid; if (force || RMMemcmp(avi, &(pHDMI->last_avi), sizeof(struct capsam_hdmi_avi_info))) { capsam_hdmi_print_avi_info_frame(pHDMI, NULL, NULL, avi); } // Set up pixel clock reduction in HDMI capture chip according to pixel repetition value if (force || (avi->pixel_rep != pHDMI->last_avi.pixel_rep)) { fprintf(stderr, "newavi - each pixel sent %lu times by source\n", avi->pixel_rep + 1); err = capsam_hdmi_apply_pixelrep(pHDMI, avi->pixel_rep); if (RMSUCCEEDED(err)) { avi->in_pixel_rep = 0; // HDMI chip output is reduced, pixel are no longer repeated } else { if (err == RM_NOT_SUPPORTED) { // TODO: use literal timing information, not reduced one } avi->in_pixel_rep = avi->pixel_rep; } } else if (pHDMI->last_avi.valid) { avi->in_pixel_rep = pHDMI->last_avi.in_pixel_rep; } else { avi->in_pixel_rep = 0; } if (avi->pixel_rep != pHDMI->last_avi.pixel_rep) { // unused for now fprintf(stderr, "newavi - each pixel sent %lu times by source\n", avi->pixel_rep + 1); } // Apply new color space and color format from AVI if (force || (avi->color_format != pHDMI->last_avi.color_format) || (avi->color_space != pHDMI->last_avi.color_space)) { enum EMhwlibColorSpace cs = pHDMI->InputColorSpace; enum EMhwlibInputColorFormat icf = pHDMI->InputColorFormat; switch (avi->color_format) { case 0: fprintf(stderr, "newavi - RGB 888\n"); icf = EMhwlibInputColorFormat_24BPP; switch (avi->quantisation) { case 0: cs = (avi->vic > 1) ? EMhwlibColorSpace_RGB_16_235 : EMhwlibColorSpace_RGB_0_255; break; case 1: cs = EMhwlibColorSpace_RGB_16_235; break; case 2: cs = EMhwlibColorSpace_RGB_0_255; break; default: fprintf(stderr, "newavi - unknown RGB quantisation range code: %lu\n", avi->quantisation); cs = (avi->vic > 1) ? EMhwlibColorSpace_RGB_16_235 : EMhwlibColorSpace_RGB_0_255;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -