[vdr] How to convert a JPEG image to an HD video frame?

André Weidemann Andre.Weidemann at web.de
Sun Aug 14 15:31:27 CEST 2011


Hi Klaus,

On 14.08.2011 14:17, Klaus Schmidinger wrote:
> On 14.08.2011 13:43, André Weidemann wrote:
>> Hi Klaus,
>>
>> On 14.08.2011 12:47, Klaus Schmidinger wrote:
>>> On 24.07.2011 20:07, André Weidemann wrote:
>>>> Hi Klaus,
>>>>
>>>> On 23.07.2011 16:57, Klaus Schmidinger wrote:
>>>>> The VDR plugin 'pictures' (part of the original VDR archive)
>>>>> uses a Perl script named 'pic2mpg', which converts a JPEG
>>>>> image into an MPEG frame that can be displayed directly
>>>>> by VDR's primary output device. This is done in essence
>>>>> by the command sequence
>>>>>
>>>>> jpegtopnm $Pict |
>>>>> pnmscale --xscale=$ScaleW --yscale=$ScaleH |
>>>>> pnmpad --black --width $SW --height $SH |
>>>>> ppmtoy4m -F $framerate -I p -S 420mpeg2 |
>>>>> mpeg2enc -f 3 -b 12500 -a $aspect -q 1 -n $system2 -o $Mpeg
>>>>>
>>>>> (see the actual script for the complete working environment).
>>>>>
>>>>> While this works fine for SD video, I can't seen to figure
>>>>> out how to make this work for an HD video output device.
>>>>> The video frame should be a 1080i frame in my case (my tv
>>>>> can't handle 1080p), but could optionally also be 720p or
>>>>> 1080p, depending on the actual tv's capabilities.
>>>>>
>>>>> Can anybody give me a pointer how this script could generate
>>>>> HD video frames?
>>>>
>>>> I have not used mpeg2enc at all. I usually use convert from
>>>> ImageMagick and ffmpeg to convert things. You might want to give those
>>>> two a try.
>>>>
>>>> Here are two simple lines to convert a jpg image to mpeg2:
>>>>
>>>> convert $Pict -background '#000000' -resize 1920x1080 -gravity center
>>>> -extent 1920x1080 /tmp/test.jpg
>>>> ffmpeg -i /tmp/temp.jpg -an -vcodec mpeg2video -b 2500 -s 1920x1080
>>>> -qscale 2 -f mpeg2video $Mpeg
>>>>
>>>> Note: Depending on your distro, ffmpeg may not support mpeg2 video
>>>> encoding.
>>>>
>>>>
>>>> For mpeg4 the ffmpeg line looks like this:
>>>> ffmpeg -i /tmp/temp.jpg -an -vcodec mpeg4 -b 2500 -s 1920x1080 -qscale
>>>> 2 -threads 4 -f mp4 -y $Mpeg
>>>>
>>>> For libx264 it looks like this:
>>>> ffmpeg -i /tmp/temp.jpg -an -vcodec libx264 -vpre lossless_ultrafast
>>>> -s 1920x1080 -qscale 2 -threads 4 -f mp4 $Mpeg
>>>>
>>>> The -vpre parameter requires a preset. They can usually be found under
>>>> /usr/share/ffmpeg/libx264-*.ffpreset.
>>>
>>> Thanks, that was a great help!
>>>
>>> I found this command to work pretty good:
>>>
>>> ffmpeg -i /tmp/test.jpg -an -vcodec libx264 -vpre baseline -s 1920x1080
>>> -qscale 2 -f mpegts -y $Mpeg
>>>
>>> It generates a decently sized TS file (some 100-200 KB) that can be
>>> displayed with
>>> the dvbhddevice plugin on a TT-S2 6400.
>>>
>>> Now I wanted to pipe the output of the convert command into ffmpeg (to
>>> avoid the temporary file),
>>> but that doesn't seem to work:
>>>
>>> convert $Pict -background '#000000' -resize 1920x1080 -gravity center
>>> -extent 1920x1080 - | ffmpeg -i pipe:0 -an -vcodec libx264 -vpre
>>> baseline -s 1920x1080 -qscale 2 -f mpegts -y $Mpeg
>>>
>>> gives me
>>>
>>> ffmpeg version 0.8, Copyright (c) 2000-2011 the FFmpeg developers
>>> built on Jun 23 2011 09:35:04 with gcc 4.5.1 20101208 [gcc-4_5-branch
>>> revision 167585]
>>> configuration: --shlibdir=/usr/lib --prefix=/usr --mandir=/usr/share/man
>>> --libdir=/usr/lib --enable-shared --disable-static --enable-libmp3lame
>>> --enable-libvorbis --enable-libtheora --enable-libspeex --enable-libxvid
>>> --enable-postproc --enable-gpl --enable-x11grab
>>> --extra-cflags='-fomit-frame-pointer -fmessage-length=0 -O2 -Wall
>>> -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables
>>> -fasynchronous-unwind-tables -g -D_LARGEFILE_SOURCE
>>> -D_FILE_OFFSET_BITS=64 -I/usr/include/gsm' --enable-debug
>>> --disable-stripping --enable-libgsm --enable-libschroedinger
>>> --enable-libdirac --enable-avfilter --enable-libvpx --enable-version3
>>> --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libx264
>>> --enable-libdc1394 --enable-pthreads --enable-librtmp
>>> libavutil 51. 9. 1 / 51. 9. 1
>>> libavcodec 53. 7. 0 / 53. 7. 0
>>> libavformat 53. 4. 0 / 53. 4. 0
>>> libavdevice 53. 1. 1 / 53. 1. 1
>>> libavfilter 2. 23. 0 / 2. 23. 0
>>> libswscale 2. 0. 0 / 2. 0. 0
>>> libpostproc 51. 2. 0 / 51. 2. 0
>>> [mp3 @ 0x807bb00] Format mp3 detected only with low score of 1,
>>> misdetection possible!
>>> [mp3 @ 0x807d900] Header missing
>>> Last message repeated 1 times
>>> [mp3 @ 0x807bb00] Could not find codec parameters (Audio: mp1, 0
>>> channels, s16)
>>> [mp3 @ 0x807bb00] Estimating duration from bitrate, this may be
>>> inaccurate
>>> pipe:0: could not find codec parameters
>>
>> Please try the following:
>>
>> convert $Pict -background '#000000' -resize 1920x1080 -gravity center
>> -extent 1920x1080 jpg:- | ffmpeg -f mjpeg -i pipe:0 -an -vcodec
>> libx264 -vpre baseline -s 1920x1080 -qscale 2 -f mpegts -y $Mpeg
>
> This results in a rather blurry image, and I get the following messages:
>
> x264 -vpre baseline -s 1920x1080 -qscale 2 -f mpegts -y x3.mp4
> ffmpeg version 0.8, Copyright (c) 2000-2011 the FFmpeg developers
> built on Jun 23 2011 09:35:04 with gcc 4.5.1 20101208 [gcc-4_5-branch
> revision 167585]
> configuration: --shlibdir=/usr/lib --prefix=/usr --mandir=/usr/share/man
> --libdir=/usr/lib --enable-shared --disable-static --enable-libmp3lame
> --enable-libvorbis --enable-libtheora --enable-libspeex --enable-libxvid
> --enable-postproc --enable-gpl --enable-x11grab
> --extra-cflags='-fomit-frame-pointer -fmessage-length=0 -O2 -Wall
> -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables
> -fasynchronous-unwind-tables -g -D_LARGEFILE_SOURCE
> -D_FILE_OFFSET_BITS=64 -I/usr/include/gsm' --enable-debug
> --disable-stripping --enable-libgsm --enable-libschroedinger
> --enable-libdirac --enable-avfilter --enable-libvpx --enable-version3
> --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libx264
> --enable-libdc1394 --enable-pthreads --enable-librtmp
> libavutil 51. 9. 1 / 51. 9. 1
> libavcodec 53. 7. 0 / 53. 7. 0
> libavformat 53. 4. 0 / 53. 4. 0
> libavdevice 53. 1. 1 / 53. 1. 1
> libavfilter 2. 23. 0 / 2. 23. 0
> libswscale 2. 0. 0 / 2. 0. 0
> libpostproc 51. 2. 0 / 51. 2. 0
> [mjpeg @ 0x807bb00] Estimating duration from bitrate, this may be
> inaccurate
> Input #0, mjpeg, from 'pipe:0':
> Duration: N/A, bitrate: N/A
> Stream #0.0: Video: mjpeg, yuvj422p, 160x120 [PAR 180:180 DAR 4:3], 25
> tbr, 1200k tbn, 25 tbc
> Incompatible pixel format 'yuvj422p' for codec 'libx264', auto-selecting
> format 'yuv420p'
> [buffer @ 0x80847e0] w:160 h:120 pixfmt:yuvj422p tb:1/1000000
> sar:180/180 sws_param:
> [scale @ 0x80871e0] w:160 h:120 fmt:yuvj422p -> w:1920 h:1080
> fmt:yuv420p flags:0x4
> [libx264 @ 0x8087660] Default settings detected, using medium profile
> [libx264 @ 0x8087660] using SAR=1/1
> [libx264 @ 0x8087660] using cpu capabilities: MMX2 Cache64
> [libx264 @ 0x8087660] profile High, level 4.0
> [mpegts @ 0x80851a0] muxrate VBR, pcr every 2 pkts, sdt every 200,
> pat/pmt every 40 pkts
> Output #0, mpegts, to 'x3.mp4':
> Metadata:
> encoder : Lavf53.4.0
> Stream #0.0: Video: libx264, yuv420p, 1920x1080 [PAR 180:180 DAR 16:9],
> q=2-31, 200 kb/s, 90k tbn, 25 tbc
> Stream mapping:
> Stream #0.0 -> #0.0
> frame= 1 fps= 0 q=28.0 Lsize= 45kB time=00:00:00.-4 bitrate=-9287.2kbits/s
> video:42kB audio:0kB global headers:0kB muxing overhead 8.419332%
> frame I:1 Avg QP:27.00 size: 42830
> [libx264 @ 0x8087660] mb I I16..4: 13.3% 85.7% 1.1%
> [libx264 @ 0x8087660] 8x8 transform intra:85.7%
> [libx264 @ 0x8087660] coded y,uvDC,uvAC intra: 62.5% 56.6% 2.5%
> [libx264 @ 0x8087660] i16 v,h,dc,p: 2% 25% 1% 72%
> [libx264 @ 0x8087660] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 13% 36% 10% 6% 7%
> 4% 10% 5% 8%
> [libx264 @ 0x8087660] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 22% 33% 9% 5% 8% 6%
> 10% 4% 4%
> [libx264 @ 0x8087660] i8c dc,h,v,p: 48% 34% 9% 9%
> [libx264 @ 0x8087660] kb/s:8566.00


After reading the ffmpeg man page again I came up with the following line:
convert $Pict -background '#000000' -resize 1920x1080 -gravity center 
-extent 1920x1080 ppm:- | ffmpeg -f image2pipe -vcodec ppm -i pipe:0 -an 
-vcodec libx264 -vpre baseline -s 1920x1080 -qscale 2 -f mpegts -y $Mpeg

I used ppm, because this was the only format ffmpeg and convert could 
agree upon after several attempts.

You can take a look at:

identify -list format
and
ffmpeg -codecs

for a list of all supported formats from ffmpeg and convert.

  André



More information about the vdr mailing list