# Phát triển plugin superresolution

Phần này giải thích cách phát triển một plugin superresolution (qtimlvsuperresolution) mới.

Ghi chú

- Hướng dẫn này dựa trên bản phát hành `imsdk.lnx.2.0.0.r1-rel`.
- Hướng dẫn này dành cho các nhà phát triển có kinh nghiệm cần tạo plugin Qualcomm IM SDK để xử lý các trường hợp không được hỗ trợ, chẳng hạn như superresolution, bằng cách xây dựng dựa trên các plugin hiện có.
- Tạo plugin GStreamer tùy chỉnh là một tác vụ nâng cao và chỉ dành cho các nhà phát triển GStreamer có kinh nghiệm.
- Có nhiều hướng dẫn chi tiết trong miền nguồn mở và trên cổng thông tin GStreamer chính thức cho tác vụ này.
- Hãy dùng hướng dẫn này làm mẫu và sử dụng các tài nguyên nguồn mở để tìm hiểu về việc phát triển plugin tùy chỉnh.

Điều kiện tiên quyết

- Bạn cần thiết lập eSDK để tải xuống và biên dịch mã ứng dụng/plugin. Hãy xem [Hướng dẫn bắt đầu nhanh với Qualcomm Intelligent Multimedia Software Development Kit (IM SDK)](https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-51/introduction.html) để biết hướng dẫn về cách thiết lập eSDK cũng như cách tải xuống và biên dịch mã plugin.
- Dùng mã nguồn của plugin hiện có làm tham chiếu trong suốt quá trình này.

    [CodeLinaro/ le / platform / vendor / qcom-opensource / gst-plugins-qti-oss · GitLab](https://git.codelinaro.org/clo/le/platform/vendor/qcom-opensource/gst-plugins-qti-oss/-/tree/imsdk.lnx.2.0.0.r1-rel?ref_type=heads)

## Cấu trúc thư mục plugin

gst-plugins-qti-oss/gst-plugins-mlv<plugin-name>/
        CMakeLists.txt
        config.h.in
        mlv<plugin-name>.c
        mlv<plugin-name>.h
        modules/
            CMakeLists.txt
            ml-video-<plugin-name>-module.h
            ml-v<plugin-name>-<module-name>.c
    Copy to clipboard

## Các bước tạo plugin superresolution

1. Tạo plugin header (`gst-plugins-mlvsuperresolution/mlvsuperresolution.h` ).

    Dùng plugin hiện có làm tham chiếu:

    [gst-plugin-mlvsegmentation/mlvsegmentation.h·imsdk.lnx.2.0.0.r2-rel · CodeLinaro / le / platform / vendor / qcom-opensource / gst-plugins-qti-oss · GitLab](https://git.codelinaro.org/clo/le/platform/vendor/qcom-opensource/gst-plugins-qti-oss/-/blob/imsdk.lnx.2.0.0.r2-rel/gst-plugin-mlvsegmentation/mlvsegmentation.h?ref_type=heads)

    1. Nhập các header cần thiết.
    2. Tạo cấu trúc bằng các biến dữ liệu cần thiết để xử lý.

        Ví dụ về chuỗi kế thừa super resolution: GObject &gt; GstObject &gt; GstElement &gt; GstBaseTransform

        GstBaseTransform phù hợp với các phần tử mà kích thước và khả năng đầu ra được xác định hoàn toàn bởi kích thước và khả năng đầu vào

struct _GstMLVideoSuperresolution {GstBaseTransform   parent;
                                               GstMLInfo          *mlinfo;
                                               GstVideoInfo       *vinfo;
                                               GstBufferPool      *outpool;
                                               GstMLModule        *module;
                                               gint               mdlenum;
                                               GstStructure       *mlconstants;
            };
            
            struct _GstMLVideoSuperresolutionClass {GstBaseTransformClass parent;
            };
            Copy to clipboard

Ghi chú

Superresolution không cần có biến nhãn.

Hãy xóa biến nhãn và những phần dùng tới nó trong mã.
2. Tạo tệp triển khai plugin (`gst-plugins-mlvsuperresolution/mlvsuperresolution.c` ).

    Dùng plugin hiện có làm tham chiếu:

    [gst-plugin-mlvsegmentation/mlvsegmentation.c imsdk.lnx.2.0.0.r2-rel · CodeLinaro / le / platform / vendor / qcom-opensource / gst-plugins-qti-oss · GitLab](https://git.codelinaro.org/clo/le/platform/vendor/qcom-opensource/gst-plugins-qti-oss/-/blob/imsdk.lnx.2.0.0.r2-rel/gst-plugin-mlvsegmentation/mlvsegmentation.c?ref_type=heads)

    1. Import `mlvsuperresolution.h` và các header bắt buộc khác.
    2. Định nghĩa caps

        - định dạng video

#define GST_ML_VIDEO_SUPERRESOLUTION_VIDEO_FORMATS "{ RGBA, BGRA, ARGB, ABGR, RGBx, BGRx, xRGB, xBGR, RGB, BGR }"
                Copy to clipboard
        - src caps

#define GST_ML_VIDEO_SUPER_RESOLUTION_SRC_CAPS \
                    "video/x-raw, " \
                    "format = (string) " GST_ML_VIDEO_SUPER_RESOLUTION_VIDEO_FORMATS "; " \
                    "video/x-raw(" GST_CAPS_FEATURE_MEMORY_GBM "), " \
                    "format = (string) " GST_ML_VIDEO_SUPER_RESOLUTION_VIDEO_FORMATS
                Copy to clipboard
        - sink caps

#define GST_ML_VIDEO_SUPER_RESOLUTION_SINK_CAPS \
                       "neural-network/tensors"
                Copy to clipboard
    3. Triển khai các hàm sau

        - Init

            1. Đăng ký plugin tùy chỉnh. Sau khi đăng ký, bạn có thể truy cập vào plugin trong ứng dụng tham chiếu bằng `gst_element_factory_make("plugin-name","plugin-name");`

static gboolean plugin_init(GstPlugin * plugin);
                    Copy to clipboard
            2. Khởi chạy superresolution với các tham số mặc định. Qua đó, bạn kiểm soát được output bufers. Khi nhận nput buffer, `gst_ml_video_super_resolution_prepare_output_buffer` được gọi để cấp phát output buffer.

static void gst_ml_video_super_resolution_init(GstMLVideoSuperResolution * super_resolution)
                    Copy to clipboard
            3. Khởi chạy hàm callback đến con trỏ hàm, đặt caps và thuộc tính mặc định.

static void gst_ml_video_super_resolution_class_init(GstMLVideoSuperResolutionClass * klass)
                    Copy to clipboard
        - Quản lý buffer

            1. Cấp phát <abbr title="Graphics Buffer Manager">graphics Buffer Manager (GBM)</abbr> hoặc ION Memory tùy thuộc vào caps đã thỏa thuận.

static GstBufferPool * gst_ml_video_super_resolution_create_pool (GstMLVideoSuperResolution * super_resolution,
                                                                                      GstCaps * caps)
                    Copy to clipboard
            2. Đảm bảo cấu hình buffer pool phù hợp dựa trên caps.

gst_ml_video_super_resolution_decide_allocation (GstBaseTransform * base,
                                                                     GstQuery * query)
                    Copy to clipboard
            3. Đảm bảo buffer đầu ra được cấp phát từ pool tùy thuộc vào caps.

static GstFlowReturn gst_ml_video_super_resolution_prepare_output_buffer (GstBaseTransform * base,
                                                                                              GstBuffer * inbuffer,
                                                                                              GstBuffer ** outbuffer)
                    Copy to clipboard
        - Caps

            1. Xác thực mô-đun, sau đó thu thập các khả năng đầu vào và đầu ra từ caps của mô-đun.

static gboolean gst_ml_video_super_resolution_set_caps (GstBaseTransform * base,
                                                                            GstCaps * incaps,
                                                                            GstCaps * outcaps)
                    Copy to clipboard
            2. Sửa caps đã thỏa thuận.

static GstCaps * gst_ml_video_super_resolution_fixate_caps (GstBaseTransform * base,
                                                                                GstPadDirection direction,
                                                                                GstCaps * incaps,
                                                                                GstCaps * outcaps)
                    Copy to clipboard
            3. Kiểm tra xem caps đã chỉ định có hợp lệ hay không như video/x-raw, video/x-text, định dạng, chiều cao và chiều rộng.

static gboolean caps_has_feature (const GstCaps * caps,
                                                      const gchar * feature)
                    Copy to clipboard
            4. Chuyển đổi caps tĩnh thành caps thông thường.

static GstCaps * gst_ml_video_super_resolution_src_caps (void)
                    Copy to clipboard
            5. Chuyển đổi caps tĩnh thành caps thông thường.

static GstCaps * gst_ml_video_super_resolution_sink_caps (void)
                    Copy to clipboard
        - Chuyển đổi

            1. Chuyển đổi sink caps thành source caps và ngược lại.

static GstCaps * gst_ml_video_super_resolution_transform_caps (GstBaseTransform * base,
                                                                                   GstPadDirection direction,
                                                                                   GstCaps * caps,
                                                                                   GstCaps * filter)
                    Copy to clipboard
            2. Sau khi suy luận, hàm hậu xử lý (`gst_ml_video_superresolution_module_execute` ) sẽ được gọi dựa trên mô-đun.

gst_ml_video_super_resolution_transform (GstBaseTransform * base,
                                                             GstBuffer * inbuffer,
                                                             GstBuffer * outbuffer)
                    Copy to clipboard
        - Thuộc tính

            1. Đặt thuộc tính của plugin, như mô-đun và hằng số.

static void gst_ml_video_super_resolution_set_property (GObject * object,
                                                                           guint prop_id,
                                                                           const GValue * value,
                                                                           GParamSpec * pspec)
                    Copy to clipboard
            2. Đọc thuộc tính của plugin, như mô-đun và hằng số.

static void gst_ml_video_super_resolution_get_property (GObject * object,
                                                                            guint prop_id,
                                                                            GValue * value,
                                                                            GParamSpec * pspec)
                    Copy to clipboard
        - De-init

            1. Giải phóng mọi buffer đã cấp phát.

static void gst_ml_video_super_resolution_finalize (GObject * object)
                    Copy to clipboard
        - Hiển thị text/bounding boxes (chỉ dựa trên use case, không bắt buộc đối với super resolution)

            1. Chồng kết quả lên khung hình đầu ra

static gboolean gst_ml_video_<plugin-name>_fill_video_output(GstMLVideoDetection * detection,
                                                                                 GArray * predictions,
                                                                                 GstBuffer * buffer);
                    Copy to clipboard
    4. Cập nhật tên plugin trong tệp `gst-plugins-mlvsuperresolution/CMakeLists.txt`.

        Dùng plugin hiện có làm tham chiếu.

        [gst-plugin-mlvsegmentation/CMakeLists.txt imsdk.lnx.2.0.0.r2-rel · CodeLinaro / le / platform / vendor / qcom-opensource / gst-plugins-qti-oss · GitLab](https://git.codelinaro.org/clo/le/platform/vendor/qcom-opensource/gst-plugins-qti-oss/-/blob/imsdk.lnx.2.0.0.r2-rel/gst-plugin-mlvsegmentation/CMakeLists.txt?ref_type=heads)

        Dùng lại tệp `config.h.in` từ plugin hiện có:

        [gst-plugin-mlvsegmentation/config.h.in imsdk.lnx.2.0.0.r2-rel · CodeLinaro / le / platform / vendor / qcom-opensource / gst-plugins-qti-oss · GitLab](https://git.codelinaro.org/clo/le/platform/vendor/qcom-opensource/gst-plugins-qti-oss/-/blob/imsdk.lnx.2.0.0.r2-rel/gst-plugin-mlvsegmentation/config.h.in?ref_type=heads)

## Tổng quan về mô-đun

- Mỗi model có các bước hậu xử lý cụ thể, cần được thực hiện trên các buffer suy luận và cập nhật output buffer cho phù hợp, như điền pixel RGB cho superresolution và segmentation hoặc tính toán bounding boxes cho vật thể phát hiện được.
- `<module-name>.c` định nghĩa các bước hậu xử lý này. Thư mục mô-đun chứa danh sách các tệp như cấu trúc bên dưới

modules/
             "gst-plugins-mlvsuperresolution/modules/ml-vsuperresolution-<module-name1>.c"
             "gst-plugins-mlvsuperresolution/modules/ml-vsuperresolution-<module-name2>.c"
        
        Here <module-name> represents the model's name like srnet for superresolution.
        Copy to clipboard

## Các bước tạo mô-đun srnet

1. Tạo header mô-đun `gst-plugins-qti-oss/gst-plugin-base/gst/ml/ml-module-video-super-resolution.h`.

    Dùng plugin hiện có làm tham chiếu:

    [gst-plugin-base/gst/ml/ml-module-video-super-resolution.h imsdk.lnx.2.0.0.r2-rel · CodeLinaro / le / platform / vendor / qcom-opensource / gst-plugins-qti-oss · GitLab](https://git.codelinaro.org/clo/le/platform/vendor/qcom-opensource/gst-plugins-qti-oss/-/blob/imsdk.lnx.2.0.0.r2-rel/gst-plugin-base/gst/ml/ml-module-video-super-resolution.h?ref_type=heads)

    1. Import các header `gst` cần thiết.
    2. Tạo hàm `execute`.

GST_API gboolean gst_ml_module_video_super_resolution_execute(GstMLModule   * module,
                                                                          GstMLFrame    * mlframe,
                                                                          GstVideoFrame * vframe);
            Copy to clipboard

        Cần có hàm này để gọi hàm hậu xử lý (`gst_ml_module_process` ) được định nghĩa trong tệp `ml-vsuperresolution-<module-name>.c`.
2. Tạo mô-đun `gst-plugins-mlvsuperresolution/modules/ml-vsuperresolution-srnet.c`.

    Dùng plugin hiện có làm tham chiếu:

    [gst-plugin-mlvsegmentation/modules/ml-vsegmentation-deeplab-argmax.c · imsdk.lnx.2.0.0.r1-rel · CodeLinaro / le / platform / vendor / qcom-opensource / gst-plugins-qti-oss · GitLab](https://git.codelinaro.org/clo/le/platform/vendor/qcom-opensource/gst-plugins-qti-oss/-/blob/imsdk.lnx.2.0.0.r1-rel/gst-plugin-mlvsegmentation/modules/ml-vsegmentation-deeplab-argmax.c?ref_type=heads)

    1. Import header `modules/ml-video-superresolution-module.h`.
    2. Định nghĩa caps đầu ra của model.

#define GST_ML_MODULE_CAPS \
                "neural-network/tensors, " \
                "type = (string) { INT8, UINT8, INT32, FLOAT32 }, " \
                "dimensions = (int) < <1, [32, 4096], [32, 4096]> >; " \
                "neural-network/tensors, " \
                "type = (string) { INT8, UINT8, INT32, FLOAT32 }, " \
                "dimensions =  (int) < <1, [32, 4096], [32, 4096], [1, 3]> >"
            Copy to clipboard

        **Ví dụ**

> 
> 
> 1. Tải xuống model [QuickSRNetLarge-Quantized- Qualcomm AI Hub](https://aihub.qualcomm.com/iot/models/quicksrnetlarge) từ AI Hub
>         2. Kiểm tra kích thước đầu ra của model LiteRT (Xem [Tích hợp model AI Hub trong ứng dụng](https://docs.qualcomm.com/doc/80-70020-15BV/topic/integrate-ai-hub-models.html)).
> 
>             - Định dạng: `dtype[N x H X W X C]`
>             - Trong caps đầu ra của mô-đun ở trên `<1, [32, 4096], [32, 4096], [1, 3]>`
> 
>                 - `N = 1`: Kích thước lô đầu ra của model
>                 - `H = [32,4096]`: Chiều cao đầu ra của model phải nằm trong phạm vi này
>                 - `W= [32,4096]`: Chiều rộng đầu ra của model phải nằm trong phạm vi này
>                 - `C = [1,3]`: Kênh đầu ra của model phải nằm trong phạm vi này
>                 - `dtype`: `int8` cho model được lượng tử hóa và `float32` cho model không được lượng tử hóa
>         3. Đối với model được lượng tử hóa, hãy kiểm tra output node để biết scale và offset.
> 
> 
>             Định dạng: `scale*(q-offset)`
    3. Triển khai các hàm sau

        - Init

gpointer gst_ml_module_open (void);
                Copy to clipboard
        - De-init

void gst_ml_module_close (gpointer instance);
                Copy to clipboard
        - Caps

GstCaps *gst_ml_module_caps (void);
                Copy to clipboard
        - Đặt cấu hình

gboolean gst_ml_module_configure (gpointer instance,
                                                  GstStructure * settings);
                Copy to clipboard

            Kiểm tra dytpe, scale và offset của mô-đun.
        - Giải lượng tử hóa

static inline gdouble gst_ml_module_get_dequant_value (void       *data,
                                                                       GstMLType  mltype,
                                                                       guint      idx,
                                                                       gdouble    offset,
                                                                       gdouble    scale);
                Copy to clipboard

            Các giá trị scale và offset cần được truyền cho các model được lượng tử hóa
        - Hậu xử lý

gboolean gst_ml_module_process (gpointer    instance,
                                                GstMLFrame  *mlframe,
                                                gpointer     output);
                Copy to clipboard
        - Buffer suy luận

indata = GST_ML_FRAME_BLOCK_DATA (mlframe, 0);
                Copy to clipboard
        - Output buffer sẽ được điền bằng dữ liệu hậu xử lý

outdata = GST_VIDEO_FRAME_PLANE_DATA (vframe, 0);
                Copy to clipboard
        - Loại dữ liệu của model

mltype = GST_ML_FRAME_TYPE (mlframe);
                Copy to clipboard
        - Hậu xử lý (cho super resolution)

for (row = 0; row < GST_VIDEO_FRAME_HEIGHT (vframe row++) {
                    for (column = 0; column < GST_VIDEO_FRAME_WIDTH (vframe); column++) {
                        // Calculate the destination index.
                        idx = (((row * GST_VIDEO_FRAME_WIDTH (vframe)) + column) * bpp) + (row * padding)
                        outdata[idx] = gst_ml_module_get_dequant_value(indata, mltype, idx, submodule->qoffsets[0], submodule->qscales[0]) * 255;
                        outdata[idx + 1] = gst_ml_module_get_dequant_value(indata, mltype, idx + 1, submodule->qoffsets[0], submodule->qscales[0]) * 255;
                        outdata[idx + 2] = gst_ml_module_get_dequant_value(indata, mltype, idx + 2, submodule->qoffsets[0], submodule->qscales[0]) * 255;
                        if (bpp == 4)
                            outdata[idx + 3] = 0;
                    }
                }
                Copy to clipboard
    4. Cập nhật tên mô-đun trong tệp `gst-plugins-mlvsuperresolution/modules/CMakeLists.txt`.

        Dùng plugin hiện có làm tham chiếu:

        [gst-plugin-mlvsegmentation/modules/CMakeLists.txt · imsdk.lnx.2.0.0.r1-rel · CodeLinaro / le / platform / vendor / qcom-opensource / gst-plugins-qti-oss · GitLab](https://git.codelinaro.org/clo/le/platform/vendor/qcom-opensource/gst-plugins-qti-oss/-/blob/imsdk.lnx.2.0.0.r1-rel/gst-plugin-mlvsegmentation/modules/CMakeLists.txt?ref_type=heads)

## Các bước để cập nhật tệp BitBake nhằm biên dịch plugin

1. Hãy làm theo phần [tạo plugin Qualcomm IM SDK](https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-51/create-your-imsdk-plugin.html) để biết hướng dẫn về cách biên dịch và cài đặt plugin siêu phân giải.
2. Thiết lập Wayland display.

ssh root@[IP address of the target device]
        Copy to clipboard

Ghi chú

Nếu được nhắc, hãy nhập mật khẩu `oelinux123` cho shell ssh.

export XDG_RUNTIME_DIR=/dev/socket/weston && export WAYLAND_DISPLAY=wayland-1
        Copy to clipboard

Tham khảo pipeline GStreamer để dùng plugin qtimlvsuperresolution

gst-launch-1.0 -e --gst-debug=2,qtimltflite:7 filesrc location=/etc/media/video.mp4 ! qtdemux ! queue ! h264parse ! \
    v4l2h264dec capture-io-mode=4 output-io-mode=4 ! video/x-raw,format=NV12 ! queue ! tee name=split \
    split. ! queue ! qtivcomposer name=mixer \
    sink_0::position="<0, 0>" sink_0::dimensions="<960, 1080>" \
    sink_1::position="<960, 0>" sink_1::dimensions="<960, 1080>" \
    ! queue ! waylandsink sync=false fullscreen=true \
    split. ! qtimlvconverter ! queue ! \
    qtimltflite delegate=external external-delegate-path=libQnnTFLiteDelegate.so \
    external-delegate-options="QNNExternalDelegate,backend_type=htp;" model=/etc/models/quicksrnetlarge_quantized.tflite ! queue ! \
    qtimlvsuperresolution module=srnet constants="qsrnetlarge,q-offsets=<0.0>,q-scales=<1.0>;" ! \
    video/x-raw,width=512,height=512,format=RGB ! queue ! mixer.
    Copy to clipboard

Ghi chú

Độ phân giải của video đầu vào phải là 128 x 128 x 3. Theo `quicksrnetlarge_quantized.tflite`, kích thước đầu vào model là 128 x 128 x 3.

Last Published: Dec 23, 2025

[Previous Topic
Phát triển plugin GStreamer tùy chỉnh](https://docs.qualcomm.com/bundle/publicresource/80-70020-15BV/topics/general-guidelines-for-developing-gstreamer-plugin.md) [Next Topic
Dùng các model và nhãn trên AI Hub với GStreamer API](https://docs.qualcomm.com/bundle/publicresource/80-70020-15BV/topics/ai-hub-qualcomm-im-sdk.md)