  void CameraViewWidget::paintGL() {
    glClearColor(bg.redF(), bg.greenF(), bg.blueF(), bg.alphaF());
    glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  
    if (latest_frame == nullptr) return;
  
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glViewport(0, 0, width(), height());
    glBindVertexArray(frame_vao);
  
 
</s> remove   uint8_t *address[3] = {latest_frame->y, latest_frame->u, latest_frame->v};
 </s> add   uint8_t *address[3] = {frame->y, frame->u, frame->v}; </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   latest_frame = nullptr;
 </s> add   frames.clear(); </s> remove       vipc_client.reset(new VisionIpcClient(stream_name, cur_stream_type, true));
 </s> add       vipc_client.reset(new VisionIpcClient(stream_name, cur_stream_type, false));
  if (frames.empty()) return;

  int frame_idx;
  for (frame_idx = 0; frame_idx < frames.size() - 1; frame_idx++) {
    if (frames[frame_idx].first == draw_frame_id) break;
  }
  VisionBuf *frame = frames[frame_idx].second;
  void CameraViewWidget::paintGL() {
    glClearColor(bg.redF(), bg.greenF(), bg.blueF(), bg.alphaF());
    glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  
  if (frames.empty()) return;

  int frame_idx;
  for (frame_idx = 0; frame_idx < frames.size() - 1; frame_idx++) {
    if (frames[frame_idx].first == draw_frame_id) break;
  }
  VisionBuf *frame = frames[frame_idx].second;
  
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glViewport(0, 0, width(), height());
    glBindVertexArray(frame_vao);
  
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