void DisplayStreamer::Run()

in streaming/screen-sharing-agent/app/src/main/cpp/display_streamer.cc [208:335]


void DisplayStreamer::Run() {
  Jni jni = Jvm::GetJni();
  WindowManager::WatchRotation(jni, display_id_, &display_rotation_watcher_);
  // Don't listen to display events on non-foldable HONOR phones. HONOR 90 is producing bogus display change events (b/348562991).
  if (!DeviceStateManager::GetSupportedDeviceStates(jni).empty() || Agent::device_manufacturer() != HONOR) {
    DisplayManager::AddDisplayListener(jni, this);
  }

  AMediaFormat* media_format = CreateMediaFormat(codec_info_->mime_type);
  VideoPacketHeader packet_header = { .display_id = display_id_, .frame_number = frame_number_};
  FrameStreamStopReason stop_reason = FrameStreamStopReason::CODEC_STOPPED;
  int error_count = 0;

  while (stop_reason != FrameStreamStopReason::END_OF_STREAM && !streamer_stopped_ && !Agent::IsShuttingDown()) {
    DisplayInfo display_info = DisplayManager::GetDisplayInfo(jni, display_id_);
    if (display_id_ != PRIMARY_DISPLAY_ID && (!display_info.IsValid() || !display_info.IsOn())) {
      Log::W("Display %d: turned off", display_id_);
      DisplayManager::OnDisplayRemoved(jni, display_id_);
      break;
    }
    Log::D("Display %d: display_info: %s", display_id_, display_info.ToDebugString().c_str());
    if (stop_reason != FrameStreamStopReason::TIMEOUT) {
      ReleaseVirtualDisplay(jni);
    }
    if (virtual_display_.IsNull() && display_token_.IsNull()) {
      string display_name = StringPrintf("studio.screen.sharing:%d", display_id_);
      if (Agent::feature_level() >= 34) {
        virtual_display_ = DisplayManager::CreateVirtualDisplay(
            jni, display_name.c_str(), display_info.logical_size.width, display_info.logical_size.height, display_id_, nullptr);
      } else {
        bool secure = Agent::feature_level() < 31;  // Creation of secure displays is not allowed on API 31+.
        display_token_ = SurfaceControl::CreateDisplay(jni, display_name.c_str(), secure);
        if (display_token_.IsNull()) {
          Log::Fatal(VIRTUAL_DISPLAY_CREATION_ERROR, "Display %d: unable to create a virtual display", display_id_);
        }
      }
    }
    {
      unique_lock lock(mutex_);
      if (codec_stop_pending_) {
        codec_stop_pending_ = false;
        ReleaseVirtualDisplay(jni);
        continue;  // Start another loop to refresh display information.
      }
      display_info_ = display_info;
      int32_t rotation_correction = video_orientation_ >= 0 ? NormalizeRotation(video_orientation_ - display_info.rotation) : 0;
      if (display_info.rotation == 2 && rotation_correction == 0 && Agent::device_type() != DeviceType::WATCH) {
        // Simulated rotation is not capable of distinguishing between regular and upside down
        // display orientation. Compensate for that using rotation_correction.
        display_info.rotation = 0;
        rotation_correction = 2;
      }
      CreateCodec();
      Size video_size = ConfigureCodec(
          codec_, *codec_info_, max_video_resolution_.Rotated(rotation_correction), bit_rate_, media_format, display_info, display_id_);
      Log::D("Display %d: rotation=%d rotation_correction=%d video_size=%dx%d",
             display_id_, display_info.rotation, rotation_correction, video_size.width, video_size.height);
      media_status_t status = AMediaCodec_createInputSurface(codec_, &surface_);  // Requires API 26.
      if (status != AMEDIA_OK) {
        Log::Fatal(INPUT_SURFACE_CREATION_ERROR, "Display %d: AMediaCodec_createInputSurface returned %d", display_id_, status);
      }
      if (Agent::feature_level() >= 34) {
        virtual_display_.Resize(video_size.width, video_size.height, display_info_.logical_density_dpi);
        virtual_display_.SetSurface(surface_);
      } else {
        int32_t height = lround(static_cast<double>(video_size.width) * display_info.logical_size.height / display_info.logical_size.width);
        int32_t y = (video_size.height - height) / 2;
        SurfaceControl::ConfigureProjection(jni, display_token_, surface_, display_info, { 0, y, video_size.width, height });
      }
      StartCodecUnlocked();
      codec_running_ = true;
      Size display_size = display_info.NaturalSize();  // The display dimensions in the canonical orientation.
      packet_header.display_width = display_size.width;
      packet_header.display_height = display_size.height;
      packet_header.display_orientation = NormalizeRotation(display_info.rotation + rotation_correction);
      packet_header.display_orientation_correction = NormalizeRotation(rotation_correction);
      packet_header.flags =
          ((display_info.flags & DisplayInfo::FLAG_ROUND) ? VideoPacketHeader::FLAG_DISPLAY_ROUND : 0) | // NOLINT(*-narrowing-conversions)
          (bit_rate_reduced_ ? VideoPacketHeader::FLAG_BIT_RATE_REDUCED : 0);
      packet_header.bit_rate = bit_rate_;
    }
    AMediaFormat* sync_frame_request = AMediaFormat_new();
    AMediaFormat_setInt32(sync_frame_request, AMEDIACODEC_KEY_REQUEST_SYNC_FRAME, 0);
    stop_reason = ProcessFramesUntilCodecStopped(&packet_header, sync_frame_request);
    Log::D("ProcessFramesUntilCodecStopped returned %d", stop_reason);
    AMediaFormat_delete(sync_frame_request);
    StopCodec();
    DeleteCodec();
    if (virtual_display_.IsNotNull()) {
      virtual_display_.SetSurface(nullptr);
    } else {
      SurfaceControl::SetSurface(jni, display_token_, nullptr);
    }
    ANativeWindow_release(surface_);
    surface_ = nullptr;
    if (stop_reason == FrameStreamStopReason::CODEC_ERROR) {
      if (++error_count >= MAX_SUBSEQUENT_ERRORS && !ReduceBitRate()) {
        ExitCode exitCode = bit_rate_ <= MIN_BIT_RATE ? WEAK_VIDEO_ENCODER : REPEATED_VIDEO_ENCODER_ERRORS;
        Log::Fatal(exitCode, "Display %d: too many video encoder errors:\n%s", display_id_,
                   GetVideoEncoderDetails(*codec_info_, packet_header.display_width, packet_header.display_height).c_str());
      }
    } else {
      error_count = 0;
      if (stop_reason == FrameStreamStopReason::TIMEOUT) {
        // Write an empty video packet.
        int64_t timestamp = duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
        packet_header.origination_timestamp_us = timestamp;
        packet_header.packet_size = 0;
        if (Log::IsEnabled(Log::Level::VERBOSE)) {
          Log::V("Display %d: writing an video packet", display_id_);
        }
        auto res = writer_->Write(&packet_header, VideoPacketHeader::SIZE);
        if (res == SocketWriter::Result::DISCONNECTED) {
          stop_reason = FrameStreamStopReason::END_OF_STREAM;
        }
      }
    }
  }

  ReleaseVirtualDisplay(jni);
  AMediaFormat_delete(media_format);
  WindowManager::RemoveRotationWatcher(jni, display_id_, &display_rotation_watcher_);
  DisplayManager::RemoveDisplayListener(this);

  if (stop_reason == FrameStreamStopReason::END_OF_STREAM) {
    Agent::Shutdown();
  }
}