  
    while (!QThread::currentThread()->isInterruptionRequested()) {
      if (!vipc_client || cur_stream_type != stream_type) {
        cur_stream_type = stream_type;
        vipc_client.reset(new VisionIpcClient(stream_name, cur_stream_type, true));
      }
  
      if (!vipc_client->connected) {
        if (!vipc_client->connect(false)) {
          QThread::msleep(100);
 
</s> remove void CameraViewWidget::vipcFrameReceived(VisionBuf *buf) {
  latest_frame = buf;
 </s> add void CameraViewWidget::vipcFrameReceived(VisionBuf *buf, uint32_t frame_id) {
  frames.push_back(std::make_pair(frame_id, buf));
  while (frames.size() > FRAME_BUFFER_SIZE) {
    frames.pop_front();
  } </s> remove     if (VisionBuf *buf = vipc_client->recv(nullptr, 1000)) {
      emit vipcThreadFrameReceived(buf);
 </s> add     if (VisionBuf *buf = vipc_client->recv(&meta_main, 1000)) {
      emit vipcThreadFrameReceived(buf, meta_main.frame_id); </s> remove       auto leads = (*s->sm)["modelV2"].getModelV2().getLeadsV3();
 </s> add       const auto leads = model.getLeadsV3(); </s> remove   UIState *s = uiState();
 </s> add 
      vipc_client.reset(new VisionIpcClient(stream_name, cur_stream_type, false));
  
    while (!QThread::currentThread()->isInterruptionRequested()) {
      if (!vipc_client || cur_stream_type != stream_type) {
        cur_stream_type = stream_type;
      vipc_client.reset(new VisionIpcClient(stream_name, cur_stream_type, false));
      }
  
      if (!vipc_client->connected) {
        if (!vipc_client->connect(false)) {
          QThread::msleep(100);
keep keep keep keep replace keep keep keep keep keep
 UI: draw camera on same frame from modelV2 (#24335)

* draw camera on same frame from modelV2

* fix reversing

* optimze

* sleep shorter

* heavy debugging

* clean up

* fix ui hang

* try this

* more generic implementation

* add unused flag back

* draw latest frames when camerad is coming up with no modeld

* only get modelV2 once

* fix drawing

* conflate, reduce buffer, and remove special case when starting

* make tests pass

* remove comments

* frame_id is a uint32_t

* not sure why passing to cameraview causes overflow

* ternary, not too complicated

* change to size

* rename to frame

* use unique_ptr

* Revert "use unique_ptr"

This reverts commit 955842d9511a26468d4deedd1807f096540cb40c.

* Assert buffer size

Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>

* use one deque with pairs and uint32_t

* formatting

* frame offset

* Revert "frame offset"

This reverts commit a2cff8a2d57a02f314d9f6adb7221b193a150e4c.

* use array

* add prints

* Revert "add prints"

This reverts commit d6978746e5c316fb2d5a619091c9aaf849c31967.

* clean up

* this handles all cases

* we want to clip

* fixes going backwards when replay or modeld lags multiple frames, then skips multiple frames

fixes going backwards when replay or modeld lags multiple frames, then skips multiple frames

* fix rare case where camera is behind model

simpler comment

* draw latest frames if we start with no model, then hang on current frame until model catches up

fix

* store if it's updated

* accurate comment

* reset to latest on connect and showevent

* better order

* use quint32 for sending signal function

* use empty

* draft

* kinda works

* works

* one line

* debug

* clean up

* revert this

* to preserve behavior, think we need to poll these

* revert

* no timeout when modeld is not alive

* Update selfdrive/ui/qt/onroad.cc

* changes from other PR

* see if we're drawing dup model or camera frames

* looks good, just need to clean up

* debug

* clean up

* clean up

* revert these changes

* fix

* pretty simple, test on device

* clean up

* revert this

Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> 
selfdrive/ui/qt/widgets/cameraview.cc