2

I've several mkv files which have streams similar following. These files may have more than one audio stream and/or subtitles e.t.c. But my problem is mjpeg streams.

Stream #0:0 -> #0:0 (h264 (native) -> h264 (h264_nvenc))
Stream #0:1 -> #0:1 (ac3 (native) -> vorbis (libvorbis))
Stream #0:2 -> #0:2 (mjpeg (native) -> h264 (h264_nvenc))
Stream #0:3 -> #0:3 (mjpeg (native) -> h264 (h264_nvenc))
Stream #0:4 -> #0:4 (mjpeg (native) -> h264 (h264_nvenc))
Stream #0:5 -> #0:5 (mjpeg (native) -> h264 (h264_nvenc))

when i try to encode my video i get this error

Error while opening encoder for output stream #0:2 - maybe incorrect parameters such as bit_rate, rate, width or height

my command is

ffmpeg -i "%%~nf%%~xf" -c:v h264_nvenc -b:v 3000k -minrate 3000k -maxrate 3000k -vf "scale=1280:-2" -acodec libvorbis -ac 6 -c:s copy -map 0 "done/%%~nf.mkv"

how can i ignore mjpeg streams not to be copied to output video, or at least how to properly copy them to output video without getting error.

1
  • @LordNeckbeard yes they are cover arts and yes your suggestion did work perfectly. If you post it as an answer i'll be more than happy to accept it. Also if possible can you explain what -map -v -map V does?
    – Ergec
    Sep 6, 2017 at 18:59

2 Answers 2

10

You can avoid the MJPEG cover art by using properly ordered selective mapping:

-map 0 -map -v -map V

What this does:

  • -map 0 Map all streams from input 0 (which is the first input per ffmpeg command).
  • -map -v Then, ignore all video streams including cover art.
  • -map V Finally, include all non-cover art video streams.

v matches all video streams, and V only matches video streams which are not attached pictures, video thumbnails or cover arts.

For more info see the documentation on stream specifiers and the -map option.

2
  • I should note that the OP's Y problem can't be solved directly by FFmpeg (ignore streams by codec). The X problem (ignore peripheral video streams) can, as shown in this answer.
    – Gyan
    Sep 7, 2017 at 4:57
  • Thanks for the solution. Somehow ffmpeg still cannot work with this type of streams. I am using this weird version from 2022 (ffmpeg version N-107368-gbe983d2354).
    – Shtefan
    Aug 3, 2022 at 7:03
1


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 -vf or -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 Video stream 0. See next option!
-filter:V:0 "scale_npp=w=-2:h=720" and here I say to apply a filter to Video stream 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.

More examples:

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 h264_nvenc.

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. :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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