Rockchip Media Process Platform (MPP)

repository·develop·Indexed 21 days ago

https://github.com/rockchip-linux/mpp

A library for media processing tasks on Rockchip hardware, providing a unified Media Process Interface (MPI) for video encoding and decoding. It features a layered architecture bridging application software to hardware acceleration modules (vdpu, vepu, rkvdec, rkvenc) and supports Linux kernels 3.10 through 6.1. The library includes core abstractions for memory and data management such as MppBuffer, MppPacket, MppFrame, and MppTask, and supports advanced memory layouts like FBC and Tile.

Tokens
29.1K
Snippets
44
Records
107
Agent score
77%

What's inside rockchip-linux-mpp

  1. Overview of Rockchip MPP

    develop

    The Media Process Platform (MPP) is a general media processing software platform designed for Rockchip chips. It provides a unified Media Process Interface (MPI) that shields developers from the complexities and differences of low-level hardware processing across various chip series.

    Core Capabilities:

    • Video Decoding: Supports H.265, H.264, H.263, AV1, VP9, VP8, AVS2, AVS, MPEG-4, MPEG-2, and MJPEG.
    • Video Encoding: Supports H.265, H.264, VP8, and MJPEG.
    • Video Processing: Includes video copy, zoom, color space conversion, and field video de-interleaving (Deinterlace).
  2. Overview of MPP documentation structure

    develop

    The MPP (Media Process Platform) documentation is divided into two distinct categories depending on your role:

    1. Library Users: Refer to the Mpp user guide and user manual for instructions on how to use the library, API usage, and external study resources.
    2. Platform Developers: Refer to the Mpp design document for information regarding design principles, module design, and internal architecture to facilitate deeper understanding of the platform.
  3. Manage MppPacket memory lifecycle

    develop

    The way MppPacket memory is released depends on how it was initialized:

    1. External malloc: If you configure an external malloc address to the MppPacket, the memory will not be released automatically by MPP.
    2. copy_init: If the MppPacket is generated via copy_init, the memory allocated during the copying process is released automatically once the copy is complete.
    3. MppBuffer: If the MppPacket is generated from an MppBuffer, the MppBuffer is referenced during creation and dereferenced (released) when the MppPacket is released.
  4. Choose a Decoder Memory Usage Mode

    develop

    MPP decoders support three memory usage modes. Choosing the right one depends on your requirements for ease of use versus performance (zero-copy).

    Mode 1: Pure Internal Mode

    User does not call MPP_DEC_SET_EXT_BUF_GROUP. The decoder creates buffers internally.

    • Pros: Easiest to use; quick to get a demo running.
    • Cons: Potential memory leaks/crashes if buffers aren't released; memory usage is uncontrolled; difficult to implement zero-copy display.

    Mode 2: Half Internal Mode

    User creates an MppBufferGroup based on the returned info change MppFrame. This is the mode used in mpi_dec_test.

    • Pros: Easy to use; memory can be safely released after the decoder closes; memory usage can be limited using mpp_buffer_group_limit_config.
    • Cons: Buffer limitation is not 100% accurate; difficult to implement zero-copy display.

    Mode 3: Pure External Mode

    User creates an empty MppBufferGroup and imports memory from an external allocator via file handles (e.g., Android SurfaceFlinger).

    • Pros: Most efficient way to achieve zero-copy display.
    • Cons: High complexity; requires external parsers to determine correct buffer sizes for the allocator.
  5. Understand the MppFrame structure

    develop

    An MppFrame is the primary structure used to define 2D image buffer information, including the location and length of valid data. For decoders, MppFrame is the output structure containing pixel data, timestamps (pts, dts), and error information.

    Key dimensions and strides:

    • width: Horizontal pixel count.
    • height: Vertical pixel count.
    • hor_stride: Distance between adjacent rows in bytes.
    • ver_stride: Interval between image components in number of rows.

    Important status flags:

    • pts: Present Time Stamp.
    • dts: Decoding Time Stamp.
    • eos: End Of Stream flag.
    • errinfo: Error flag indicating decoding errors.
    • discard: Discard flag; if set, the frame should not be displayed (e.g., due to broken reference relationships).
    • info_change: If true, indicates a change in stream information (width, height, stride, or format). When this occurs, you must re-analyze and potentially resize your memory pool.
    • fmt: MppFrameFormat representing color space and memory arrangement.
    • buffer: The underlying MppBuffer containing the actual data.
    /* Conceptual representation of MppFrame members */
    struct MppFrame {
        RK_U32 width;
        RK_U32 height;
        RK_U32 hor_stride;
        RK_U32 ver_stride;
        RK_U32 mode;
        RK_U64 pts;
        RK_U64 dts;
        RK_U32 eos;
        RK_U32 errinfo;
        RK_U32 discard;
        size_t buf_size;
        RK_U32 info_change;
        MppFrameFormat fmt;
        MppFrameColorRange color_range;
        MppBuffer buffer;
    };
  6. Choose a decoder image memory allocation mode

    develop

    MPP decoders support three modes for managing the memory used to store decoded pixel data. Choosing the right mode depends on your requirements for simplicity, memory control, and zero-copy performance.

    Mode 1: Pure internal allocation mode

    Memory is allocated directly by the MPP decoder. The user obtains the output image and must release it after use.

    • How to use: Do not call MPP_DEC_SET_EXT_BUF_GROUP. Call MPP_DEC_SET_INFO_CHANGE_READY when the decoder reports an info change. The user must release each acquired frame's data directly.
    • Pros: Simplest implementation; good for quick performance evaluation.
    • Cons: Risk of memory leaks if not released before decoder destruction; no control over memory usage (can lead to exhaustion); difficult to achieve zero-copy display.

    Mode 2: Semi-internal allocation mode (Default)

    The user creates an MppBufferGroup based on the buf_size of the MppFrame returned by get_frame and configures it via MPP_DEC_SET_EXT_BUF_GROUP.

    • How to use: Use mpp_buffer_group_limit_config to limit decoder memory usage.
    • Pros: Simple and allows some memory usage limitations.
    • Cons: Memory usage limits are not 100% accurate (usage fluctuates); difficult to achieve zero-copy display.

    Mode 3: Pure external allocation mode

    The decoder imports memory file handles (e.g., dmabuf, ion, or drm) from an external allocator provided by the user.

    • How to use: Create an empty external mode MppBufferGroup, commit the external file handles (e.g., from Android's gralloc), and configure it via MPP_DEC_SET_EXT_BUF_GROUP.
    • Pros: Enables easy zero-copy display by using memory directly from the external display system.
    • Cons: Complex implementation; requires modifications to user program workflows.
  7. Understand the MPP System Framework

    develop

    MPP operates through a layered architecture to bridge the gap between hardware and applications:

    1. Hardware Layer: Contains hardware accelerator modules like vdpu, vepu, rkvdec, and rkvenc.
    2. Kernel Driver Layer: Linux kernel codec hardware drivers (including MMU, memory, clock, and power management). Supported kernels include 3.10, 4.4, 4.19, 5.10, and 6.1.
    3. MPP Layer (Userspace): The core library that provides the unified MPI (Media Process Interface). It includes the MPI module, OSAL (Operating System Abstraction Layer), HAL (Hardware Abstraction Layer), and specific Video Decoder/Encoder/Processing modules.
    4. Operating System Layer: Runs on Linux distributions (e.g., Debian) or Android.
    5. Application Layer: Applications can call the MPI directly or use middleware like OpenMax or GStreamer that adapt to the MPP layer.
  8. Understand mpi_dec_test output logs

    develop

    When running mpi_dec_test, the logs provide critical information about the decoding process:

    • MPP Version: Indicated by mpp_info: mpp version: ....
    • Info Change Events: Indicated by mpi_dec_test: [address] decode_get_frame get info changed found. This often precedes requests for specific memory layouts.
    • Memory Requirements: The decoder will log requested dimensions and strides, e.g., decoder require buffer w:h [1920:1080] stride [1920:1088] buf_size 4177920.
    • Frame Progress: decode get frame [index] indicates successful frame output.
    • Performance Metrics: A summary line provides total time, first frame delay, and FPS, e.g., decode 30 frames time 263ms delay 69ms fps 113.99.
    • Success/Memory Usage: A final line like test success max memory 19.92 MB confirms completion and reports peak memory usage.
  9. Core Data Structures in the MPI Interface

    develop

    The MPI uses specific data structures to handle the interaction between the application and the kernel driver. Most structures are accessed via void* handles and managed through mpp_xxx_set/get_xxx interfaces to ensure forward compatibility.

    Key Abstractions:

    • MppMem: Encapsulation of standard C malloc memory.
    • MppBuffer: Encapsulation of dmabuf memory used for hardware interaction (supports ion/drm allocators).
    • MppPacket: A one-dimensional buffer used primarily to represent bitstream data (e.g., encoded video packets).
    • MppFrame: A two-dimensional buffer used primarily to represent image data (e.g., decoded video frames).

    Typical Decoding Workflow:

    1. Assign address and size to an MppPacket for the input bitstream.
    2. Use the put_packet interface to input the bitstream.
    3. Use the get_frame interface to retrieve the resulting MppFrame (image data).
  10. Understand Global vs. Temporary encoder control information

    develop

    MPP distinguishes between two types of control information:

    1. Global Control Information: Affects the entire encoding process (e.g., code rate, width, height). These are configured via the Control Interface (commands).
    2. Temporary Control Information: Acts only on a single frame (e.g., per-frame OSD configuration, user data). These are configured via the MppMeta interface carried by the MppFrame.
  11. Configure the encoder using MppEncCfg and control interfaces

    develop

    Unlike decoders, encoders in MPP require explicit parameter configuration before they can perform encoding tasks. MPP recommends using the MppEncCfg structure in conjunction with the control interface using the MPP_ENC_SET_CFG and MPP_ENC_GET_CFG commands.

    To ensure binary compatibility and simplify version management, MppEncCfg uses a key-value mapping approach rather than a fixed structure. Configuration is performed using string keys in the format [type:parameter]. The API provides specific functions for different data types (s8, u8, s16, u16, s32, u32, s64, u64, ptr, and st) to handle both setting and getting these values.

    /* Example of the configuration pattern */
    // Use mpp_enc_cfg_set_* to configure
    // Use mpp_enc_cfg_get_* to retrieve
    // Keys follow the format [type:parameter]
  12. Configure encoder settings using MppEncCfg

    develop

    MPP uses the MppEncCfg structure to configure encoder parameters via the MPP_ENC_SET_CFG and MPP_ENC_GET_CFG commands. Instead of using fixed structures that break binary compatibility when new features are added, MppEncCfg uses a key-value mapping system where keys are strings in the format [type:parameter].

    To set or get values, use the corresponding function group based on the data type (e.g., s32, u32, ptr, st).

    // Example of setting a parameter
    MPP_RET ret = mpp_enc_cfg_set_s32(cfg, "rc:bps_target", 2000000);
    
    // Example of getting a parameter
    RK_S32 target_bps;
    ret = mpp_enc_cfg_get_s32(cfg, "rc:bps_target", &target_bps);