I'm here also playing with ffmpeg and nvdec/nvenc.
I've found that some options is not good.
I've played with nvdec also, and found that it's better to use
-filter (ffmpeg documentation says it's a "per-stream filtering option") instead of
-af aliases as those aliases touch "all streams of video or audio". Here is a quote from there:
3.1.1 Simple filtergraphs
Simple filtergraphs are those that have exactly one input and output, both of the same type. In the above diagram they can be represented by simply inserting an additional step between decoding and encoding:
| | | |
| decoded | | encoded data |
| frames |\ _ | packets |
|_________| \ /||______________|
\ __________ /
simple _\|| | / encoder
filtergraph | filtered |/
| frames |
Simple filtergraphs are configured with the per-stream -filter option (with -vf and -af aliases for video and audio respectively). A simple filtergraph for video can look for example like this:
_______ _____________ _______ ________
| | | | | | | |
| input | ---> | deinterlace | ---> | scale | ---> | output |
|_______| |_____________| |_______| |________|
Note that some filters change frame properties but not frame contents. E.g. the fps filter in the example above changes number of frames, but does not touch the frame contents. Another example is the setpts filter, which only sets timestamps and otherwise passes the frames unchanged.
Also, there is a stream_type specifiers for video: v and uppercase V.
’v’ matches all video streams, ’V’ only matches video streams which are not attached pictures, video thumbnails or cover arts.
So, my example of command I have "constructed" to mess with nvdec/nvenc on a nVidia GTX755M SLI:
C:\soft\ffmpeg_cuda\media-autobuild_suite\local64\bin-video\ffmpeg.exe -y -vsync 0 -hwaccel cuvid -hwaccel_device 1 -c:V:0 h264_cuvid -i "C:\torrent\Video\Movies\Love's Enduring Promise (2004) [Amazon] WEB-DL 1080p [Ukr.Eng Sub.Eng] [Hurtom].mkv" -f matroska -map 0 -c copy -c:V:0 h264_nvenc -filter:V:0 "scale_npp=w=-2:h=720" -b:V:0 20M -gpu 1 "C:\torrent\Video\Movies\Love's Enduring Promise (2004) [Amazon] WEB-DL 720p [Ukr.Eng Sub.Eng] [Hurtom].mkv"
I'm using ffmpeg, built with this bundle: "media-autobuild_suite"
-y overwrites output file without asking. Be careful to not to make output path the same as input path, I think you may ERASE input mediafile that way using this option.
-vsync 0 I think says to disable vsync for processing, haven't played with it, so for now I can't say if it is useful or so, may be omitted. You may give opinions in comments to say your findings.
-hwaccel cuvid says to decode input videostream with nVidia's video decoder.
-hwaccel_device 1 says to use GPU 1 (zero-based counting) for video DECODING (I have SLI, but seems that ffmpeg is not in friendship with SLI configurations). I use second videocard as it's mainly doing nothing, so works at lesser temperatures (it's dedicated videodevice, connected to PCI-E in my notebook).
-c:V:0 h264_cuvid says to use
h264_cuvid input media decoder for stream 0, a
Video (not an embedded picture)
-i "C:\torrent\Video\Movies\Love's Enduring Promise (2004) [Amazon] WEB-DL 1080p [Ukr.Eng Sub.Eng] [Hurtom].mkv" here I give an input filepath.
-f matroska an output container, I choose an MKV as input is in this format too.
-map 0 that says "map all the input streams to output file in the same order".
-c copy works in conjunction with previous option. Says to use
copy codec for all streams, so all audio, embedded media will be just copied to output file without reencoding. For video transcoding I do there is nothing to do with audio, I just make "lesser-reolution" video in output file.
-c:V:0 h264_nvenc here is (at last!) I say to apply
nvenc encoder to output
0. See next option!
-filter:V:0 "scale_npp=w=-2:h=720" and here I say to apply a filter to
0 (exactly one stream in input file). I here use an
h=720 to make video in "720p" format. Be careful, as videostream may be more wider as 16:9, and you may need to set "w=1280:h=-2" instead for that case to limit using width instead of height. That will be "720p" too, but videoframe is "wider" than needed. Also, you need to check for an existence of
scale_npp filter in your ffmpeg bundle, it is available if you installed CUDA bundle WITH Visual Studio integration.
-b:V:0 20M saying to use bitrate of 20Mbit/s as an upper limit. For VBR it's like an "upper, cut limit", it even can not reach it. You can make it even higher if you will work with higher resolutions. I'm still playing with that parameter and video options, so in this my post I may add some edits comcerning video quality of output stream.
-gpu 1 says to use a GPU 1 (second GPU) too. An video encode and Video decode conveyors in videocard is a different modules, so you can use them seamlessly.
"C:\torrent\Video\Movies\Love's Enduring Promise (2004) [Amazon] WEB-DL 720p [Ukr.Eng Sub.Eng] [Hurtom].mkv" output filepath.
C:\soft\ffmpeg_cuda\media-autobuild_suite\local64\bin-video\ffmpeg.exe -y -i "C:\temp\Video\MOVI0004.avi" -f matroska -map 0 -c copy -c:V:0 h264_nvenc 20M -gpu 1 "C:\temp\Video\Reencoded\MOVI0004.mkv"
Fast reencode of video file which makes transcoding of "Airon Simple Full HD" videofile to MKV using
C:\soft\ffmpeg_cuda\media-autobuild_suite\local64\bin-video\ffmpeg.exe -i "C:\torrent\Video\Series\Death_Note_[BDRip_720p]\Death Note - 01 [BDRip 1280x720 x264].mkv" -f matroska -map 0 -c copy -codec:v h264_nvenc -pix_fmt yuv420p -b:v 8M -vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2" -gpu 1 "C:\torrent\Video\Series\Reencoded\DeathNote_ffmpeg_hvenc5_try1\Death Note - 01 [BDRip 1280x720 x264].mkv"
Here all almost the same, but introducing an option to use "older" format of videoframe -
-pix_fmt yuv420p, which is supported by osmc@Raspberry Pi 3. Take a look also at
-vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2" (actually, it should be
-filter:V:0 pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2"). I've found a recommendation to use "pad" filter instead of scale filter, as with scale you may obtain bad video (bloated, lapped image) in output file. Those maths is a workaround for an error about "not 2-based number in width or height of a video stream". NVENC can complain on width or height of output stream, and this is a workaround: using pad as a video container for "not changing video contents", but adding one line to width or height to make it dividable by 2.
Also, there I'm not using NVDEC as my input video is an anime wiht Hi10P profile, which is niot supported by my GTX755M, unfortunately. :(