Discussion:
[Libav-user] Encoding with no compression with OpenH264
Arthur Muller
2016-03-07 22:46:03 UTC
Permalink
Hello,



I need to create a MP4/OpenH264 file from a series of images. Because the
images are all of a technical nature, I need to have absolutely no
compression. How can I achieve this with OpenH264?



When I used libx264 I set the number of b-frames to zero and it worked fine.
I'm not sure OpenH264 even supports B frames given the discussion I saw
here:



https://github.com/cisco/openh264/issues/1844



If anybody could let me know what parameters I need to set to prevent any
compression and not skip any frames I would appreciate it.



Thanks.



-Arthur
Carl Eugen Hoyos
2016-03-07 23:30:41 UTC
Permalink
Post by Arthur Muller
I need to create a MP4/OpenH264 file from a series of images.
Because the images are all of a technical nature, I need to have
absolutely no compression. How can I achieve this with OpenH264?
Do you mean lossless encoding?
(No compression is not possible with h264.)

I suspect x264 is the only h264 encoding that supports
lossless encoding.

Carl Eugen
Arthur Muller
2016-03-07 23:38:52 UTC
Permalink
Carl,
Post by Carl Eugen Hoyos
Do you mean lossless encoding?
(No compression is not possible with h264.)
Yes. I meant lossless.
Post by Carl Eugen Hoyos
I suspect x264 is the only h264 encoding that supports lossless encoding.
Is this a limitation of OpenH264, or of FFMPEG?

-Arthur
Carl Eugen Hoyos
2016-03-08 01:40:33 UTC
Permalink
Post by Arthur Muller
Post by Carl Eugen Hoyos
I suspect x264 is the only h264 encoding that supports
lossless encoding.
Is this a limitation of OpenH264, or of FFMPEG?
The fact that FFmpeg does not contain a native h264 encoder
(but has to use an external library) is probably a limitation
of FFmpeg, limitations of specific h264 encoders like
openh264 are not limitations of FFmpeg.

Before using lossless h264 encoding, please make sure that
your intended decoder supports it (only FFmpeg supports
decoding of lossless h264).

Carl Eugen
Arthur Muller
2016-03-08 16:19:55 UTC
Permalink
Carl and others,

My constraint is a client that requires MP4 with OpenH264 of the highest possible quality for scientific presentations. I would have been happy with mpeg4; the quality is wonderful. My alternative is to go through the OpenH264 API and code something from scratch given a series of png images. I would rather use FFMPEG if I can. I assume the client's audience will have the proper tools to decode the final video.

So this brings up the question: is there any way to improve on the quality of a OpenH264 MP4 video generated with FFMPEG? Are there calls I can make through the libav API that will enhance the quality of the video - even with some loss? Lossless would be an ideal case. But I don't really need the ideal case. I just thought it would be easier to set a flag this way. But if there is another way of improving the quality of the video I would love to hear that. Honestly, I fear the alternative if I can't use FFMPEG.

I would even be willing to hack the ffmpeg source code if somebody could give me pointers to it. After all, the ffmpeg code is now making calls to the external openH264 library. If I knew what calls to make directly to that library maybe I could make this work.

-Arthur
Carl Eugen Hoyos
2016-03-08 16:38:53 UTC
Permalink
Post by Arthur Muller
My constraint is a client that requires MP4 with OpenH264
of the highest possible quality for scientific presentations.
There should be no problem: Nobody can see the difference
between a high-bitrate yuv420p h264 encoding and a lossless
yuv420p h264 encoding.
(And openh264 only supports yuv420p, this is not your fault.)

What is your problem? Please test current FFmpeg git head and
provide the command line you tested together with the
complete, uncut console output and explain what goes wrong.

Carl Eugen
Arthur Muller
2016-03-08 16:48:44 UTC
Permalink
What is your problem? Please test current FFmpeg git head and provide the command line you tested together with the complete, uncut console output and explain what goes wrong.
Carl,

Fair request.

I can't use the latest version of FFmpeg because it fails to compile if I include openH264. In a previous post I asked about this and was told to use a previous version of FFmpeg. And that worked! I'm using v1.5.1. So I assume this is the best I can do as far as using the latest version of FFmpeg.

And - believe it or not - after using libav for a few months now I'm more familiar with the libav API than with the command line. I do have a series of 18 png files sent by the customer. I can rename them to conform to ffmpeg command line program so I can use the proper formatting.

I hope I'm not asking too much if I ask for help here. Can you tell me what arguments I should pass to ffmpeg (built with openh264!) to generate a high quality, openh264-encoded mp4 file from these files? If it turns out the quality is acceptable then it's a matter of going to my program to see what I may be missing there.

-Arthur
Arthur Muller
2016-03-08 16:59:54 UTC
Permalink
Apologies,

I meant to say I'm using FFmpeg version 3.0 along with OpenH264 version 1.5.1.

-Arthur
Arthur Muller
2016-03-08 17:25:19 UTC
Permalink
Another follow-up: the reason for the low-resolution quality of the video may have been a result of a very high frame rate request on my part. I'm investigating this.

-Arthur
Carl Eugen Hoyos
2016-03-08 17:53:08 UTC
Permalink
Post by Arthur Muller
I meant to say I'm using FFmpeg version 3.0
But only current FFmpeg git head is supported here.

Sorry, Carl Eugen
Arthur Muller
2016-03-08 17:56:36 UTC
Permalink
Carl,
Post by Carl Eugen Hoyos
But only current FFmpeg git head is supported here.
Understood. No apologies needed. Your suggestion to run the ffmpeg command line generated a high quality video, so I started poking around for what could have been different from what I was doing. The only possible culprit I could think of was the frame rate, so I checked that to realize that my default was too high for this problem.

So your suggestion worked. Thanks!

I forwarded the client the resulting video; let's see what they have to say...

-Arthur
Arthur Muller
2016-03-08 19:24:16 UTC
Permalink
More updates:

1) The user is still not happy with the resolution. He says a frame rate of 1 frame per second is too slow and he would prefer to use 10 frames per second instead. And, even at this frame rate, the quality is much lower than either libx264 or mpeg4.

2) Even though I'm unable to share the set of images, I extracted 2 png images - one for a good quality image and one for the bad quality image. I just don't know whether it's ok to attach images within this group. I assume the list administrators are monitoring this exchange. If somebody could let me know whether it's ok to attach a couple of images which are just pieces of the background to show the quality difference I'm getting please let me know.

3) I tried using just the command line to see whether I can get my parameters to generate a good h264.mp4 file. I used the following command:

ffmpeg -framerate 10 -start_number 1 -i image%02d.png -c:v h264 fr10_ffmpeg.mp4

With my 17 images, if I set a frame rate of 10, I get the following message from ffmpeg:

[libopenh264 @ 0x261d840] [OpenH264] this = 0x0x263fa90, Warning:bEnableFrameSkip = 0,bitrate can't be controlled for RC_QUALITY_MODE,RC_BITRATE_MODE and RC_TIMESTAMP_MODE without
enabling skip frame.

4) I also get the following message:

Side data:
unknown side data type 10 (24 bytes)

5) Each png file is around 190K. The h264-encoded mp4 file is 454K; the mpeg4 file is 3.8M. Clearly, the mpeg4 file appears to be storing all images in more detail, while the h264 encoder is not. Using a frame rate of 1 frame/second, the h264-encoded file is 1.7M.

-Arthur
Carl Eugen Hoyos
2016-03-08 20:14:19 UTC
Permalink
Post by Arthur Muller
ffmpeg -framerate 10 -start_number 1 -i image%02d.png
-c:v h264 fr10_ffmpeg.mp4
"-start_number 1" should not be necessary.
Complete, uncut console output missing.

Carl Eugen
Arthur Muller
2016-03-08 20:22:57 UTC
Permalink
Post by Carl Eugen Hoyos
Complete, uncut console output missing.
Here it is.

-Arthur
Post by Carl Eugen Hoyos
ffmpeg -framerate 10 -i image%02d.png -c:v h264 output.mp4
ffmpeg version 3.0 Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
configuration: --enable-libopenh264
libavutil 55. 17.103 / 55. 17.103
libavcodec 57. 24.102 / 57. 24.102
libavformat 57. 25.100 / 57. 25.100
libavdevice 57. 0.101 / 57. 0.101
libavfilter 6. 31.100 / 6. 31.100
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
Input #0, image2, from 'image%02d.png':
Duration: 00:00:01.80, start: 0.000000, bitrate: N/A
Stream #0:0: Video: png, rgb24(pc), 1536x856, 10 fps, 10 tbr, 10 tbn, 10 tbc
[libopenh264 @ 0x2dea7c0] [OpenH264] this = 0x0x2e0c870, Warning:bEnableFrameSkip = 0,bitrate can't be controlled for RC_QUALITY_MODE,RC_BITRATE_MODE and RC_TIMESTAMP_MODE without enabling skip frame.
Output #0, mp4, to 'output.mp4':
Metadata:
encoder : Lavf57.25.100
Stream #0:0: Video: h264 (libopenh264) ([33][0][0][0] / 0x0021), yuv420p, 1536x856, q=2-31, 200 kb/s, 10 fps, 10240 tbn, 10 tbc
Metadata:
encoder : Lavc57.24.102 libopenh264
Side data:
unknown side data type 10 (24 bytes)
Stream mapping:
Stream #0:0 -> #0:0 (png (native) -> h264 (libopenh264))
Press [q] to stop, [?] for help
frame= 18 fps=0.0 q=-0.0 Lsize= 249kB time=00:00:01.80 bitrate=1134.3kbits/s speed=1.94x
video:248kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.347569%
Carl Eugen Hoyos
2016-03-08 20:36:11 UTC
Permalink
Post by Carl Eugen Hoyos
ffmpeg -framerate 10 -i image%02d.png -c:v h264 output.mp4
ffmpeg version 3.0 Copyright (c) 2000-2016 the FFmpeg developers
Still not recommended.
All releases contain more bugs and less features than
current FFmpeg git head, in a few days you can use
newer libopenh264 with current FFmpeg which may (or may
not) improve quality.
Post by Carl Eugen Hoyos
Stream #0:0: Video: png, rgb24(pc), 1536x856,
10 fps, 10 tbr, 10 tbn, 10 tbc
Note that there is an unavoidable quality loss if you
compress rgb input with (baseline) h264 which implies
yuv420p. If quality is really relevant, use qtrle (or
keep png which can also be put into mov).
Post by Carl Eugen Hoyos
Stream #0:0: Video: h264 (libopenh264) ([33][0][0][0] / 0x0021),
yuv420p, 1536x856, q=2-31, 200 kb/s,
If you want to keep this (known to be bad quality)
encoder, you have to use a very high bitrate if you
want the best possible quality.
Test with something like -b:v 20k

Carl Eugen
Arthur Muller
2016-03-08 21:25:25 UTC
Permalink
Carl,

First of all, thanks for your patience on staying with me on this. I truly appreciate it.
Post by Arthur Muller
version 3.0 Copyright (c) 2000-2016 the FFmpeg developers
Still not recommended...
Understood. I may need to get the git head.
Post by Arthur Muller
Stream #0:0: Video: png, rgb24(pc), 1536x856,
10 fps, 10 tbr, 10 tbn, 10 tbc
Note that there is an unavoidable quality loss if you compress rgb input with (baseline) h264 which implies yuv420p. If quality is really relevant, use qtrle (or keep png which can also be put into mov).
I use the command line ffmpeg and asked for the qtrle codec. You are right: the quality is great. I assume that by default it does not keep the png files.

1) How could I force it to do just that?
2) I assume that if I choose to write a MOV file instead I can skip the RGB->YUV conversion step and use the RGB directly. In this case I would call avformat_alloc_output_context2(&oc,NULL,"mov",NULL), correct?
Post by Arthur Muller
Stream #0:0: Video: h264 (libopenh264) ([33][0][0][0] / 0x0021),
yuv420p, 1536x856, q=2-31, 200 kb/s,
If you want to keep this (known to be bad quality) encoder, you have to use a very high bitrate if you want the best possible quality.
Test with something like -b:v 20k
No visible difference between the 2 files.

-Arthur
Carl Eugen Hoyos
2016-03-09 13:40:47 UTC
Permalink
Post by Arthur Muller
I assume that by default it does not keep the png files.
1) How could I force it to do just that?
Use -vcodec copy (or -vcodec png to make sure the original
encoder didn't do anything very stupid).
Post by Arthur Muller
Post by Arthur Muller
Stream #0:0: Video: h264 (libopenh264) ([33][0][0][0] / 0x0021),
yuv420p, 1536x856, q=2-31, 200 kb/s,
If you want to keep this (known to be bad quality) encoder,
you have to use a very high bitrate if you want the best
possible quality.
Test with something like -b:v 20k
No visible difference between the 2 files.
This indicates that either you have done something wrong
or the task ("use yuv420p h264 but please don't use any
quality") was impossible (or the encoder is really
complete crap which I don't know).

Carl Eugen
Arthur Muller
2016-03-09 14:10:43 UTC
Permalink
Carl,
Post by Carl Eugen Hoyos
Use -vcodec copy (or -vcodec png to make sure the original
encoder didn't do anything very stupid).
Are you suggesting I NOT use qtrle when creating MOV files, but rather a png codec?

Arthur
Carl Eugen Hoyos
2016-03-09 14:26:52 UTC
Permalink
Post by Arthur Muller
Use -vcodec copy (or -vcodec png to make sure the original 
encoder didn't do anything very stupid).
Are you suggesting I NOT use qtrle when creating MOV files,
but rather a png codec?
I suggest you test to find out which of the three -
-vcodec copy, -vcodec qtrle, -vcodec png - produces
the smallest output files.
(But I don't remember if png in mov is always supported
by QT.)
Note that -vcodec copy will be significantly faster, that
may also be relevant.

Please consider to set your mailer to text-only.

Carl Eugen
Carl Eugen Hoyos
2016-03-09 14:46:15 UTC
Permalink
Post by Carl Eugen Hoyos
I suggest you test to find out which of the three -
-vcodec copy, -vcodec qtrle, -vcodec png - produces
the smallest output files.
You may also want to test -vcodec png -pred paeth

Carl Eugen
m***@vki.com
2016-03-10 20:14:23 UTC
Permalink
Post by Carl Eugen Hoyos
This indicates that either you have done something wrong
or the task ("use yuv420p h264 but please don't use any
quality") was impossible (or the encoder is really
complete crap which I don't know).
It turns out I found some more information on using FFMPEG with OpenH264. It may not be relevant, but I thought I'd post it here. It reads:
Turns out that much/most of the control over quality-related parameters lies in the codec-specific "private" dictionary. For example: AVCodecContext *c = <your context>;
av_opt_set(c->priv_data, "profile", "baseline", AV_OPT_SEARCH_CHILDREN);
av_opt_set(c->priv_data, "level", "3.0", AV_OPT_SEARCH_CHILDREN);
av_opt_set(c->priv_data, "preset", "slow", AV_OPT_SEARCH_CHILDREN);
av_opt_set(c->priv_data, "crf", "18", AV_OPT_SEARCH_CHILDREN);
Judicious tweaking of these (and other) params gets me the control over quality I was searching for. This then brings up the question: can anybody suggest which private parameters I could/should try to improve the quality of an OpenH264/MP4 video? Preferably, parameters and possible options to try; I will be happy to try the combinations and report back.Thanks.-Arthur 
Stefano Sabatini
2016-03-08 17:29:44 UTC
Permalink
Post by Arthur Muller
Post by Carl Eugen Hoyos
What is your problem? Please test current FFmpeg git head and
provide the command line you tested together with the complete,
uncut console output and explain what goes wrong.
Carl,
Fair request.
I can't use the latest version of FFmpeg because it fails to compile
if I include openH264. In a previous post I asked about this and was
told to use a previous version of FFmpeg. And that worked! I'm using
v1.5.1. So I assume this is the best I can do as far as using the
latest version of FFmpeg.
I posted a patch yesterday to fix that, see:
http://thread.gmane.org/gmane.comp.video.ffmpeg.devel/211120
Post by Arthur Muller
And - believe it or not - after using libav for a few months now I'm
more familiar with the libav API than with the command line. I do
have a series of 18 png files sent by the customer. I can rename
them to conform to ffmpeg command line program so I can use the
proper formatting.
I hope I'm not asking too much if I ask for help here. Can you tell
me what arguments I should pass to ffmpeg (built with openh264!) to
generate a high quality, openh264-encoded mp4 file from these files?
If it turns out the quality is acceptable then it's a matter of
going to my program to see what I may be missing there.
The only parameters used by FFmpeg/libavcodec which affect the quality
are the bitrate and the max_bitrate. I don't know if it possible to
use other parameters exposed by the openh264 API, if that's the case
patches are welcome (TM). So in order to increase the quality you
simply increase the bitrate.

You can have a look at the wrapper code libavcodec/libopenh264enc.c to
see how FFmpeg uses the openh264 API.

HTH.
Arthur Muller
2016-03-08 17:44:54 UTC
Permalink
Stefano,
Post by Stefano Sabatini
http://thread.gmane.org/gmane.comp.video.ffmpeg.devel/211120
Excellent news. Thanks!
Post by Stefano Sabatini
The only parameters used by FFmpeg/libavcodec which affect the quality are the bitrate and the max_bitrate. I don't know if it possible to use other parameters exposed by the openh264 API, if that's the case patches are welcome (TM). So in >order to increase the quality you simply increase the bitrate.
I think you and I arrived at the same conclusion - that's what I wrote in my follow-up message a few minutes ago: I may have been using too high a frame rate.
Post by Stefano Sabatini
You can have a look at the wrapper code libavcodec/libopenh264enc.c to see how FFmpeg uses the openh264 API.
This is useful. Thanks again. Hopefully, I won't need to go there. I reduced the frame rate from a default of 30 frames/second to 1 frame per second. After all, I only have 17 frames and it's a scientific presentation. The video now takes 17 seconds to go through, which is reasonable. At 30 frames per second everything was over in the blink of an eye, so the only way to make this happen was to reduce the quality.

-Arthur
Arthur Muller
2016-03-08 19:30:44 UTC
Permalink
Stefano,
Post by Stefano Sabatini
http://thread.gmane.org/gmane.comp.video.ffmpeg.devel/211120
I clicked on the link above but it took me to an email. Sorry for my ignorance, but how do I download your latest patch?

-Arthur
Carl Eugen Hoyos
2016-03-08 20:16:12 UTC
Permalink
Post by Arthur Muller
I clicked on the link above but it took me to an email.
Sorry for my ignorance, but how do I download your latest patch?
It is part of this email (gmane slightly changes the
format):
http://ffmpeg.org/pipermail/ffmpeg-devel/2016-March/190980.html

You can copy and paste the patch from the email.

Carl Eugen
Stephane Poirier
2016-03-08 02:06:40 UTC
Permalink
Hi Arthur,

I don't know if it can help, but I am encoding raw video (no compression
whatsoever) using codec
AV_CODEC_ID_RAWVIDEO with pixformat AV_PIX_FMT_RGB24 in container .avi file.

The .avi generated are huge but high quality.

I too, am looking for some lossless compression but I haven't found any
way yet. I am a newbie to libav.

Steph


-------- Forwarded Message --------
Subject: [Libav-user] Encoding with no compression with OpenH264
Date: Mon, 7 Mar 2016 14:46:03 -0800
From: Arthur Muller <***@vki.com>
Reply-To: This list is about using libavcodec, libavformat, libavutil,
libavdevice and libavfilter. <libav-***@ffmpeg.org>
To: libav-***@ffmpeg.org



Hello,

I need to create a MP4/OpenH264 file from a series of images. Because
the images are all of a technical nature, I need to have absolutely no
compression. How can I achieve this with OpenH264?

When I used libx264 I set the number of b-frames to zero and it worked
fine. I’m not sure OpenH264 even supports B frames given the discussion
I saw here:

https://github.com/cisco/openh264/issues/1844

If anybody could let me know what parameters I need to set to prevent
any compression and not skip any frames I would appreciate it.

Thanks.

-Arthur
Dirr Bernhard
2016-03-08 08:16:48 UTC
Permalink
Hi Stephane, hi Arthur,

I am using the lossless FFV1 (AV_CODEC_ID_FFV1) codec within libav.
In my case, pixel format is AV_PIX_FMT_YUV422P10 (video source is SMPTE HD-SDI).

The compression ratio depends of course on video contents. I get ratios between 2:1 and 4:1. Lossy compression is of course far more effective, but in turn requires more time to encode.

Regards
Bernhard


I don't know if it can help, but I am encoding raw video (no compression whatsoever) using codec
AV_CODEC_ID_RAWVIDEO with pixformat AV_PIX_FMT_RGB24 in container .avi file.
I too, am looking for some lossless compression but I haven't found any way yet. I am a newbie to libav.


I need to create a MP4/OpenH264 file from a series of images. Because the images are all of a technical nature, I need to have absolutely no compression. How can I achieve this with OpenH264?
Carl Eugen Hoyos
2016-03-08 08:39:17 UTC
Permalink
Post by Stephane Poirier
I don't know if it can help, but I am encoding raw video (no
compression whatsoever) using codec AV_CODEC_ID_RAWVIDEO
with pixformat AV_PIX_FMT_RGB24 in container .avi file.
The .avi generated are huge but high quality.
They are only lossless if your input was RGB (which is
generally less likely than other pix_fmts).
Post by Stephane Poirier
I too, am looking for some lossless compression but I haven't
found any way yet.
There are many lossless encoders in FFmpeg, both common ones
like png and huffyuv, and less common ones like ljpeg and
jpegls. FFV1 is a lossless codec developed within FFmpeg that
is currently standardized.

Please remember not to top-post here, Carl Eugen
Stephane Poirier
2016-03-08 15:49:01 UTC
Permalink
Carl,

FYI - I am not a FFmpeg user, I am a libav user, I generate each frame
with my own c code
using libav.

Steph
Post by Carl Eugen Hoyos
Post by Stephane Poirier
I don't know if it can help, but I am encoding raw video (no
compression whatsoever) using codec AV_CODEC_ID_RAWVIDEO
with pixformat AV_PIX_FMT_RGB24 in container .avi file.
The .avi generated are huge but high quality.
They are only lossless if your input was RGB (which is
generally less likely than other pix_fmts).
Post by Stephane Poirier
I too, am looking for some lossless compression but I haven't
found any way yet.
There are many lossless encoders in FFmpeg, both common ones
like png and huffyuv, and less common ones like ljpeg and
jpegls. FFV1 is a lossless codec developed within FFmpeg that
is currently standardized.
Please remember not to top-post here, Carl Eugen
_______________________________________________
Libav-user mailing list
http://ffmpeg.org/mailman/listinfo/libav-user
-----
No virus found in this message.
Checked by AVG - www.avg.com
Version: 2015.0.6189 / Virus Database: 4540/11769 - Release Date: 03/07/16
Stephane Poirier
2016-03-08 15:47:20 UTC
Permalink
Carl,

FYI - I am not a FFmpeg user, I am a libav user, I generate each frame
with my own c code
using libav.

Steph
Post by Carl Eugen Hoyos
Post by Stephane Poirier
I don't know if it can help, but I am encoding raw video (no
compression whatsoever) using codec AV_CODEC_ID_RAWVIDEO
with pixformat AV_PIX_FMT_RGB24 in container .avi file.
The .avi generated are huge but high quality.
They are only lossless if your input was RGB (which is
generally less likely than other pix_fmts).
Post by Stephane Poirier
I too, am looking for some lossless compression but I haven't
found any way yet.
There are many lossless encoders in FFmpeg, both common ones
like png and huffyuv, and less common ones like ljpeg and
jpegls. FFV1 is a lossless codec developed within FFmpeg that
is currently standardized.
Please remember not to top-post here, Carl Eugen
_______________________________________________
Libav-user mailing list
http://ffmpeg.org/mailman/listinfo/libav-user
-----
No virus found in this message.
Checked by AVG - www.avg.com
Version: 2015.0.6189 / Virus Database: 4540/11769 - Release Date: 03/07/16
Loading...