Invalid key_frame(I) and P- frame sequence in h264 Binary stream - ffmpeg

I am getting video from USB webcam and encoding into h.264 raw stream as follows...
ffmpeg.exe -f dshow -rtbufsize 200M -i video="Logitech HD Webcam C270" -vcodec libx264 -preset ultrafast -tune zerolatency -g 30 -s 480x640 -buf
size:v 50M output.h264
I am expecting 1-Key frame and 29-P Frame(with SPS/PPS) in output.h264 stream.But I am not getting the expected result.However video is playing fine.
I tried to get Metadata of same file using ffprob ..
ffprobe -show_frames videofilename.h264 > outputlogfile.txt
Here I can see proper sequence 1-Key frame and 29-P frames.But if we open h264 file in binary reader(I am using HDX) I can see Key/P frames not in proper sequence.
You can download h264 sample and ffprob logs from below links.
https://www.dropbox.com/s/3ghpkqdc36wdgxr/TimerSample.h264?dl=0
https://www.dropbox.com/s/gdn64004o0udrfk/TimerSample.txt?dl=0
You can find binary sequence of same file from here (filtered by start code)
Please let me know whether i am missing some filter. Thank you.

The highlighted elements in the screenshot show that the bitstream begins with a SPS unit, then a PPS unit, then a SEI unit, followed by slices of an IDR picture, then non-reference picture slices. This is all normal and expected.
Use
ffmpeg -i videofilename.h264 -c copy -bsf:v trace_headers -f null -
to see a text dump of the parsing of the bitstream.

Related

Remove all non key frames from video without re-encoding

I have a HEVC mkv video from which I need to remove all but key frames without re-encoding whole thing.
I found out that I can extra key frames using this
ffmpeg -i full.mkv -c:v copy -vf "select=eq(pict_type\,PICT_TYPE_I)" key.mkv
but I get:
Filtergraph 'select=eq(pict_type\,PICT_TYPE_I)' was defined for video output stream 0:0 but codec copy was selected.
Filtering and streamcopy cannot be used together.
What do I do?
You'll have to use the bitstream filter filter_units for this:
ffmpeg -i test.mkv -c copy -map v -bsf:v "filter_units=pass_types=16-23|32-34" key.mkv
This will only pass through random access pictures from the HEVC stream. This should cover most of them but HEVC has more keyframes types than H.264 so I'll update the types above if there are some I've missed.

FFmpeg efficient capture from rtsp ipcamera

I need to capture an audio/video rtsp stream uncompressed in a file from ipcamera. Audio (pcm_alaw) and video (h264) must be synchronized. It is necessary that the file does not get corrupted if the camera loses the connection for a few moments (mp4).
At the moment I use the command below, but the ts codec does not support pcm_alaw and therefore the audio is not heard:
ffmpeg -stimeout 2000000 -rtsp_transport tcp -i rtsp://admin:1234#192.168.5.22/h264 -c:v copy -c:a copy -f mpegts -y main.ts
I use the mpegts codec because I need to check the duration of the capture in real time with the command:
ffprobe -i /home/pi/NAS/main.mov -show_entries format=duration -v quiet -of csv="p=0"
If i use mkv or avi its output would be:
N/A
The verification of the duration is important because I capture files of about 3 hours and at my choice I perform some data while the capture is in progress. I prefer not to compress the audio because I have often noticed some asynchrony with respect to the video when cutting.
Thank you.
Instead of -c:a copy you can use -c:a aac or -c:a mp3 to convert the audio stream before you save it.
MPEG-TS h264 is only compatible with mp3 or aac (source).

FFMPEG reduce fps for live h264 stream with direct copy

I found different articles on changing the fps with ffmpeg but none of them is matching for my exact purposes.
There is an ffmpeg command like below:
ffmpeg -i RTSPCAMERAPRODUCEH264 -c:v copy -an -movflags +frag_keyframe+empty_moov -f mp4
This will remux my camerastream to fragmented mp4 perfectly.
Is there a way to force ffmpeg to lower the FPS to save bandwidth?
I.e. camera streams 30fps, it needs 1Mbps for fmp4 (sample numbers!):
I'd like to know if it's possible to lower the FPS and get an output stream for which 500kbps (50% of original is enough) without re-encoding.
ffmpeg -r 1 -i RTSPCAMERAPRODUCEH264 -c:v copy -an -movflags +frag_keyframe+empty_moov -f mp4
and
ffmpeg -i RTSPCAMERAPRODUCEH264 -c:v copy -an -movflags +frag_keyframe+empty_moov -r 1 -f mp4
do not seem to work.
A temporally coded video stream (like one with H264 codec) cannot arbitrarily drop intermediate packets, so this is not possible. Only whole or trailing part of GOPs may be dropped.

FFMPEG: how to save input camera stream into the file with the SAME codec format?

I have the camera-like device that produces video stream and passes it into my Windows-based machine via USB port.
Using the command:
ffmpeg -y -f vfwcap -i list
I see that (as expected) FFmpeg finds the input stream as stream #0.
Using the command:
ffmpeg -y -f vfwcap -r 25 -i 0 c:\out.mp4
I can successfully save the input stream into the file.
From the log I see:
Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 240x320, 25 tbr, 1k tbn, 25 tbc
No pixel format specified, yuv422p for H.264 encoding chosen.
So, my input format is transcoded to yuv422p.
My question:
How can I cause FFmpeg to save my input video stream into out.mp4 WITHOUT transcoding - actually, to copy input stream to output file as close as possible, with the same format?
How can I cause ffmpeg to save my input videostream into out.mp4 WITHOUT transcoding
You can not. You can stream copy the rawvideo from vfwcap, but the MP4 container format does not support rawvideo. You have several options:
Use a different output container format.
Stream copy to rawvideo then encode.
Use a lossless encoder (and optionally re-encode it after capturing).
Use a different output container format
This meets your requirement of saving your input without re-encoding.
ffmpeg -f vfwcap -i 0 -codec:v copy rawvideo.nut
rawvideo creates huge file sizes.
Stream copy to rawvideo then encode
This is the same as above, but the rawvideo is then encoded to a more common format.
ffmpeg -f vfwcap -i 0 -codec:v copy rawvideo.nut
ffmpeg -i rawvideo.nut -codec:v libx264 -crf 23 -preset medium -pix_fmt yuv420p -movflags +faststart output.mp4
See the FFmpeg and x264 Encoding Guide for more information about -crf, -preset, and additional detailed information on creating H.264 video.
-pix_fmt yuv420p will use a pixel format that is compatible with dumb players like QuickTime. Refer to colorspace and chroma subsampling for more info.
-movflags +faststart relocates the moov atom which allows the video to begin playback before it is completely downloaded by the client. Useful if you are hosting the video and users will view it in their browser.
Use a lossless encoder
Using huffyuv:
ffmpeg -f vfwcap -i 0 -codec:v huffyuv lossless.mkv
Using lossless H.264:
ffmpeg -f vfwcap -i 0 -codec:v libx264 -qp 0 lossless.mp4
Lossless files can be huge, but not as big as rawvideo.
Re-encoding the lossless output is the same as re-encoding the rawvideo.

Using FFMPEG to losslessly convert YUV to another format for editing in Adobe Premier

I have a raw YUV video file that I want to do some basic editing to in Adobe CS6 Premiere, but it won't recognize the file. I thought to use ffmpeg to convert it to something Premiere would take in, but I want this to be lossless because afterwards I will need it in YUV format again. I thought of avi, mov, and prores but I can't seem to figure out the proper command line to ffmpeg and how to ensure it is lossless.
Thanks for your help.
Yes, this is possible. It is normal that you can't open that raw video file since it is just raw data in one giant file, without any headers. So Adobe Premiere doesn't know what the size is, what framerate ect.
First make sure you downloaded the FFmpeg command line tool. Then after installing you can start converting by running a command with parameters. There are some parameters you have to fill in yourself before starting to convert:
What type of the YUV pixel format are you using? The most common format is YUV4:2:0 planar 8-bit (YUV420p). You can type ffmpeg -pix_fmts to get a list of all available formats.
What is the framerate? In my example I will use -r 25 fps.
What encoder do you want to use? The libx264 (H.264) encoder is a great one for lossless compression.
What is your framesize? In my example I will use -s 1920x1080
Then we get this command to do your compression.
ffmpeg -f rawvideo -vcodec rawvideo -s 1920x1080 -r 25 -pix_fmt yuv420p -i inputfile.yuv -c:v libx264 -preset ultrafast -qp 0 output.mp4
A little explanation of all other parameters:
With -f rawvideo you set the input format to a raw video container
With -vcodec rawvideo you set the input file as not compressed
With -i inputfile.yuv you set your input file
With -c:v libx264 you set the encoder to encode the video to libx264.
The -preset ultrafast setting is only speeding up the compression so your file size will be bigger than setting it to veryslow.
With -qp 0 you set the maximum quality. 0 is best, 51 is worst quality in our example.
Then output.mp4 is your new container to store your data in.
After you are done in Adobe Premiere, you can convert it back to a YUV file by inverting allmost all parameters. FFmpeg recognizes what's inside the mp4 container, so you don't need to provide parameters for the input.
ffmpeg -i input.mp4 -f rawvideo -vcodec rawvideo -pix_fmt yuv420p -s 1920x1080 -r 25 rawvideo.yuv

Resources