[FFmpeg-trac] #9589(undetermined:new): Progress-report line need be constrained to 80 characters at maximum
FFmpeg
trac at avcodec.org
Fri Jan 7 22:19:48 EET 2022
#9589: Progress-report line need be constrained to 80 characters at maximum
-------------------------------------+-------------------------------------
Reporter: blit2z | Type: defect
Status: new | Priority: normal
Component: | Version:
undetermined | unspecified
Keywords: Progress- | Blocked By:
report CR |
Blocking: | Reproduced by developer: 0
Analyzed by developer: 0 |
-------------------------------------+-------------------------------------
As you know, "ffmpeg" displays a progress-report line like the following.
Note that there are four white spaces at the end.
{{{
frame= 315 fps=0.0 q=29.0 size= 0kB time=00:00:08.73 bitrate=
0.0kbits/s speed=17.4x
}}}
The width of every progress-report line printed by "ffmpeg" is 97
characters, and ends with a Carriage Return character (CR 0x0D \r).
However, it is strongly advisable that the width of progress-report line
ending with CR should be constrained to 80 characters at maximum. Let me
explain why.
The problem that arises when the progress-report line is wider than 80
characters is a generic problem that occurs with not only "ffmpeg" but any
CLI program that uses CR to implement a progress-report line. Thus,
before I continue to talk about the progress-report line of "ffmpeg", let
me expound the Carriage Return character (CR 0x0D \r) and a progress-
report line in general which is NOT specific to "ffmpeg".
As used by some command-line programs on Unix-like systems, the Carriage
Return character (CR 0x0D \r) is useful to implement a progress-report
line.
To see what a progress-report line is, save the following code as
"cr_test_progress.sh", and execute it on a terminal window whose width is
80 characters or more.
{{{
#!/bin/bash
printf %b 'processed=10% speed=7.3mbits/s '; sleep 1; printf %b '\r'
printf %b 'processed=20% speed=7.0mbits/s '; sleep 1; printf %b '\r'
printf %b 'processed=30% speed=8.8mbits/s '; sleep 1; printf %b '\r'
printf %b 'processed=40% speed=7.3mbits/s '; sleep 1; printf %b '\r'
printf %b 'processed=70% speed=14.4mbits/s'; sleep 1; printf %b '\r'
printf %b 'processed=80% speed=7.1mbits/s '; sleep 1; printf %b '\r'
printf %b 'processed=100% speed=12.8mbits/s\n'
}}}
A progress-report line refreshes with new information, overwriting and
deleting the old line. The Carriage Return character (CR 0x0D \r) causes
the carriage (or cursor or caret) to return to the first column on the
current terminal row without advancing the carriage to the line below.
Hence the current terminal row will be overwritten. If each progress-
report line ended with a newline character (LF 0x0A \n) instead of a
carriage return character (CR 0x0D \r), then the line would not be
overwritten, and each old line of the progress-report would persist where
they are and would build up; thus, the terminal screen would be flooded
with obsolete information.
By the way, let me use the term "pseudo-line" for a line ending with CR,
when it is desired to distinguish it from a full line ending with a
newline character (LF 0x0A \n). When it is unimportant to distinguish the
two, I may call both kinds of line just a "line". Also note that a
"terminal line", that is, a line on a terminal screen, is sometimes should
be distinguished from a line in a file or a line being sent to the
terminal.
If any line in general (regardlessly of whether containing CR or not) is
longer than the width of the terminal window, then the terminal wraps the
line. Whether this wrap is hard or soft depends on the terminal program.
In most cases, the factory default for the width of a terminal window is
80. Thus, suppose that the terminal window is 80 characters wide.
Suppose also that a progress-report pseudo-line ending with CR is 90
characters long. Then, the terminal wraps it into two terminal lines (80
and 10), and brings the cursor back to the beginning of the 10-character-
long latter line.
Do not expect as if the CR would cause the terminal to move the cursor
back to the beginning of the 80-character-long first part. In fact, only
the 10-character-long latter part is deleted and overwritten; the 80
-character-long first part is never deleted and hence persists there.
Thus, the 80-character-long first part builds up, as the progress-report
pseudo-line refreshes repeatedly.
To see this behavior, save the following code as "cr_test_wide.sh", and
execute it on a terminal window whose width is exactly 80 characters.
When copying, pasting and saving the following code, make sure not to
hard-wrap it.
{{{
#!/bin/bash
echo ' 1 2 3 4 5 6
7 8'
echo
'12345678901234567890123456789012345678901234567890123456789012345678901234567890'
printf %b
'11111111111111111111111111111111111111111111111111111111111111111111111111111111ABCDEFGHIJ';
sleep 2; printf %b '\r'
printf %b
'22222222222222222222222222222222222222222222222222222222222222222222222222222222abcdefghij';
sleep 2; printf %b '\r'
printf %b
'33333333333333333333333333333333333333333333333333333333333333333333333333333333QRSTUVWXYZ';
sleep 2; printf %b '\r'
printf %b
'44444444444444444444444444444444444444444444444444444444444444444444444444444444qrstuvwxyz\n'
}}}
Each line consists of 80 digits followed by 10 alphabets, totaling 90
visible characters. The first three lines are pseudo-lines ending with
CR. The last line ends with LF. Assuming the window width is 80
characters, the terminal wraps each line into 80 digits and 10 alphabets.
For each pseudo-line, only the 10 alphabets are deleted and overwritten;
and all the digits persist and build up.
Note that this behavior that CR causes the cursor to return to the
beginning of the latter row is regardless of whether the wrap is hard or
soft. This behavior is reasonable for hardwrapped rows. Upon
encountering a CR, the terminal simply returns the cursor to the first
column of the current terminal row. For softwrapped rows, this behavior
may be somewhat counter-intuitive. Nevertheless, this is how terminals
behave upon encountering a CR. This is true for Linux (GNOME Terminal on
Cinnamon desktop and MATE Terminal on MATE desktop) and macOS
(Terminal.app).
To reproduce the problem with "ffmpeg", set the width of the terminal
window to 80 characters, and run any "ffmpeg" command (such as the
following) that prints a progress-report line. It seems that any
progress-report line printed by "ffmpeg" is 97 characters long including
trailing spaces. The following command generates an mp4 video which is
simply a black burst with no interesting pictures, and whose resolution is
640x480 and whose duration is 240 seconds. The file size of the resultant
video is approximately 250 KB. As it generates the video, it reports the
progress. Make sure that the width of the terminal window to 80
characters.
{{{
ffmpeg -f lavfi -i color=s=640x480:r=30:d=240:c=0x000000 -f mp4
black_480.mp4
}}}
It is common that the width of terminal window is 80 characters by default
out of the box. It is strongly advisable that the width of progress-
report line ending with CR should be constrained to 80 characters at
maximum.
An exemplar program that conforms to this constraint is "curl". "curl"
wisely constrains the width of its progress-report line to 78 characters.
The reason why the progress-report line of `ffmpeg` is very long and why
that of `curl` is concise follows. On each progress-report line, `ffmpeg`
prints not only values but also field names. On the other hand, `curl`
prints only values on each progress-report line, and prints field names on
the header only once, separating field names from values.
Here is an example of progress report by `curl`. The header with field
names ends with LF, is printed only once, and stays there permanently.
The values are on the pseudo-line ending with CR, and are repeatedly
refreshed and updated.
{{{
% Total % Received % Xferd Average Speed Time Time Time
Current
Dload Upload Total Spent Left
Speed
39 133M 39 52.1M 0 0 46.9M 0 0:00:02 0:00:01 0:00:01
42.8M
}}}
It is desirable that "ffmpeg" should constrain the width of progress-
report line to 80 characters at maximum as "curl" does.
--
Ticket URL: <https://trac.ffmpeg.org/ticket/9589>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list