예제 #1
0
static int get_modes( HDMI_RES_GROUP_T group)
{
   static TV_SUPPORTED_MODE_T supported_modes[MAX_MODE_ID] = {{0}};
   HDMI_RES_GROUP_T preferred_group;
   uint32_t preferred_mode;
   int num_modes;
   int i;

   vcos_assert(( group == HDMI_RES_GROUP_CEA ) ||
               ( group == HDMI_RES_GROUP_DMT ));

   num_modes = vc_tv_hdmi_get_supported_modes( group, supported_modes,
                                               vcos_countof(supported_modes),
                                               &preferred_group,
                                               &preferred_mode );
   if ( num_modes < 0 )
   {
      LOG_ERR( "Failed to get modes" );
      return -1;
   }

   LOG_STD( "Group %s has %u modes:",
            HDMI_RES_GROUP_NAME(group), num_modes );
   for ( i = 0; i < num_modes; i++ )
   {
      char p[8] = {0};
      if( supported_modes[i].pixel_rep )
         snprintf(p, sizeof(p)-1, "x%d ", supported_modes[i].pixel_rep);
      else
         snprintf(p, sizeof(p)-1, " ");

      LOG_STD( "%s mode %u: %ux%u @ %uHz %s, clock:%luMHz %s%s %s",
               supported_modes[i].native ? "  (native)" : "          ",
               supported_modes[i].code, supported_modes[i].width,
               supported_modes[i].height, supported_modes[i].frame_rate,
               aspect_ratio_str(supported_modes[i].aspect_ratio),
               supported_modes[i].pixel_freq / 1000000UL, p,
               supported_modes[i].scan_mode ? "interlaced" : "progressive",
               supported_modes[i].struct_3d_mask ? threed_str(supported_modes[i].struct_3d_mask) : "");
   }

   return 0;
}
static const char *status_mode( TV_DISPLAY_STATE_T *tvstate ) {
   static char mode_str[MAX_STATUS_STR_LENGTH] = {0};
   int tmp = 0;
   size_t offset = 0;
   if(tvstate->state & ( VC_HDMI_HDMI | VC_HDMI_DVI )) {
      //HDMI or DVI on
      tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, (tvstate->state & VC_HDMI_HDMI) ? "HDMI" : "DVI");
      if(!tmp) {
         //We should still have space at this point
         switch(tvstate->display.hdmi.group) {
         case HDMI_RES_GROUP_CEA:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " CEA (%d)", tvstate->display.hdmi.mode); break;
         case HDMI_RES_GROUP_DMT:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " DMT (%d)", tvstate->display.hdmi.mode); break;
         default: break;
         }
      }
      if(!tmp && tvstate->display.hdmi.format_3d) {
         switch(tvstate->display.hdmi.format_3d) {
         case HDMI_3D_FORMAT_SBS_HALF:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " 3D SbS"); break;
         case HDMI_3D_FORMAT_TB_HALF:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " 3D T&B"); break;
         default: break;
         }
      }
      if(!tmp) {
         if (tvstate->state & VC_HDMI_HDMI)
            //Only HDMI mode can signal pixel encoding in AVI infoframe
            switch(tvstate->display.hdmi.pixel_encoding) {
            case HDMI_PIXEL_ENCODING_RGB_LIMITED:
               tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " RGB lim"); break;
            case HDMI_PIXEL_ENCODING_RGB_FULL:
               tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " RGB full"); break;
            case HDMI_PIXEL_ENCODING_YCbCr444_LIMITED:
               tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " YCbCr444 lim"); break;
            case HDMI_PIXEL_ENCODING_YCbCr444_FULL:
               tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " YCbCr444 full"); break;
            case HDMI_PIXEL_ENCODING_YCbCr422_LIMITED:
               tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " YCbCr422 lim"); break;
            case HDMI_PIXEL_ENCODING_YCbCr422_FULL:
               tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " YCbCr422 full"); break;
            default: break;
            }
         else
            //DVI will always be RGB, and CEA mode will have limited range, DMT mode full range
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset,
                        (tvstate->display.hdmi.group == HDMI_RES_GROUP_CEA)?
                        " RGB lim" : " RGB full");
      }

      //This is the format's aspect ratio, not the one
      //signaled in the AVI infoframe
      if(!tmp)
         tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " %s", aspect_ratio_str(tvstate->display.hdmi.aspect_ratio));

      if(!tmp &&tvstate->display.hdmi.pixel_rep) {
         tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " x%d", tvstate->display.hdmi.pixel_rep);
      }
      if(!tmp && tvstate->state & VC_HDMI_HDCP_AUTH) {
         tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " HDCP");
      }
   } else if(tvstate->state & ( VC_SDTV_NTSC | VC_SDTV_PAL )) {
      if(!tmp) {
         if(tvstate->state & VC_SDTV_NTSC) {
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, "NTSC");
         } else {
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, "PAL");
         }
      }
      if(!tmp && tvstate->display.sdtv.cp_mode) {
         switch(tvstate->display.sdtv.cp_mode) {
         case SDTV_CP_MACROVISION_TYPE1:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " Macrovision type 1"); break;
         case SDTV_CP_MACROVISION_TYPE2:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " Macrovision type 2"); break;
         case SDTV_CP_MACROVISION_TYPE3:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " Macrovision type 3"); break;
         case SDTV_CP_MACROVISION_TEST1:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " Macrovision test 1"); break;
         case SDTV_CP_MACROVISION_TEST2:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " Macrovision test 2"); break;
         case SDTV_CP_CGMS_COPYFREE:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " CGMS copy free"); break;
         case SDTV_CP_CGMS_COPYNOMORE:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " CGMS copy no more"); break;
         case SDTV_CP_CGMS_COPYONCE:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " CGMS copy once"); break;
         case SDTV_CP_CGMS_COPYNEVER:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " CGMS copy never"); break;
         case SDTV_CP_WSS_COPYFREE:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " WSS copy free"); break;
         case SDTV_CP_WSS_COPYRIGHT_COPYFREE:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " WSS (c) copy free"); break;
         case SDTV_CP_WSS_NOCOPY:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " WSS no copy"); break;
         case SDTV_CP_WSS_COPYRIGHT_NOCOPY:
            tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " WSS (c) no copy"); break;
         default: break;
         }
      }
      //This is the format's aspect ratio
      tmp = status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, " %s", aspect_ratio_str(tvstate->display.sdtv.display_options.aspect));
   } else {
      status_sprintf(mode_str, MAX_STATUS_STR_LENGTH, &offset, "TV is off");
   }

   return mode_str;
}
static int get_modes( HDMI_RES_GROUP_T group, int json_output)
{
   static TV_SUPPORTED_MODE_T supported_modes[MAX_MODE_ID];
   HDMI_RES_GROUP_T preferred_group;
   uint32_t preferred_mode;
   int num_modes;
   int i;

   vcos_assert(( group == HDMI_RES_GROUP_CEA ) ||
               ( group == HDMI_RES_GROUP_DMT ));

   memset(supported_modes, 0, sizeof(supported_modes));

   num_modes = vc_tv_hdmi_get_supported_modes( group, supported_modes,
                                               vcos_countof(supported_modes),
                                               &preferred_group,
                                               &preferred_mode );
   if ( num_modes < 0 )
   {
      LOG_ERR( "Failed to get modes" );
      return -1;
   }

   if (json_output)
   {
      LOG_STD( "[" );
   }
   else
   {
      LOG_STD( "Group %s has %u modes:",
               HDMI_RES_GROUP_NAME(group), num_modes );
   }

   for ( i = 0; i < num_modes; i++ )
   {
      char p[8] = {0};
      if( supported_modes[i].pixel_rep )
         vcos_safe_sprintf(p, sizeof(p)-1, 0, "x%d ", supported_modes[i].pixel_rep);

      if (json_output)
      {
         LOG_STD( "{ \"code\":%u, \"width\":%u, \"height\":%u, \"rate\":%u, \"aspect_ratio\":\"%s\", \"scan\":\"%s\", \"3d_modes\":[%s] }%s",
                  supported_modes[i].code, supported_modes[i].width,
                  supported_modes[i].height, supported_modes[i].frame_rate,
                  aspect_ratio_str(supported_modes[i].aspect_ratio),
                  supported_modes[i].scan_mode ? "i" : "p",
                  supported_modes[i].struct_3d_mask ? threed_str(supported_modes[i].struct_3d_mask, 1) : "",
                  (i+1 < num_modes) ? "," : "");
      }
      else
      {
         int preferred = supported_modes[i].group == preferred_group && supported_modes[i].code == preferred_mode;
         LOG_STD( "%s mode %u: %ux%u @ %uHz %s, clock:%uMHz %s%s %s",
                  preferred ? "  (prefer)" : supported_modes[i].native ? "  (native)" : "          ",
                  supported_modes[i].code, supported_modes[i].width,
                  supported_modes[i].height, supported_modes[i].frame_rate,
                  aspect_ratio_str(supported_modes[i].aspect_ratio),
                  supported_modes[i].pixel_freq / 1000000U, p,
                  supported_modes[i].scan_mode ? "interlaced" : "progressive",
                  supported_modes[i].struct_3d_mask ? threed_str(supported_modes[i].struct_3d_mask, 0) : "");
      }
   }

   if (json_output)
   {
      LOG_STD( "]" );
   }
   return 0;
}