Video file transcoded unnecessarily before sending; inflates a 12MB video to almost 90MB!
Bug description
Sending videos takes forever because Signal Android performs some kind of processing prior to sending. This processing inexplicably takes a 12MB H.264 640x360 video with a 167kbps total bitrate, and somehow inflates it to almost 90MB.
Steps to reproduce
- Attach and send a low-quality video approximately 12MB in size. (Media send quality in settings can be High or Standard, makes zero difference)
Actual result: The video takes roughly 5 minutes to process before even starting to upload. The upload then begins for an 88MB file. Expected result: No processing or transcoding delay occurs, the video is uploaded at a size no larger than the source, and the upload is virtually instantaneous. The Signal desktop app behaves exactly this way for the same video file using the same internet connection.
Device info
Device: OnePlus Open Android version: 13 Signal version: 7.3.1
Link to debug log
https://debuglogs.org/android/7.3.1/28a1ea63cbc652c60d2300faaa566648894a66f2f102d751e0d80a25e03d3c37)
Video file meta
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L3
Format settings : CABAC / 4 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference : 4 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 9 min 26 s
Bit rate : 36.9 kb/s
Width : 640 pixels
Height : 360 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 30.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.005
Stream size : 2.49 MiB (21%)
Title :
Writing library : x264 core 164 r3081 19856cc
Encoding settings : cabac=1 / ref=3 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=11 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=1 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=25 / scenecut=40 / intra_refresh=0 / rc_lookahead=40 / rc=crf / mbtree=1 / crf=23.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00
Color range : Limited
Color primaries : BT.709
Transfer characteristics : BT.709
Matrix coefficients : BT.709
Codec configuration box : avcC
Audio
ID : 2
Format : AAC LC
Format/Info : Advanced Audio Codec Low Complexity
Codec ID : mp4a-40-2
Duration : 9 min 26 s
Source duration : 9 min 26 s
Bit rate mode : Constant
Bit rate : 130 kb/s
Channel(s) : 2 channels
Channel layout : L R
Sampling rate : 44.1 kHz
Frame rate : 43.066 FPS (1024 SPF)
Compression mode : Lossy
Stream size : 8.75 MiB (74%)
Source stream size : 8.75 MiB (74%)
Title :
Default : Yes
Alternate group : 1
I am able to experience the delay in upload , but my file size is not inflating , can you upload screenshots
I experienced a similar issue from uploading a video file from iCloud to Signal (on iOS), it got from ca. 49MB inflated to ca. 101MB
I am able to experience the delay in upload , but my file size is not inflating , can you upload screenshots
The original file size is ~12MB.
Hi @cousinit99 , can you also upload the debug log
Hi @cousinit99 , can you also upload the debug log
It's in the OP.
Screencast from 19-04-24 10:07:53 PM IST.webm Hi @cousinit99 , I am actually experiencing a decrease(compression) in file size , am I reproducing correct ? if yes , please pass me the file which is causing the issue
The video is mostly audio in terms of content. The visual is essentially a static picture with subtitles. Very little changes from one frame to the next. The subtitles are all that change visually. There's a great deal of temporal redundancy. My guess is that the encoder is removing the motion vector compression from the original file.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
I am having this same issue. I'm on a Samsung Galaxy S21 and used Samsung's default Gallery app to edit and save a video. The file is about 12MB. When adding it as an attachment in signal, it inflates to about 50MB. I tried both h264 and hevc as input, both were inflated in size. Switching Signal from HD to standard quality helps, but the file is still larger (25.5MB) than the original. The video itself was created by doing a screen recording and then editing (cropping) the screen recording in the official Gallery app.
Edit: I thought it may be related to the high framerate of the input video (58FPS) so I re-encoded to 22FPS. No change. In fact, both the 58FPS version and the 22FPS version result in a 48.6MB Signal attachment. HEVC and h264 also both result in a 48.6MB attachment. The input file size does not seem to make a difference, input framerate, input codec, no change in resulting Signal attachment size. The video is 2:28 long. Does Signal have a minimum kbps it transcodes to?
Edit2: The estimated video file size when attaching is incorrect. The actual file size after sending and downloading the attachment is the same as the original video size. I took a look around in the code for the app and I believe it is this figure which is in err:
private final long fileSizeEstimate;
from here
However, this is my first time looking in this codebase. Someone more familiar with the code could suggest if I'm on the right path.
Bitrate levels used for calculating the estimated file size based on the length of the video.
Doing some napkin math, the L3 size with my input video length comes to around 46,250,000 (e.g. confirms the sizes the app is displaying, after adding audio). I do think this is where the estimated file size is coming from. The confusing part from the user experience is that the displayed size of the attachment is not clearly presented as an estimate, it appears to be the actual size the file will be. Something trivial like location data or other metadata of the file is requiring transcoding/remuxing, rather than the size of the input file. The input file does require transcoding, but the estimated file size far exceeds what the actual output will be after stripping location/other metadata from the file.
So, this is a presentation issue rather than a 'broken compression' issue.
If I'm right, and someone can confirm that, then my initial suggestion for a fix would be to present the estimate differently for files that require transcoding due to size vs due to other reasons.
See e.g. here.
this.transcodeRequired = inputBitRate >= targetQuality.getTargetTotalBitRate() * 1.2 || inSize > upperSizeLimit || containsLocation(mediaMetadataRetriever) || options != null;
if (!transcodeRequired) {
Log.i(TAG, "Video is within 20% of target bitrate, below the size limit, contained no location metadata or custom options.");
}
this.fileSizeEstimate = targetQuality.getByteCountEstimate();
I'm not seeing what you're seeing. The estimated file size during upload matches the completed file size. Here's the metadata for the same video file after uploading and saving. There's clearly been some changes made to the encoder since OP, because the file size has been reduced to some extent, but this reduced size was the estimated file size I just observed during the upload.
The encoder changes various options that results in a larger file size. Incidentally, it now also truncates the file prematurely, which I struggle to even speculate about...
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : [email protected]
Format settings : CABAC / 1 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference : 1 frame
Format settings, GOP : M=1, N=30
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 8 min 58 s
Source duration : 8 min 58 s
Bit rate : 748 kb/s
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate : 30.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.027
Stream size : 48.1 MiB (85%)
Source stream size : 48.1 MiB (85%)
Language : English
Encoded date : 2024-08-09 04:14:04 UTC
Tagged date : 2024-08-09 04:14:04 UTC
Color range : Limited
Color primaries : BT.601 PAL
Transfer characteristics : BT.601
Matrix coefficients : BT.470 System B/G
Codec configuration box : avcC
Audio
ID : 2
Format : AAC LC
Format/Info : Advanced Audio Codec Low Complexity
Codec ID : mp4a-40-2
Duration : 8 min 58 s
Bit rate mode : Constant
Bit rate : 128 kb/s
Channel(s) : 2 channels
Channel layout : L R
Sampling rate : 44.1 kHz
Frame rate : 43.066 FPS (1024 SPF)
Compression mode : Lossy
Stream size : 8.22 MiB (15%)
Language : English
Encoded date : 2024-08-09 04:14:04 UTC
Tagged date : 2024-08-09 04:14:04 UTC
Errors : Missing ID_END
Conformance errors : 1
AAC : Yes
I see, that does look like a separate issue. I have been trying to reproduce and been unable.
I do see there are some changes evident in the media information you provided (reference frames 4->1, resolution increased) and the obvious bitrate increase. I'm looking here to see if I can find what might cause your issue. If you are willing you could look here as well. Having a file that clearly reproduces the problem would help.
As for the truncation, although I haven't looked into it further, I would start by investigating this recent commit, if the truncation problem only started occurring within the last two months, simply because the commit message seems relevant. This increases my suspicions. I have not investigated the truncation further.