5

I'm a newbie in video editing on linux and am trying to rotate a video I took with my phone using AVCONV on an Ubuntu 12.04 machine. It all seems to go honky dory except the output is losing quality.

The original video is 1920 x 1080 - 30fps - 1:47 long - 270MB

I initially attempted converting by running:

avconv -i in.mp4 -strict experimental -vf transpose=1 out.mp4

After seeing poor results I enforced frame rate, frame size and compression:

avconv -i in.mp4 -strict experimental -vf transpose=1 -r 30 -s hd1080 -qcomp 1 out.mp4

the resulting video compresses down to 45MB (from 270MB) and is really pixelated. Can you tell me how to avoid this and maintain the original quality of the video?

Here's what the converter spits out: avconv version 0.8.16-4:0.8.16-0ubuntu0.12.04.1, Copyright (c) 2000-2014 the Libav developers built on Sep 16 2014 18:33:49 with gcc 4.6.3 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'tractor_powered_cable-car.mp4': Metadata: major_brand : isom minor_version : 0 compatible_brands: isom3gp4 creation_time : 2015-01-01 10:28:17 Duration: 00:01:47.34, start: 0.000000, bitrate: 20145 kb/s Stream #0.0(eng): Video: h264 (High), yuv420p, 1920x1080, 19974 kb/s, PAR 65536:65536 DAR 16:9, 29.99 fps, 90k tbr, 90k tbn, 180k tbc Metadata: creation_time : 2015-01-01 10:28:17 Stream #0.1(eng): Audio: aac, 48000 Hz, stereo, s16, 155 kb/s Metadata: creation_time : 2015-01-01 10:28:17 File 'out.mp4' already exists. Overwrite ? [y/N] Y [buffer @ 0x21940e0] w:1920 h:1080 pixfmt:yuv420p [transpose @ 0x218dcc0] w:1920 h:1080 dir:1 -> w:1080 h:1920 rotation:clockwise vflip:0 Output #0, mp4, to 'out.mp4': Metadata: major_brand : isom minor_version : 0 compatible_brands: isom3gp4 creation_time : 2015-01-01 10:28:17 encoder : Lavf53.21.1 Stream #0.0(eng): Video: mpeg4, yuv420p, 1080x1920 [PAR 1:1 DAR 9:16], q=2-31, 200 kb/s, 30 tbn, 30 tbc Metadata: creation_time : 2015-01-01 10:28:17 Stream #0.1(eng): Audio: aac, 48000 Hz, stereo, s16, 200 kb/s Metadata: creation_time : 2015-01-01 10:28:17 Stream mapping: Stream #0:0 -> #0:0 (h264 -> mpeg4) Stream #0:1 -> #0:1 (aac -> aac) Press ctrl-c to stop encoding frame= 3218 fps= 46 q=31.0 Lsize= 44341kB time=107.27 bitrate=3386.3kbits/s dup=1 drop=0
video:41833kB audio:2441kB global headers:0kB muxing overhead 0.150674%

Thanks, Shakus

  • Shouldn't we start marking "how to rotate without reencoding" to be duplicates by now? – v010dya May 3 '15 at 6:39
4

There's no way to do this losslessly, other than setting a meta-data flag and depending on players to rotate the video. (This is what cell-phone cameras do).

With avconv / ffmpeg, what you're doing is using your decoded -> transposed video as a source to encode with x264. See https://trac.ffmpeg.org/wiki/Encode/H.264 for how to do this. IDK where you found a suggestion to use -qcomp 1, but changing the quantizer compression curve to an extreme is usually not what you want with x2641.

You shouldn't need to enforce framerate, either. Phone cam videos are sometimes variable frame rate, so you should use -vsync 2 if you're outputting to mp4. (vsync 2 is the default for mkv).

Anyway, this should work:

ffmpeg -i in.mp4 -codec copy -map 0 -movflags +faststart -vf transpose=1 -c:v libx264 -preset slower -crf 22 -vsync 2 out.mp4

(also include -metadata:s:v rotate="" if needed, see LordNeckBeard's comment.)

See the encode guide for details on how to choose crf and preset.

-map 0 maps any extra metadata streams, like chapters, into the output file.

-codec copy copies the audio untouched, instead of decoding and re-encoding.

Since you're re-encoding anyway, you might want to stabilize your video with vid.stab. See https://askubuntu.com/questions/405244/deshaking-videos-using-script for instructions (and a note on avconv vs. ffmpeg). The command I posted works with avconv as well as ffmpeg, but Ubuntu's avconv isn't built with vid.stab.


Footnote 1: -qcomp 1 is pure constant quality (or constant-something, maybe quantization, which isn't exactly the same thing as quality). i.e. not reducing quality in high-complexity scenes at all. (So you potentially spend a lot of bits in a few short scenes / shots / segments which make up a small fraction of the total time of the video, leaving less bitrate for the stuff where those bits gain you more quality. -qcomp 0 is basically CBR.

The default 0.6 is often a good choice, but some people like to boost it some, maybe to 0.7 or 0.8, to get closer to constant-QP. -tune grain (try to preserve film-grain instead of smoothing it out) sets qcomp=0.8, among many other psy settings. (most importantly -psy-rd <unset>:0.25 to favour more energy, even if it doesn't match the source.)

qcomp Anywhere in the middle smooths out the bitrate curve some.

| improve this answer | |
  • 1
    Don't forget to reset the stream rotation metadata if you use a filter to "physically" rotate; otherwise it will be copied to the output and hilarity may ensue. If the metadata exists (check the ffmpeg console output), then add -metadata:s:v rotate="" to your command. – llogan May 4 '15 at 7:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.