3

I am developing a video app for a Qualcomm Snapdragon which runs Android. I have an app that takes in a video stream, processes it, and sends a datastream out based on the image. It can also have a mode to display the images to HDMI, but it is not necessary. I have also configured my app to automatically run on startup.

It is important that the system can be started without an HDMI plugged in. However, when starting the system without a monitor plugged in, the boot process gets caught in an infinite loop where it seems to be trying to start video/audio services, failing, and trying again. When the HDMI is plugged in, the system is able to finish booting and then continue to the home screen. Here is the log I obtained over serial that is looped forever when trying to boot without HDMI:

[ 22.471956] init: property_set("ro.boottime.audioserver", "22471598897") failed: property already set
[ 22.481207] init: property_set("ro.boottime.cameraserver", "22480859470") failed: property already set
[ 22.490533] init: property_set("ro.boottime.media", "22490197595") failed: property already set
[ 22.499191] init: property_set("ro.boottime.netd", "22498862751") failed: property already set
[ 22.531151] init: property_set("ro.boottime.wificond", "22530820772") failed: property already set
[ 22.983305] MSM-CPP cpp_init_hardware:1023 stream_cnt:0
[ 23.126367] init: property_set("ro.boottime.zygote", "23125974574") failed: property already set
[ 23.206157] MSM-CPP cpp_init_hardware:1023 stream_cnt:0
[ 23.561725] msm_qti_pp_get_rms_value_control, back not active to query rms be_idx:3
[ 23.573642] msm_voice_sound_focus_get: Error getting Sound Focus Params, err=-22
[ 23.580423] msm_voice_source_tracking_get: Error getting Source Tracking Params, err=-22
[ 23.588465] msm_audio_get_copp_idx_from_port_id: Invalid FE, exiting
[ 23.594484] msm_audio_sound_focus_get: Could not get copp idx for port_id=16385
[ 23.602184] msm_audio_get_copp_idx_from_port_id: Invalid FE, exiting
[ 23.608040] msm_audio_source_tracking_get: Could not get copp idx for port_id=16385
[ 23.616115] msm_voice_sound_focus_get: Error getting Sound Focus Params, err=-22
[ 23.623421] msm_voice_source_tracking_get: Error getting Source Tracking Params, err=-22
[ 23.631478] msm_audio_get_copp_idx_from_port_id: Invalid FE, exiting
[ 23.637464] msm_audio_sound_focus_get: Could not get copp idx for port_id=4101
[ 23.644995] msm_audio_get_copp_idx_from_port_id: Invalid FE, exiting
[ 23.651027] msm_audio_source_tracking_get: Could not get copp idx for port_id=4101
[ 23.658855] msm_audio_get_copp_idx_from_port_id: Invalid FE, exiting
[ 23.664939] msm_audio_sound_focus_get: Could not get copp idx for port_id=4103
[ 23.672444] msm_audio_get_copp_idx_from_port_id: Invalid FE, exiting
[ 23.678435] msm_audio_source_tracking_get: Could not get copp idx for port_id=4103
[ 23.688260] msm_pcm_volume_ctl_get substream runtime not found
[ 23.694029] msm_pcm_volume_ctl_get substream runtime not found
[ 23.699605] msm_pcm_volume_ctl_get substream runtime not found
[ 23.705037] msm_compr_audio_effects_config_get: stream or effects inactive
[ 23.712576] msm_pcm_volume_ctl_get substream runtime not found
[ 23.717709] msm_compr_audio_effects_config_get: stream or effects inactive
[ 23.725125] msm_compr_audio_effects_config_get: stream or effects inactive
[ 23.731802] msm_pcm_volume_ctl_get substream runtime not found
[ 23.737211] msm_pcm_volume_ctl_get substream or runtime not found
[ 23.744698] msm_pcm_volume_ctl_get substream runtime not found
[ 23.749964] msm_compr_audio_effects_config_get: stream or effects inactive
[ 23.757250] msm_compr_audio_effects_config_get: stream or effects inactive
[ 23.764110] msm_compr_audio_effects_config_get: stream or effects inactive
[ 23.770790] msm_compr_audio_effects_config_get: stream or effects inactive
[ 23.777327] msm_compr_audio_effects_config_get: stream or effects inactive
[ 23.784724] msm_compr_audio_effects_config_get: stream or effects inactive
[ 25.705018] init: property_set("ro.boottime.surfaceflinger", "25704640562") failed: property already set
[ 25.705499] init: Failed to bind socket 'pdx/system/vr/display/client': No such file or directory
[ 25.705779] init: Failed to bind socket 'pdx/system/vr/display/manager': No such file or directory
[ 25.706060] init: Failed to bind socket 'pdx/system/vr/display/vsync': No such file or directory
[ 26.052708] init: Unable to open '/sys/android_power/request_state': No such file or directory
[ 26.060404] init: Unable to write to '/sys/power/state': Invalid argument
[ 26.138413] init: property_set("ro.boottime.hwcomposer-2-1", "26138041187") failed: property already set
[ 26.534961] init: property_set("ro.boottime.audio-hal-2-0", "26534542802") failed: property already set
[ 27.048016] msm_qti_pp_get_rms_value_control, back not active to query rms be_idx:3
[ 27.057638] msm_voice_sound_focus_get: Error getting Sound Focus Params, err=-22
[ 27.064137] msm_voice_source_tracking_get: Error getting Source Tracking Params, err=-22
[ 27.072189] msm_audio_get_copp_idx_from_port_id: Invalid FE, exiting
[ 27.078398] msm_audio_sound_focus_get: Could not get copp idx for port_id=16385
[ 27.085828] msm_audio_get_copp_idx_from_port_id: Invalid FE, exiting
[ 27.092048] msm_audio_source_tracking_get: Could not get copp idx for port_id=16385
[ 27.099817] msm_voice_sound_focus_get: Error getting Sound Focus Params, err=-22
[ 27.107172] msm_voice_source_tracking_get: Error getting Source Tracking Params, err=-22
[ 27.115220] msm_audio_get_copp_idx_from_port_id: Invalid FE, exiting
[ 27.121482] msm_audio_sound_focus_get: Could not get copp idx for port_id=4101
[ 27.128760] msm_audio_get_copp_idx_from_port_id: Invalid FE, exiting
[ 27.135023] msm_audio_source_tracking_get: Could not get copp idx for port_id=4101
[ 27.142667] msm_audio_get_copp_idx_from_port_id: Invalid FE, exiting
[ 27.148883] msm_audio_sound_focus_get: Could not get copp idx for port_id=4103
[ 27.156218] msm_audio_get_copp_idx_from_port_id: Invalid FE, exiting
[ 27.162444] msm_audio_source_tracking_get: Could not get copp idx for port_id=4103
[ 27.171810] msm_pcm_volume_ctl_get substream runtime not found
[ 27.177051] msm_pcm_volume_ctl_get substream runtime not found
[ 27.182976] msm_pcm_volume_ctl_get substream runtime not found
[ 27.188378] msm_compr_audio_effects_config_get: stream or effects inactive
[ 27.195922] msm_pcm_volume_ctl_get substream runtime not found
[ 27.201188] msm_compr_audio_effects_config_get: stream or effects inactive
[ 27.208164] msm_compr_audio_effects_config_get: stream or effects inactive
[ 27.215088] msm_pcm_volume_ctl_get substream runtime not found
[ 27.220547] msm_pcm_volume_ctl_get substream or runtime not found
[ 27.227649] msm_pcm_volume_ctl_get substream runtime not found
[ 27.232647] msm_compr_audio_effects_config_get: stream or effects inactive
[ 27.239729] msm_compr_audio_effects_config_get: stream or effects inactive
[ 27.246622] msm_compr_audio_effects_config_get: stream or effects inactive
[ 27.253478] msm_compr_audio_effects_config_get: stream or effects inactive
[ 27.260348] msm_compr_audio_effects_config_get: stream or effects inactive
[ 27.267146] msm_compr_audio_effects_config_get: stream or effects inactive

I believe there should be some way to edit the init.rc file to prevent the audio/video services being run at bootup, then register some sort of "hot plug" in ueventd when HDMI is plugged in later, after boot.

While I have looked into these things, I am lost on how to actually go about implementing them and I do not know for sure if this is the correct path. Any help would be much appreciated!

Edit: It seems that the way to properly do this by editing Android source code is way above my pay grade, but an easy fix is to buy an HDMI dummy plug that simulates an HDMI monitor. Basically it just has EDID data in its registers and spits that back out when the operating system initially looks for its display.

  • it's the [SurfaceFlinger](https://source.android.com/devices/graphics/surfaceflinger-windowmanager#surfaceflinger) – Martin Zeitler Oct 01 '19 at 18:16
  • @MartinZeitler Thank you for pointing me in this direction! I see this line in the hardware composer (hwc) documentation "virtual displays send output to a Gralloc buffer" Would this be a valid way to approach the problem? I'm thinking that maybe I could create a virtual display that defaults as the internal display in order to get the system running. Then, I could hotplug an hdmi monitor later as needed. – Jay Jackman Oct 01 '19 at 18:31
  • I've left a more explicit answer, which provides further hints (currently don't have any AOSP or hardware)... the primary goal should be to connect a virtual display, the secondary goal should be to handle display switching... which appear to be two questions on their own. – Martin Zeitler Oct 01 '19 at 20:33

1 Answers1

1

DisplayDevice.cpp has lead me to Virtual display composition:

Virtual display composition is similar to external display composition. The difference between virtual display composition and physical display composition is that virtual displays send output to a Gralloc buffer instead of to the screen. Hardware Composer (HWC) writes the output to a buffer, provides the completion fence, and sends the buffer to a consumer (such as the video encoder, GPU, CPU, and so on). Virtual displays can use 2D/blitter or overlays if the display pipeline writes to memory.

Also Virtual displays explains it:

SurfaceFlinger supports an internal display (built into the phone or tablet), external displays (such as a television connected through HDMI), and one or more virtual displays that make composited output available within the system. Virtual displays can be used to record the screen or send the screen over a network. Frames generated for a virtual display are written to a BufferQueue.

One would have to connect a virtual display device, in order to provide the expected output buffer. After a short research, I'm not exactly sure how to accomplish that, but when looking at the log... it seems that it already fucks up when trying to get a display, in order to show the boot animation.

That virtual display device would need to be setup as the primary output buffer. I'd assume it should be possible to configure that with file system.prop or some *.rc file or any init.*.sh it may reference. TYPE_HDMI = 2 and TYPE_VIRTUAL = 5 ... found in Display.java. It seems the event you are looking for, when plugging in or unplugging the HDMI cable, is DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED.

Feel free to post a better answer, in case you can find out how that works.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216