mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-23 00:02:28 +00:00
desktop: fix stretched video preview and playback for AV1 videos (#7391)
* desktop: fix stretched video preview and playback for AV1 videos libvlc passes the padded size the decoder allocated to the buffer format callback, not the size of the picture. dav1d pads to a multiple of 128, so a 1920x1080 AV1 video arrives as 1920x1152, and vlc scales the picture to fill it - the preview sent with the message, and desktop playback, were 6.7% too tall. H264 pads much less, so it was barely visible there. Ask for the size of the track being played instead. It is already populated when the buffer format is negotiated, and matching the track that is playing matters for files with more than one video track, where the first track is not necessarily the one being decoded. Falls back to the previous behaviour when the track is not known. * plans: desktop video preview aspect ratio
This commit is contained in:
1 parent
222fc4ad99
commit
11c7a62a38
2 files changed
+86
-3
No files matched your search
+13
-3
@@ -23,6 +23,7 @@ import javax.swing.SwingUtilities
|
||||
internal class SkiaBitmapVideoSurface : VideoSurface(VideoSurfaceAdapters.getVideoSurfaceAdapter()) {
|
||||
|
||||
private val videoSurface = SkiaBitmapVideoSurface()
|
||||
@Volatile private var mediaPlayer: MediaPlayer? = null
|
||||
private lateinit var imageInfo: ImageInfo
|
||||
private lateinit var frameBytes: ByteArray
|
||||
private val skiaBitmap: Bitmap = Bitmap()
|
||||
@@ -31,6 +32,7 @@ internal class SkiaBitmapVideoSurface : VideoSurface(VideoSurfaceAdapters.getVid
|
||||
val bitmap: State<ImageBitmap?> = composeBitmap
|
||||
|
||||
override fun attach(mediaPlayer: MediaPlayer) {
|
||||
this.mediaPlayer = mediaPlayer
|
||||
videoSurface.attach(mediaPlayer)
|
||||
}
|
||||
|
||||
@@ -39,9 +41,17 @@ internal class SkiaBitmapVideoSurface : VideoSurface(VideoSurfaceAdapters.getVid
|
||||
private var sourceHeight: Int = 0
|
||||
|
||||
override fun getBufferFormat(sourceWidth: Int, sourceHeight: Int): BufferFormat {
|
||||
this.sourceWidth = sourceWidth
|
||||
this.sourceHeight = sourceHeight
|
||||
return RV32BufferFormat(sourceWidth, sourceHeight)
|
||||
// libvlc passes the size the decoder padded the picture to, not the size of the picture (dav1d
|
||||
// pads to a multiple of 128, so 1920x1080 arrives as 1920x1152), and vlc stretches the picture to
|
||||
// fill whatever size is returned. Ask for the size of the track being played instead. The format
|
||||
// is negotiated more than once, and vlc has not selected the track yet on the first calls
|
||||
val player = mediaPlayer
|
||||
val tracks = player?.media()?.info()?.videoTracks()
|
||||
val playingTrack = player?.video()?.track()
|
||||
val track = tracks?.firstOrNull { it.id() == playingTrack } ?: tracks?.singleOrNull()
|
||||
this.sourceWidth = track?.width()?.takeIf { it > 0 } ?: sourceWidth
|
||||
this.sourceHeight = track?.height()?.takeIf { it > 0 } ?: sourceHeight
|
||||
return RV32BufferFormat(this.sourceWidth, this.sourceHeight)
|
||||
}
|
||||
|
||||
override fun allocatedBuffers(buffers: Array<ByteBuffer>) {
|
||||
|
||||
Reference in new issue
Block a user