Saturday, February 07, 2009

the dark of winter has me in its grasp

The Mule has been working long hours for himself and you, valued video compatriots!

That sounds positive, as it should be. Though in truth, I am feeling less positive than that message implies. Personal and professional life has got me down, but is par for the course these days. Oh well. A pithy quote to pick myself up would be rather nice here. Instead, let me regale you of the past weeks activities, as some of the tribulations may help individuals in similar need.

Sh*t Storm
This week, as I look back at my notes, I see a hailstorm of problems that I've dealt with:
-Fedora 10, x86-64 spontaneous system lockups/reboots (workaround: noapic on kernel cmd line)
-pulseaudio screwing up my audio
-usb keyboard stops working (workaround: disable keyboard acceleration)
-Gnome session saving broken (the workaround seems more of a pain than its worth)
-1080p editing eats RAM! (bought more RAM)
-Belkin firewire card causing reboots
-I didn't order my RAM in matched pairs, so I'm stuck waiting until Monday for RAM! (finally got it!)
-Evolution has trouble fetching mail from Comcast's POP servers, so I've reverted to use Pine (now "Alpine")

Needless to say, my productivity dropped and frustration was running high.

The Good News
Knock on wood, I think I was able to workaround the spontaneous reboots using "noapic" boot option to the kernel. Whereas the box was rebooting every six hours, now it has been up a full two days without a reboot! Of course, this isn't a true fix and I will have to submit a bug to the Fedora team. And the other problems still exist.

Most importantly, I've discovered a new scheme for solid, fast 1080P editing in Cinelerra:
1) convert Canon 5D video to MPEG2-TS
2) import into Cinelerra
3) render to any format you need

A Couple of Options
In my initial post on editing Canon 5D video, I found that the easiest way for me to get content from the Canon 5D into Cinelerra was using a conversion to MJPEG. However, the drawback with using mjpeg is that the image quality is lacking. Specifically, the output is darker than the original content. So over the past week, I found two solutions to convert the beautiful output of the Canon:

1) convert to H264 using this two pass string:
#CONVERT CANON USING H264, pass 1
ffmpeg -y -i INPUT.MOV -an -v 1 -threads 8 -vcodec libx264 -aspect 1.7777 -b 9000k -bt 7775k -refs 1 -loop 1 -deblockalpha 0 -deblockbeta 0 -parti4x4 1 -partp8x8 1 -me full -subq 1 -me_range 21 -chroma 1 -slice 2 -bf 0 -level 30 -g 300 -keyint_min 30 -sc_threshold 40 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.7 -qmax 51 -qdiff 4 -i_qfactor 0.71428572 -maxrate 10000k -bufsize 2M -cmp 1 -f mp4 -pass 1 /dev/null

#CONVERT CANON USING H264, pass 2
ffmpeg -y -i INPUT.MOV -v 1 -threads 8 -vcodec libx264 -aspect 1.7777 -b 9000k -bt 7775k -refs 1 -loop 1 -deblockalpha 0 -deblockbeta 0 -parti4x4 1 -partp8x8 1 -me full -subq 1 -me_range 21 -chroma 1 -slice 2 -bf 0 -level 30 -g 300 -keyint_min 30 -sc_threshold 40 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.7 -qmax 51 -qdiff 4 -i_qfactor 0.71428572 -maxrate 10000k -bufsize 2M -acodec libfaac -ab 160k -ar 48000 -ac 2 -cmp 1 -f mp4 -pass 2 OUTPUT.mp4


Now, this H264 content is beautiful, will import into Cinelerra and is editable. However, I found that when I went to render the final output, four minutes of the 1080p, H264 content took SIX HOURS to render!! That is unacceptable. I believe the lengthy render time has something to do with the color space or internal conversion that Cinelerra is doing. This bears further research.

If you're not familiar with H264 (x264 libraries on Linux), here's some useful H264 reference material.

2) convert to MPEG2-TS

Converting Canon to 1080p, MPEG2-TS
Now, there are a few steps here.

a. Take a file from the Canon and use ffmpeg to pass a lossless yuv4mpegpipe stream into mpeg2enc, with the result a video stream with no audio:
ffmpeg -i INPUT.MOV -threads 8 -s 1920x1088 -f yuv4mpegpipe - | mpeg2enc --multi-thread 8 --verbose 0 --aspect 3 --format 13 --frame-rate 5 --video-bitrate 24000 --nonvideo-bitrate 384 --interlace-mode 0 --force-b-b-p --video-buffer 448 --video-norm n --keep-hf --no-constraints --sequence-header-every-gop --min-gop-size 6 --max-gop-size 6 -o OUTPUT.m2v

Next, render out the audio:
ffmpeg -y -i INPUT.MOV -acodec mp2 -ar 44100 -ab 256k -ac 2 OUTPUT.m2a

Using mplex, mux the video and audio streams together:
mplex -f 3 -b 2000 OUTPUT.m2a OUTPUT.m2v -o OUTPUT.ps

Using VLC, convert the MPEG2-PS into an MPEG2-TS:
cvlc OUTPUT.ps --sout '#duplicate{dst=std{access=file,mux=ts,dst="OUTPUT.m2t"}}' vlc://quit

Update 2009/02/13
I've found that VLC is not writing proper keyframes at the beginning of the converted MPEG-PS video output from mplex. This is only for 1080p video. The VLC command for 720p video still works. For the 1080p, I've found a workaround using our savior, ffmpeg:
ffmpeg -y -i OUTPUT.ps -acodec copy -f mpegts -qscale 1 OUTPUT.m2t
*** end update ***

I used this method to output a new version of my Water video from Cinelerra to Vimeo here:
/2009/01/water-new-canon-5d-video.html

The quality and the colors are definetly improved upon over the old version. However, the larger file size is a drawback (479MB for 4m16s of video). So I'd like to get the H264 output without compression artifacts during the scenes with a lot of motion. So now its time to figure that out. Erg.

In general though, I think this is some good news!

Until the next time,
the mule

5 comments:

Unknown said...

For what its worth, here's my modified version of the script. Several of the args don't work with the current version of ffmpeg, so I updated it with help from another site. I'm not certain it's exactly the same, but it looks pretty good.

If you use this, watch out for the "-r 59.94" which sets the frame rate for my camera (Sanyo FH1) and the modified bitrate params.

#!/bin/bash
# direct to H264
# Adapted from:
# http://crazedmuleproductions.blogspot.com/2009/02/dark-of-winter-has-me-in-its-grasp.html
# with help from:
# http://www.itbroadcastanddigitalcinema.com/ffmpeg_howto.html

opts="-v 1 -threads 3 -f mp4 -r 59.94"

vargs="-vcodec libx264 -b 7800k -bt 6500k -maxrate 10000k -refs 1 -flags +loop -deblockalpha 0 -deblockbeta 0 -partitions +parti8x8+parti4x4+partp8x8+partp4x4+partb8x8 -me_method full -subq 1 -me_range 21 -cmp +chroma -flags +loop+slice -bf 0 -level 30 -g 300 -keyint_min 30 -sc_threshold 40 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.7 -qmax 51 -qdiff 4 -i_qfactor 0.71428572 -bufsize 2M"

aargs="-acodec libfaac -ab 160k -ar 48000 -ac 2"

#CONVERT CANON USING H264, pass 1
ffmpeg -y -i "$1" $opts $vargs -an -pass 1 /dev/null

#CONVERT CANON USING H264, pass 2
ffmpeg -y -i "$1" $opts $vargs $aargs -pass 2 "$2.mp4"

Cacasodo said...

Thanks wrzwicky! I appreciate the additional info.
--the mule--

Howard said...

I've followed the links to your blog, and you've given me hope that I may succeed in getting the images from my 7D into Cinelerra. So far, however, the scripts don't quite work for me. Some call libfaac, which despite all my efforts remains an "Unknown encoder ..." The script into MPEG2-TS almost works, but I get this message:

++ WARN: [mpeg2enc] Specified display frame-rate 30.00 will over-ride
++ WARN: [mpeg2enc] (different!) frame-rate 29.97 of the input stream
**ERROR: [mpeg2enc] display_horizontal_size must be in range 0...16383

The warning seems correct, but anticipated. The error, on the other hand, I can't get rid of.

So I need either to get rid of the error, or find a way to access libfaac.

Any thoughts will be appreciated.

Anonymous said...

Hi Cacasodo

Great tutorial

but i can't run it

gives me this error:


ffmpeg -i MVI_0952.MOV -threads 8 -s 1920x1088 -f yuv4mpegpipe - | mpeg2enc --multi-thread 8 --verbose 0 --aspect 3 --format 13 --frame-rate 5 --video-bitrate 24000 --nonvideo-bitrate 384 --interlace-mode 0 --force-b-b-p --video-buffer 448 --video-norm n --keep-hf --no-constraints --sequence-header-every-gop --min-gop-size 6 --max-gop-size 6 -o OUTPUT.m2v
FFmpeg version git-N-28713-g65daa94, Copyright (c) 2000-2011 the FFmpeg developers
built on Mar 30 2011 09:20:16 with gcc 4.6.0
configuration: --prefix=/usr --enable-gpl --enable-libmp3lame --enable-libvorbis --enable-libfaac --enable-libxvid --enable-libx264 --enable-libvpx --enable-libtheora --enable-postproc --enable-shared --enable-x11grab --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libschroedinger --enable-libopenjpeg --enable-version3 --enable-nonfree --enable-runtime-cpudetect --disable-debug
libavutil 50. 40. 0 / 50. 40. 0
libavcodec 52.116. 0 / 52.116. 0
libavformat 52.104. 0 / 52.104. 0
libavdevice 52. 4. 0 / 52. 4. 0
libavfilter 1. 76. 0 / 1. 76. 0
libswscale 0. 13. 0 / 0. 13. 0
libpostproc 51. 2. 0 / 51. 2. 0

Seems stream 0 codec frame rate differs from container frame rate: 50000.00 (50000/1) -> 25.00 (25/1)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'MVI_0952.MOV':
Metadata:
major_brand : qt
minor_version : 537331968
compatible_brands: qt CAEP
creation_time : 2011-04-20 17:56:55
Duration: 00:00:23.12, start: 0.000000, bitrate: 46934 kb/s
Stream #0.0(eng): Video: h264 (Constrained Baseline), yuvj420p, 1920x1088, 45395 kb/s, 25 fps, 25 tbr, 25k tbn, 50k tbc
Metadata:
creation_time : 2011-04-20 17:56:55
Stream #0.1(eng): Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
Metadata:
creation_time : 2011-04-20 17:56:55
[buffer @ 0x88ffff0] w:1920 h:1088 pixfmt:yuvj420p
[yuv4mpegpipe @ 0x88fec70] ERROR: yuv4mpeg only handles yuv444p, yuv422p, yuv420p, yuv411p and gray pixel formats. Use -pix_fmt to select one.
Output #0, yuv4mpegpipe, to 'pipe:':
Metadata:
major_brand : qt
minor_version : 537331968
compatible_brands: qt CAEP
creation_time : 2011-04-20 17:56:55
encoder : Lavf52.104.0
Stream #0.0(eng): Video: rawvideo, yuvj420p, 1920x1088, q=2-31, 200 kb/s, 90k tbn, 25 tbc
Metadata:
creation_time : 2011-04-20 17:56:55
Stream mapping:
Stream #0.0 -> #0.0
Could not write header for output file #0 (incorrect codec parameters ?)
**ERROR: [mpeg2enc] Could not read YUV4MPEG2 header: system error (failed read/write)!


I have searched and i try but no luck


Best Regards
ArchGalileu

Cacasodo said...

Gaspar,
Given this error:
ERROR: yuv4mpeg only handles yuv444p, yuv422p, yuv420p, yuv411p and gray pixel formats. Use -pix_fmt to select one.

It seems that the yuv4mpeg handler in FFmpeg doesn't like your video input stream. You should convert the frame format to one FFmpeg/yuv4mpeg likes using -pix_fmt:
"Use -pix_fmt to select one."

Try that first.
-the mule-