Hello Loic,
Thanks for responding to my post, I am seeing some interesting effects when negotiating profile/level through the caps filter.
My results are below:
Caps Filter: resolution=1280x720, stream-format=byte-stream, alignment=au, profile=constrained-baseline, level=3.1, framerate=30/1:
Pipeline: gst-launch-1.0 -v -e v4l2src device=/dev/video3 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! v4l2h264enc ! video/x-h264, stream-format=byte-stream, alignment=au, profile=constrained-baseline, level=9, width=1280, height=720, framerate=30/1 ! h264parse ! mp4mux ! filesink location=capsFilter.mp4
Result: Fails to negotiate
Log: https://gist.github.com/RobGries/0703499b133eb4dda63f30da8d68f265#file-caps-filter-profile-and-level-txt
Caps Filter: resolution=1280x720, stream-format=byte-stream, alignment=au, profile=constrained-baseline, framerate=30/1:
Pipeline: gst-launch-1.0 -v -e v4l2src device=/dev/video3 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! v4l2h264enc ! video/x-h264, stream-format=byte-stream, alignment=au, profile=constrained-baseline, width=1280, height=720, framerate=30/1 ! h264parse ! mp4mux ! filesink location=capsFilter.mp4
Result: Negotiates properly, but chooses an incorrect level id for the resolution provided (uses level 1, which is not valid for 720P/30)
Log: https://gist.github.com/RobGries/0703499b133eb4dda63f30da8d68f265#file-caps-filter-profile-and-no-level-txt
Caps Filter: resolution=1280x720, stream-format=byte-stream, alignment=au, profile=constrained-baseline, level=3.1, framerate=30/1 with extra-controls=extra-controls="controls,h264_level=9(3.1),h264_profile=1(constrained-baseline)
Pipeline: gst-launch-1.0 -v -e v4l2src device=/dev/video3 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! v4l2h264enc extra-controls=“controls,h264_level=9,h264_profile=1” ! video/x-h264, stream-format=byte-stream, alignment=au, profile=constrained-baseline, level=9, width=1280, height=720, framerate=30/1 ! h264parse ! mp4mux ! filesink location=capsFilter.mp4
gst-launch-1.0 -v -e v4l2src device=/dev/video3 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! v4l2h264enc extra-controls=“controls,h264_level=9,h264_profile=1” ! video/x-h264, stream-format=byte-stream, alignment=au, profile=constrained-baseline, level=9, width=1280, height=720, framerate=30/1 ! h264parse ! mp4mux ! filesink location=capsFilter.mp4
Result: Fails to negotiate
Log: https://gist.github.com/RobGries/0703499b133eb4dda63f30da8d68f265#file-caps-filter-profile-and-level-with-extra-controls-txt
Caps Filter: resolution=1280x720, stream-format=byte-stream, alignment=au, profile=constrained-baseline, framerate=30/1 with extra-controls=extra-controls="controls,h264_level=9(3.1)
Pipeline: gst-launch-1.0 -v -e v4l2src device=/dev/video3 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! v4l2h264enc extra-controls=“controls,h264_level=9” ! video/x-h264, stream-format=byte-stream, alignment=au, profile=constrained-baseline, width=1280, height=720, framerate=30/1 ! h264parse ! mp4mux ! filesink location=capsFilter.mp4
Result: Negotiates properly and uses the proper level parameter
Log: https://gist.github.com/RobGries/0703499b133eb4dda63f30da8d68f265#file-caps-filter-profile-no-level-extra-controls-level-txt
Key Takeaway: It seems like the downstream (of the encoder) caps-filter can properly negotiate profile, however it cannot negotiate level as when it is set it fails to negotiate the stream properly and leads to a failure to encode. I am able to work around this by setting the upstream “extra-controls” for level along with the other characteristics of the stream such as resolution, stream-format, alignment, and framerate. Note that when neither the extra-controls nor the caps-filter set the level, it defaults to level 1 which is invalid since the resolution exceeds it. For more information regarding levels/resolution consult this table on wikipedia here: Advanced Video Coding - Wikipedia. Also note that this is not an exhaustive list of codec parameters that are able to be configured. There are many more different configurations that can be used here, the difficult part is ascertaining whether or not the codec parameters are compatible with a wide range of decoders. Also as stated above in the gstreamer mailing list post, there are no checks that engage on either the v4l2 codec side nor the gstreamer pipeline side that will confirm the validity of the stream. It would be helpful to ascertain a codec-side configuration that attempts to strictly adhere to the H.264 specification as there is a high possibility that parameters supplied to the encoder can create situations where looser conforming decoders may decode a stream with bitstream errors, but stricter decoders will fail to decode.