Two packet/buffer lifecycle fixes (encoder persistent packet, decoder input packet ownership) - #968
Two packet/buffer lifecycle fixes (encoder persistent packet, decoder input packet ownership)#968wangjiamingg wants to merge 3985 commits into
Conversation
Use 64-bit literals in bit operations to prevent overflow when singleton module ID >= 32. Change-Id: Ib08190bbcbb1a0b46559ea3c2ae57d801b5efadf Signed-off-by: Yanjun Liao <yanjun.liao@rock-chips.com>
Add dup function for mpp_frame and mpp_meta. NOTE: The buffer in MppFrame is not dup. Signed-off-by: Herman Chen <herman.chen@rock-chips.com> Change-Id: I4965bc6016c8ffca4b72bbd49e2653eab06c7591
When vproc create new output buffer with hdr_info the original hdr_info in old buffer must be copy to the new one with hdr_offset and hdr_size. Signed-off-by: Herman Chen <herman.chen@rock-chips.com> Change-Id: I7cbfec07adf2de8147f2918332e391074291e4c5
If packet is splited outside of mpp and video_sequence_start_code is not guaranteed, there will not be valid NALS. Thus segment fault will happen. Change-Id: Idb5e51772384c6663260d382b94845a8e1ac7c35 Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
Change-Id: Ifa84dda229711e9af31967b1a57936079da3bb3a Signed-off-by: Yanjun Liao <yanjun.liao@rock-chips.com>
fixes c6fa4c9 /usr/lib/gcc-cross/aarch64-linux-gnu/14/../../../../aarch64-linux-gnu/bin/ld: .../lib/librockchip_mpp.so: undefined reference to `log2' /usr/lib/gcc-cross/aarch64-linux-gnu/14/../../../../aarch64-linux-gnu/bin/ld: .../lib/librockchip_mpp.so: undefined reference to `sincos' /usr/lib/gcc-cross/aarch64-linux-gnu/14/../../../../aarch64-linux-gnu/bin/ld: .../lib/librockchip_mpp.so: undefined reference to `log' /usr/lib/gcc-cross/aarch64-linux-gnu/14/../../../../aarch64-linux-gnu/bin/ld: .../lib/librockchip_mpp.so: undefined reference to `pow' Signed-off-by: nyanmisaka <nst799610810@gmail.com> Change-Id: I3bda683c4a468b66bc2d7cd84765a89c86e0d9e0
Add aligned(4) to packed structs for alignment. Tests prove memory usage and performance unaffected. kernel spcae patch: https://10.10.10.29/c/rk/mpp/+/280064 Change-Id: I23e4c77042721550934962530667d2abc19701d2 Signed-off-by: Yanjun Liao <yanjun.liao@rock-chips.com>
Change-Id: I01d20443cb80b65d156ff2e9f4f7467c4e9446f8 Signed-off-by: xueman.ruan <xueman.ruan@rock-chips.com>
Spec: avs2 Error Case: Buffers were cleared and re-import when seeking, ref_base registers carrys old task's buffer fd. If new task after seeking with no ref frame or ref num less than old task, will occur dma_buf import issue Error Log: [64248.193315][ T4180] mpp_dma_import_fd:224: dma_buf_get fd 126 failed(-9) [64248.193378][ T4180] rk_vcodec: mpp_task_attach_fd:1841: can't import dma-buf 126 [64248.193394][ T4180] rk_vcodec: mpp_translate_reg_address:1898: reg[165]: 0x0000007e fd 126 failed Signed-off-by: Chandler Chen <chandler.chen@rock-chips.com> Change-Id: I446a6f0a4d646fe67af544bfb5400f4a03b27937
1. Align register and structure naming to kmpp 2. Align parameters to kmpp Change-Id: I9dfbf409fb7c0575462aa7b6107edb362d1c1595 Signed-off-by: Yanjun Liao <yanjun.liao@rock-chips.com>
Change-Id: Ibbf7a35f7f6ca01a613d24d6e01e665361808d94 Signed-off-by: Lankun Lin <lankun.lin@rock-chips.com> Signed-off-by: Yanjun Liao <yanjun.liao@rock-chips.com>
Change-Id: I404f50950e2934a3d4db66b75751c1e3b84d5c4d Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
GDR decoding faile due to registers configuration breaked by error reference frame index checking, although disable_error is set. The issue is introduced by 5f20063. Change-Id: Iab181d92ad30332f68735cd5500cae1175dbc418 Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
Change-Id: Ic4d81241cc0ae4d2dc98ad9f394ad32dcbb0a18d Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
1. Avoid mutual dependencies using forward declaration. 2. remove some unused dependencies Change-Id: Idb9007dfd107695470ac69cb8afb11ec221e97bb Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
Change-Id: I91a3ae0c65c18ce60b759a22cfb767088e19ed01 Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
'#define' and 'undef' shall not be used on a reserved identifier or reserved macro name. Change-Id: I5e9633df20b013f3a1686dba3200885e65f5371b Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
Change-Id: Icd1fab0435f3a756be44090c63078a88f7bf0458 Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
Serverity level: 2 Function should not declared with an empty parameter list. "void" should not be omitted when defining a function with no parameters. Change-Id: Id2a14d64827e46c050d46e6d0ff003c7897d5f2e Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
Signed-off-by: Chandler Chen <chandler.chen@rock-chips.com> Change-Id: I68be40f20fd930300809c67dc46f0d833aa85774
The dynamic data maynot carried in every frame, so it is neccessary to keep the dynamic data. Change-Id: If6ca0964eb8679134dff128e7dbde7a8a6285069 Signed-off-by: Yandong Lin <yandong.lin@rock-chips.com>
Platform: All Format: HEVC Error log: H265D_PARSER: hevc_frame_start found two frame in one packet do nothing ! Cause: split_nal_units() doesn't detect frame boundaries, processes all NALs causing multi-frame in single iteration. Solution: Check first_slice_segment_in_pic_flag in VCL NALs, break loop when new frame start found Change-Id: I79a14e5505f2447d766ee66eb81b4741a6d74094 Signed-off-by: Yanjun Liao <yanjun.liao@rock-chips.com>
The extra data(sps/pps) will be lost when the following flow occur: push extra data -> reset -> push idr data. Change-Id: I886cd38888050b505dc597a3759f80657a3fa66a Signed-off-by: Chen Jinsen <kevin.chen@rock-chips.com>
Signed-off-by: Yandong Lin <yandong.lin@rock-chips.com> Change-Id: I9c397c658998270c318b4c4bfd1fb1481149272f
Change-Id: Ia75de3e19d6025eb826aa934f5e02db24785041e Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com>
Change-Id: I499246c4670f02a81d413515e376a54d6304232e Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com>
Change-Id: I291e68da76a0317d3c97288d0290342596af7ae5 Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com>
Change-Id: I8330005ca017c2731b1c202d7bba3a8169d5acdf Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com>
Change-Id: I2339d314225d324b687e94c6b13a1e96189eeff6 Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com>
Change-Id: Ia1e09ce5875095651fcca7c767b9b7db9279c81e Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com>
When stream data is corrupted (e.g., during seeking), extract_length may become a large negative value like -1347309641 (0xAFAFFB11). Signed comparison treats negative values as less than positive length, bypassing the check and causing memcpy to crash with SIGSEGV. Restore the unsigned cast to correctly detect invalid NAL lengths from corrupted input data. Signed-off-by: Herman Chen <herman.chen@rock-chips.com> Change-Id: I7b447c23a278954d392bc16f7aa771fd49a9ab1f
Change-Id: I1d2198b422293e822e6bfe81d2d554bd82ef9338 Signed-off-by: Yanjun Liao <yanjun.liao@rock-chips.com>
Platform: RK3288/RK3399/RK322X/RK332X which use rkv as H.265 decoder Spec: h265 Error case: Bug in introduced in commit: fix[h265d]: Modify RefPicList array size to 16 When parser found error frame and assignment the array[15] as the recovery frame the rkv hal driver had only 15 address register. The recovery frame info will overflow to next register value and corrupt the frame pixel data. Err log: No not but output data is corrupted. Solution: Use rkv register number as the loop limit. Source: video_h265_1920x1080.mkv Signed-off-by: Herman Chen <herman.chen@rock-chips.com> Change-Id: I5e1162ec0b9d16d0284b4e7ae934cb7f89bbd0b6
Set tile output with -f 0x2000000. Change-Id: If4fb2d0ff0b3247563a1a8f1b6d553ef664c22c9 Signed-off-by: Hongjin Li <vic.hong@rock-chips.com>
pu8_inter_interpolation_num_big_lvl and pu32_inter_interpolation_num_small_lvl should be 0 or 1. Change-Id: I98c3a1cd5b2d2583a4d4c25313a868bdd9d571e9 Signed-off-by: timkingh.huang <timkingh.huang@rock-chips.com>
1. support loglevel change dynamically 2. eliminate unused-parameter warning 3. update libvdpp version to v1.4.1 Change-Id: Ice164d580cba2ed60b9b24df43249d7b570246fa Signed-off-by: vance.wu <vance.wu@rock-chips.com>
The frame parallel encoding with task_cnt > 1 is not required on RK3572/RV1126B platforms. Simplify the HAL context by using single fixed buffers instead of dynamically indexed arrays. Changes: - Replace ext_line_bufs[] with single ext_line_buf - Replace regs_sets[] with single regs_set pointer - Convert amend_sets pointer to embedded amend struct - Remove prefix_sets/slice_sets dynamic allocation - Remove task_idx rotation and reg_idx tracking - Remove conditional TSVC async encoding block This reduces memory footprint and simplifies code flow. Platform: RK3572/RV1126B Spec: h264/h265 Change-Id: I505bc840bbcf1979e13b55c38c65bca49153297a Signed-off-by: Yanjun Liao <yanjun.liao@rock-chips.com>
Use last_frame_type instead of last_frame_fb.frame_type for colmv_load_hevc judgment. Change-Id: I5546c9691f550bdb25c8f71a6b890c1c0f2b34fc Signed-off-by: Yanjun Liao <yanjun.liao@rock-chips.com>
Change-Id: I49812e1a9ac1c201001c172ca59d5434e9a674de Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com>
Change-Id: I9381dc0ffff4014d1fd675067e45ae06db0fbff7 Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com>
Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com> Change-Id: Ic0b809430f142a91ace83a9b678fb63105188cfe
Add ELEM_TYPE_arr, ELEM_TYPE_s8, ELEM_TYPE_u8 to ElemType enum Change-Id: I5afe39046de1904a8c72ca3a687a0f816a2681f8 Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com>
Adapter ELEM_TYPE_s8, ELEM_TYPE_u8, ELEM_TYPE_arr Change-Id: I2ff4ca0d5a9d5312d2d3e43a5d8c83cb78d41824 Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com>
Change-Id: Idae4a676aaf493c83cc090f057d1f7d423d9cb65 Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com>
The array is arranged with 8 elements per row Change-Id: I25a4dd3bd73ee6dd70a09ddd023d6676d92d098e Signed-off-by: Xiaoxu Chen <xiaoxu.chen@rock-chips.com>
Add test cases for new array type support: - test_typed_arrays: s8/u8/s16/u16/s64/u64/bool/string arrays - test_object_array: array of objects with multiple fields - test_nested_array: nested 2D arrays - test file input with JSON/TOML format auto-detection Signed-off-by: Herman Chen <herman.chen@rock-chips.com> Change-Id: I72979954a8c07c740dd461989dcdf939f09170f6
In TSVC scenarios, dual-core frame parallel encoding was timing out because DCHS synchronization IDs did not follow the frame reference chain. Correcting this mapping ensures proper hardware handshakes across temporal layers. Change-Id: I4735fc291a7fd170ec6417149f17dc08af0d2fe4 Signed-off-by: Chandler.Chen <chandler.chen@rock-chips.com>
Change-Id: I89290be67cd67bfbe7b6e2177d13a886c5836d99 Signed-off-by: timkingh.huang <timkingh.huang@rock-chips.com>
Change-Id: I124de97072a592260427d7f1333152f0fbc6a98b Signed-off-by: timkingh.huang <timkingh.huang@rock-chips.com>
Change-Id: I2038320d1d5c9ad884f785789e468eb191f8eba5 Signed-off-by: timkingh.huang <timkingh.huang@rock-chips.com>
Platform: all
Spec: h265
Error case:
The hdr meta storage is a global buffer all frame level storage save the
pointer. When next frame's hdr meta is larger than previous one the old
buffer will be released and alloc a new one. But the previous frame
still use the old pointer. So it is a used-after-free issue.
Error log:
backtrace:
#00 pc 000000000005fb4c /apex/com.android.runtime/lib64/bionic/libc.so
rockchip-linux#1 pc 0000000000165e48 /system/lib64/libmpp.so (fill_hdr_meta_to_frame+1332)
rockchip-linux#2 pc 00000000001c46a4 /system/lib64/libmpp.so (try_proc_dec_task+3544)
rockchip-linux#3 pc 00000000001c2fb0 /system/lib64/libmpp.so (mpp_dec_parser_thread+724)
rockchip-linux#4 pc 00000000000cb6a8 /apex/com.android.runtime/lib64/bionic/libc.so
rockchip-linux#5 pc 000000000006821c /apex/com.android.runtime/lib64/bionic/libc.so
Solution:
Add hdr meta storage pool module and use storage index to refer the
buffer.
Source: H265-209-Everest.ts
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
Change-Id: I7f0c2bc021366eeddaa026ee96bee116d5f98252
Signed-off-by: Herman Chen <herman.chen@rock-chips.com> Change-Id: If381fc96c19db30098fed37c5aee8148936e6ff9
Platform: General Spec: jpegd Error case: in: yuvj444p out: yuv420 Repro Cmd: gst-launch-1.0 videotestsrc ! 'video/x-raw,width=4096,height=2160' ! jpegenc ! jpegparse ! mppjpegdec ! fakesink Err log: mpp_dec: Assertion slot_size <= buffer_size failed at mpp_dec_advanced_thread:1049 mpp_dec: mpp_dec_advanced_thread required buffer size 26542080 is larger than input buffer size 17694720 Solution: Synchronize the user-configured output format to jpegd_parser. Reported-by: Jianfei Chen <jeffy.chen@rock-chips.com> Change-Id: I46abecca31386bbe70ced57eda10c75a91825935 Signed-off-by: Hongjin Li <vic.hong@rock-chips.com>
Optimize buffer management and enable fast parse on vdpu383 and vdpu384b platforms. Change-Id: Ia2d49159f2d1680211652b1386b8f83135be951e Signed-off-by: Hongjin Li <vic.hong@rock-chips.com>
Change-Id: Ib09d1ef7c4a438b2549ddc890e22d5a06e82c360 Signed-off-by: timkingh.huang <timkingh.huang@rock-chips.com>
Change-Id: Icad644e678bbcdd08de9ecb1e3df9c13e5e53d91 Signed-off-by: timkingh.huang <timkingh.huang@rock-chips.com>
Change-Id: I08bc66cc93ba0fe41f613062c785355c3cd8e653 Signed-off-by: timkingh.huang <timkingh.huang@rock-chips.com>
…packet In the sync encode path, enc->packet is a persistent packet reused across frames. mpp_enc_check_pkt_buf() assigned pkt->buffer directly, silently dropping the reference held by the previous frame's buffer and leaking one MppBuffer per encoded frame. Use mpp_packet_set_buffer() so the previously attached buffer is put before the new one is attached; the final buffer is still released once at encoder teardown through mpp_packet_deinit(). Reproduction: run an encoder for several hours with frequent start/stop cycles; before this change RSS grows linearly with buffer-group usage, after it stays flat. Signed-off-by: wangjiamingg <wangjiamingg@users.noreply.github.com>
When the decoded output frame carries KEY_INPUT_PACKET in its meta so
that the consumer can release the bitstream buffer, dec->mpp_pkt_in
still owns the same packet. dec_release_input_packet() could then deinit
it a second time after the meta consumer already did ('found
non-positive ref_count' on the packet's MppBuffer, followed by crash).
MppPacket has no inc_ref API and MppMeta set/get copies raw pointers
without touching refcounts, so the only safe hand-off is a single-owner
transfer: clear dec->mpp_pkt_in right after attaching the packet to the
output frame meta.
Verified with per-packet alloc/free accounting (PKT_NEW vs PKT_DEINIT)
over 1820 packets: balanced after the change.
Signed-off-by: wangjiamingg <wangjiamingg@users.noreply.github.com>
|
Thanks for digging into the packet lifecycle! After a careful review against the current code, we don't think these two issues
The direct assignment pkt->buffer = buffer in mpp_enc_check_pkt_buf() only runs when enc->pkt_buf == NULL. This invariant guarantees the packet never holds an old buffer at that point: • mpp_enc_check_frm_pkt() re-derives enc->pkt_buf from mpp_packet_get_buffer(enc->packet) at the beginning of every task, so the two are always in sync; More importantly, the proposed change is a leak in the opposite direction: mpp_packet_set_buffer() calls mpp_buffer_inc_ref() on the new buffer, but the reference returned by mpp_buffer_get() is never put. With the patch applied, every newly created output buffer would gain a net +1 reference and never return to the buffer group — which produces exactly the linear RSS growth described in the commit message. If you measured RSS growth before and flat RSS after, the root cause was likely something else.
dec->mpp_pkt_in is only used by the parser-thread mode (try_get_input_packet() / try_proc_dec_task(), called from |
Two packet/buffer lifecycle fixes (encoder persistent packet, decoder input packet ownership)
Hi,
While chasing a ~1.3 GB/day memory leak in a long-running kiosk product
(RK3588, GStreamer + MPP decode/encode pipelines restarted every few
seconds), we found two lifecycle issues in MPP core. Both are fixed
locally and verified in production for several days.
Patch 1: mpp_enc_impl — stale buffer ref in persistent encoder packet
mpp_enc_check_pkt_buf()assignspkt->buffer = bufferdirectly. Forthe sync path,
enc->packetis a persistent packet reused acrossframes, so this raw assignment drops the previous frame's MppBuffer
reference every frame → one leaked MppBuffer per encoded frame.
Fix: use
mpp_packet_set_buffer(), which puts the previously attachedbuffer before attaching the new one. Teardown behaviour is unchanged.
Repro: any long-running encode (h264/h265) with frequent start/stop;
buffer-group usage grows linearly before, flat after.
Patch 2: mpp_dec_normal — single-owner transfer of input packet to frame meta
When the decoded output frame carries KEY_INPUT_PACKET so that the
consumer can release the bitstream buffer,
dec->mpp_pkt_instill ownsthe same packet.
dec_release_input_packet()can then deinit it asecond time after the consumer already did ("found non-positive
ref_count" on the packet's MppBuffer, then crash).
MppPacket has no inc_ref API and MppMeta set/get copies raw pointers
without touching refcounts, so the only safe hand-off is a single-owner
transfer: clear
dec->mpp_pkt_inright after attaching the packet tothe output frame meta.
Repro: decode where the consumer reads KEY_INPUT_PACKET back from the
output frame meta and deinits it (e.g. gstreamer-rockchip drain path);
per-packet alloc/free accounting shows double deinit before, balanced
after.
Both fixes are independent of each other; happy to split/rework as
preferred.