Skip to content

Video binding failing in some cases due to a bug in DefaultVideoTileController #499

Open
@Jim-Bar

Description

@Jim-Bar

Hi,

We think there is a mistake in DefaultVideoTileController which causes video bindings to fail under certain circumstances. This occurs when two participants in a video meeting swap their videos.

Description

Initial situation:

  1. VideoRenderView A shows tileId 1
  2. VideoRenderView B shows tileId 2

Final situation (expected):

  1. VideoRenderView A shows tileId 2
  2. VideoRenderView B shows tileId 1

Final situation (actual):

  1. VideoRenderView A shows frozen tileId 1
  2. VideoRenderView B shows tileId 1

To Reproduce

Here are the steps to reproduce:

  1. Have two participants in a meeting
  2. Disable the video of the first participant then re-enable it
  3. Now proceed to swapping the tiles: bind the VideoRenderView of the second participant to the first tileId
  4. Bind the VideoRenderView of the first participant to the second tileId

The video of the second participant shows the old video and is frozen (binding didn't occur).

We did not try to reproduce it on the demo app because it means a bit of work for triggering the swap of videos. However I can upload a video recording of the bug occurring in our application if needed.

Explanation and probable solution

The problem is caused by step 2. When the video is disabled, DefaultVideoTileController::onRemoveVideoTile() is invoked but does not remove the VideoRenderView (let's call it X) from renderViewToBoundVideoTileMap. Most likely a call to removeRenderViewFromBoundVideoTileMap(tileId) is missing line 201.

Then when later re-enabling the video, a new VideoRenderView is created (let's call it Y). Then, when swapping the videos, the following occurs:

  1. DefaultVideoTileController::bindVideoView() is invoked
  2. The block checking whether a VideoRenderView is associated with a video tile is entered ("Override the binding from (…)")
  3. A call is made to removeRenderViewFromBoundVideoTileMap() to remove the VideoRenderView which is going to be replaced
  4. renderViewToBoundVideoTileMap.entries.firstOrNull finds the VideoRenderView X (which no more exists and should have been removed in onRemoveVideoTile()) and removes it from the map instead of finding and removing Y (both have the save tileId)
  5. First video replaced the other, now DefaultVideoTileController::bindVideoView() is invoked a second time to swap the second video
  6. The same block as in 2 is entered althought it should not because Y should have been removed from the map there but was not
  7. Again, call to removeRenderViewFromBoundVideoTileMap() which in turn calls videoTile.unbind(), unbinding the first video we swapped previously
  8. Hence the video being frozen

We confirmed that by adding the missing call line 201 described above the bug goes away. This seems to be the right way of solving the issue, however we are not that familiar with the internals of Chime so maybe there is a better way.

Test environment Info

  • Version amazon-chime-sdk: 0.17.4
  • Version amazon-chime-sdk-media: 0.17.5

Additional info

This was not tested on iOS.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions