commit | e5b5b5f04fc4bc08ecd2f25d22aaceaaf89465ba | [log] [tgz] |
---|---|---|
author | Mattijs Korpershoek <[email protected]> | Tue Apr 09 15:09:05 2024 +0200 |
committer | Mattijs Korpershoek <[email protected]> | Mon Sep 30 14:08:35 2024 +0200 |
tree | b077bb638316e5d643778b4b6b5893676ecf4ea3 | |
parent | 5c00f2d123b5d4498f331d654ad6f9b872406156 [diff] |
v4l2_codec2: encode: fix crash when input.buffers[0] is nullptr The client can crash the V4L2EncodeComponent by passing an input with one buffer where buffer==nullptr: F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** F DEBUG : Build fingerprint: 'TI/am62p/am62p:14/UQ1A.240105.002/eng.mkorpe.20240325.115051:userdebug/test-keys' F DEBUG : Revision: '0' F DEBUG : ABI: 'arm64' F DEBUG : Timestamp: 2024-04-09 07:53:02.494446645+0000 F DEBUG : Process uptime: 8s F DEBUG : Cmdline: /vendor/bin/hw/[email protected] F DEBUG : pid: 4949, tid: 4955, name: V4L2EncodeCompo >>> /vendor/bin/hw/[email protected] <<< F DEBUG : uid: 1013 F DEBUG : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE) F DEBUG : signal 0 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr -------- F DEBUG : Cause: null pointer dereference F DEBUG : x0 0000000000000000 x1 b400007acbed72e8 x2 b400007a3beda7f0 x3 0000000000000010 F DEBUG : x4 020000797bedb2c0 x5 b400007a2bed1878 x6 0000000000000001 x7 7f7f7f7f7f7fff7f F DEBUG : x8 00000078e68d0710 x9 b40000795bed9990 x10 b40000795bed99a0 x11 0000000000000003 F DEBUG : x12 0000000000000000 x13 0000000000000004 x14 0000000000000276 x15 0000000000000000 F DEBUG : x16 0000007b7c1eac60 x17 0000007b80a6c770 x18 00000078e5aa2000 x19 b400007a0bede5a0 F DEBUG : x20 00000078e68d07e0 x21 0000000000000000 x22 0000000000000000 x23 b400007a9bed6210 F DEBUG : x24 0000000000000000 x25 00000078e68d1000 x26 0000000000000002 x27 0000007b8a387b88 F DEBUG : x28 00000000000fc000 x29 00000078e68d0680 F DEBUG : lr 0000007b7c1cbb20 sp 00000078e68d0680 pc 0000007b80a6c778 pst 0000000080000000 F DEBUG : 12 total frames F DEBUG : backtrace: F DEBUG : #00 pc 0000000000069778 /vendor/lib64/libcodec2_vndk.so (C2Buffer::data() const+8) (BuildId: 1d42f8105aac0515945328329706c2e1) F DEBUG : #01 pc 0000000000042b1c /vendor/lib64/libv4l2_codec2_components.so (android::V4L2EncodeComponent::queueTask(std::__1::unique_ptr<C2Work, std::__1::default_delete<C2Work> >)+348) (BuildId: 2f6128320f05c503e8ee6dc9e05df980) F DEBUG : #02 pc 00000000000470a8 /vendor/lib64/libv4l2_codec2_components.so (base::internal::Invoker<base::internal::BindState<void (android::V4L2EncodeComponent::*)(std::__1::unique_ptr<C2Work, std::__1::default_delete<C2Work> >), base::WeakPtr<android::V4L2EncodeComponent>, std::__1::unique_ptr<C2Work, std::__1::default_delete<C2Work> > >, void ()>::RunOnce(base::internal::BindStateBase*)+120) (BuildId: 2f6128320f05c503e8ee6dc9e05df980) F DEBUG : #03 pc 00000000000acca0 /vendor/lib64/libchrome.so (base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*)+192) (BuildId: 87e214635dddac0ae594ee401576361a) F DEBUG : #04 pc 00000000000cc9ac /vendor/lib64/libchrome.so (base::MessageLoop::RunTask(base::PendingTask*)+348) (BuildId: 87e214635dddac0ae594ee401576361a) F DEBUG : #05 pc 00000000000ccd84 /vendor/lib64/libchrome.so (base::MessageLoop::DoWork()+468) (BuildId: 87e214635dddac0ae594ee401576361a) F DEBUG : #06 pc 00000000000ce080 /vendor/lib64/libchrome.so (base::MessagePumpDefault::Run(base::MessagePump::Delegate*)+96) (BuildId: 87e214635dddac0ae594ee401576361a) F DEBUG : #07 pc 00000000000f1fec /vendor/lib64/libchrome.so (base::RunLoop::Run()+60) (BuildId: 87e214635dddac0ae594ee401576361a) F DEBUG : #08 pc 0000000000111e88 /vendor/lib64/libchrome.so (base::Thread::ThreadMain()+392) (BuildId: 87e214635dddac0ae594ee401576361a) F DEBUG : #09 pc 000000000010f040 /vendor/lib64/libchrome.so (base::(anonymous namespace)::ThreadFunc(void*)+128) (BuildId: 87e214635dddac0ae594ee401576361a) F DEBUG : #10 pc 00000000000d6fb0 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 218db69eb66aeb253a34d956906a8bba) F DEBUG : #11 pc 000000000006ad90 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 218db69eb66aeb253a34d956906a8bba) This is tested by VtsHalMediaC2V1_0TargetComponentTest#testInputBuffer(). Fix this by guarding against this condition, as done in SimpleC2Component[1] [1] https://android.googlesource.com/platform/frameworks/av/+/refs/heads/main/media/codec2/components/base/SimpleC2Component.cpp#1141 Test: atest VtsHalMediaC2V1_0TargetComponentTest Change-Id: I407f8f7fb420bd993a665c0a7cb10ad1e224d0fb Signed-off-by: Mattijs Korpershoek <[email protected]>
This document is aimed to provide information about the v4l2_codec2 project. The target readers of this document are the developers and following maintainers of this project, and the partners who are willing to use the V4L2 components.
v4l2_codec2 project provides a component implementation of Codec2 framework, the next-generation codec framework. The component implementation delegates the request to the driver via the V4L2 API.
Install the build package and files, and set the parameters in device.mk
# Add the folder to the namespace. PRODUCT_SOONG_NAMESPACES += external/v4l2_codec2 # Add the build target. PRODUCT_PACKAGES += \ android.hardware.media.c2@1.0-service-v4l2 \ libc2plugin_store # If a customized allocator is needed, then add this package. # See more detail at "Customized allocator" section. PRODUCT_PACKAGES += \ libv4l2_codec2_vendor_allocator # Install media_codecs_c2.xml. # The destination is: /vendor/etc/media_codecs_c2.xml PRODUCT_COPY_FILES += \ <path_to_file>:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_c2.xml # Set the customized property of v4l2_codec2, including: # - The maximum concurrent instances for decoder/encoder. # It should be the same as "concurrent-instances" at media_codec_c2.xml. PRODUCT_PROPERTY_OVERRIDES += \ ro.vendor.v4l2_codec2.decode_concurrent_instances=8 \ ro.vendor.v4l2_codec2.encode_concurrent_instances=8 # Codec2.0 poolMask: # ION(16) # BUFFERQUEUE(18) # BLOB(19) # V4L2_BUFFERQUEUE(20) # V4L2_BUFFERPOOL(21) # SECURE_LINEAR(22) # SECURE_GRAPHIC(23) # # For linear buffer allocation: # If ION is chosen, then the mask should be 0xf50000 # If BLOB is chosen, then the mask should be 0xfc0000 PRODUCT_PROPERTY_OVERRIDES += \ debug.stagefright.c2-poolmask=0xf50000 # Install extended policy for codec2. # The destination is: /vendor/etc/seccomp_policy/codec2.vendor.ext.policy PRODUCT_COPY_FILES += \ <path_to_policy>:$(TARGET_COPY_OUT_VENDOR)/etc/seccomp_policy/codec2.vendor.ext.policy
Add decode and encode components in media_codecs_c2.xml
<?xml version="1.0" encoding="utf-8" ?> <MediaCodecs> <Encoders> <MediaCodec name="c2.v4l2.avc.encoder" type="video/avc"> <Limit name="size" min="32x32" max="1920x1088" /> <Limit name="alignment" value="2x2" /> <Limit name="block-size" value="16x16" /> <Limit name="blocks-per-second" range="1-244800" /> <Limit name="bitrate" range="1-12000000" /> <Limit name="concurrent-instances" max="8" /> <Limit name="performance-point-1280x720" range="30-30" /> </MediaCodec> <MediaCodec name="c2.v4l2.vp8.encoder" type="video/x-vnd.on2.vp8"> <Limit name="size" min="32x32" max="1920x1088" /> <Limit name="alignment" value="2x2" /> <Limit name="block-size" value="16x16" /> <Limit name="blocks-per-second" range="1-244800" /> <Limit name="bitrate" range="1-12000000" /> <Limit name="concurrent-instances" max="8" /> <Limit name="performance-point-1280x720" range="30-30" /> </MediaCodec> <MediaCodec name="c2.v4l2.vp9.encoder" type="video/x-vnd.on2.vp9"> <Limit name="size" min="32x32" max="1920x1088" /> <Limit name="alignment" value="2x2" /> <Limit name="block-size" value="16x16" /> <Limit name="blocks-per-second" range="1-244800" /> <Limit name="bitrate" range="1-12000000" /> <Limit name="concurrent-instances" max="8" /> <Limit name="performance-point-1280x720" range="30-30" /> </MediaCodec> </Encoders> <Decoders> <MediaCodec name="c2.v4l2.avc.decoder" type="video/avc" > <Limit name="size" min="16x16" max="4096x4096" /> <Limit name="alignment" value="2x2" /> <Limit name="block-size" value="16x16" /> <Limit name="blocks-per-second" min="1" max="1879200" /> <Limit name="bitrate" range="1-62500000" /> <Limit name="concurrent-instances" max="8" /> <Limit name="performance-point-3840x2160" range="30-30" /> <Feature name="adaptive-playback" /> </MediaCodec> <MediaCodec name="c2.v4l2.vp8.decoder" type="video/x-vnd.on2.vp8" > <Limit name="size" min="16x16" max="4096x4096" /> <Limit name="alignment" value="2x2" /> <Limit name="block-size" value="16x16" /> <Limit name="blocks-per-second" min="1" max="1984500" /> <Limit name="bitrate" range="1-62500000" /> <Limit name="concurrent-instances" max="8" /> <Limit name="performance-point-3840x2160" range="30-30" /> <Feature name="adaptive-playback" /> </MediaCodec> <MediaCodec name="c2.v4l2.vp9.decoder" type="video/x-vnd.on2.vp9" > <Limit name="size" min="16x16" max="4096x4096" /> <Limit name="alignment" value="2x2" /> <Limit name="block-size" value="16x16" /> <Limit name="blocks-per-second" min="1" max="2073600" /> <Limit name="bitrate" range="1-62500000" /> <Limit name="concurrent-instances" max="8" /> <Limit name="performance-point-3840x2160" range="30-30" /> <Feature name="adaptive-playback" /> </MediaCodec> <MediaCodec name="c2.v4l2.avc.decoder.secure" type="video/avc" > <Limit name="size" min="16x16" max="4096x4096" /> <Limit name="alignment" value="2x2" /> <Limit name="block-size" value="16x16" /> <Limit name="blocks-per-second" min="1" max="1879200" /> <Limit name="bitrate" range="1-62500000" /> <Limit name="concurrent-instances" max="8" /> <Limit name="performance-point-3840x2160" range="30-30" /> <Feature name="adaptive-playback" /> <Feature name="secure-playback" required="true" /> </MediaCodec> <MediaCodec name="c2.v4l2.vp8.decoder.secure" type="video/x-vnd.on2.vp8" > <Limit name="size" min="16x16" max="4096x4096" /> <Limit name="alignment" value="2x2" /> <Limit name="block-size" value="16x16" /> <Limit name="blocks-per-second" min="1" max="1984500" /> <Limit name="bitrate" range="1-62500000" /> <Limit name="concurrent-instances" max="8" /> <Limit name="performance-point-3840x2160" range="30-30" /> <Feature name="adaptive-playback" /> <Feature name="secure-playback" required="true" /> </MediaCodec> <MediaCodec name="c2.v4l2.vp9.decoder.secure" type="video/x-vnd.on2.vp9" > <Limit name="size" min="16x16" max="4096x4096" /> <Limit name="alignment" value="2x2" /> <Limit name="block-size" value="16x16" /> <Limit name="blocks-per-second" min="1" max="2073600" /> <Limit name="bitrate" range="1-62500000" /> <Limit name="concurrent-instances" max="8" /> <Limit name="performance-point-3840x2160" range="30-30" /> <Feature name="adaptive-playback" /> <Feature name="secure-playback" required="true" /> </MediaCodec> </Decoders> </MediaCodecs>
Set SELinux file policy in sepolicy/file_contexts
/vendor/bin/hw/android\.hardware\.media\.c2@1\.0-service-v4l2(.*)? u:object_r:mediacodec_exec:s0
Add additional permission in codec2.vendor.ext.policy
_llseek: 1 epoll_create1: 1 epoll_ctl: 1 epoll_pwait: 1 eventfd2: 1 fstat64: 1 fstatat64: 1 fstatfs64: 1 getcwd: 1 getdents64: 1 getuid32: 1 mmap2: 1 pselect6: 1 statfs64: 1 sysinfo: 1 ugetrlimit: 1
Set file permission in ueventd.rc
/dev/video* 0600 media media
The default allocator of the decoder's output buffer is C2AllocatorGralloc. However, C2AllocatorGralloc might not fit the requirement for secure playback. In this case, we can implement a customized C2Allocator, and load it at run-time. Please create a library libv4l2_codec2_vendor_allocator
, and export a function CreateVendorAllocator()
for creating the customized C2Allocator. Here is an example below.
cc_library_shared { name: "libv4l2_codec2_vendor_allocator", vendor: true, defaults: [ "libcodec2-impl-defaults", ], srcs: [ "C2VendorAllocatorFactory.cpp", ], shared_libs: [ "libc2plugin_store", ], }
//#define LOG_NDEBUG 0 #define LOG_TAG "C2VendorAllocatorFactory" #include <C2AllocatorGralloc.h> #include <utils/Log.h> #include <v4l2_codec2/plugin_store/V4L2AllocatorId.h> namespace android { ::C2Allocator* CreateVendorAllocator(::C2Allocator::id_t allocatorId) { ALOGV("%s(%d)", __func__, allocatorId); // Change to create vendor-customized implementation. switch (allocatorId) { case V4L2AllocatorId::V4L2_BUFFERQUEUE: return new C2AllocatorGralloc(V4L2AllocatorId::V4L2_BUFFERQUEUE, true); case V4L2AllocatorId::V4L2_BUFFERPOOL: return new C2AllocatorGralloc(V4L2AllocatorId::V4L2_BUFFERPOOL, true); case V4L2AllocatorId::SECURE_LINEAR: return new C2AllocatorGralloc(V4L2AllocatorId::SECURE_LINEAR, true); case V4L2AllocatorId::SECURE_GRAPHIC: return new C2AllocatorGralloc(V4L2AllocatorId::SECURE_GRAPHIC, true); default: ALOGE("%s(): Unknown allocator ID: %d", __func__, allocatorId); } return nullptr; } } // namespace android extern "C" ::C2Allocator* CreateAllocator(::C2Allocator::id_t allocatorId) { return ::android::CreateVendorAllocator(allocatorId); }
Currently the V4L2 encoder has support for the H.264, VP8 and VP9 codecs. Codec selection can be done by selecting the encoder with the appropriate name.
The following parameters are static and can not be changed at run-time:
The following parameters are dynamic, and can be freely adjusted at run-time:
The V4L2 encoder supports various input pixel formats, however frames are currently always passed to the V4L2 encoder in the NV12 format. If a video frame using a different pixel format is passed to the encoder, format conversion will be performed to convert the frame to the NV12 format.
To improve the resilience of H.264 video streams when data is missing, SPS and PPS NAL units are prepended to IDR frames by enabling the V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR control. If the V4L2 driver does not support this control the encoder will manually cache and prepend SPS and PPS NAL units.