【分享】修改V4L2的Video Pipeline的devicetree


介紹

PetaLinux 能夠根據Vivado的設計,自動生成V4L2的Video Pipeline的devicetree。但是它主要為Xilinx的VCU TRD服務,測試的組合比較少。很多時候,需要根據自己的工程,修改V4L2的Video Pipeline的devicetree。

硬件設計

有項目需要對輸入的視頻,既需要對原始視頻做編解碼,也需要縮放后再做編解碼。於是創建了下面的硬件設計。
V4L2硬件設計

axis_data_fifo主要用於暫時緩存數據。axis_broadcaster和vpss之間的axis_data_fifo、axis_register_slice,可以刪除,完全不影響共。

兩個framebuffer_write的tready通過邏輯門的“或”操作,連接到了一起,再連接到前級axis_register_slice的輸入,保證只要有一個framebuffer_write在工作,前面的模塊就能向后輸出數據。

devicetree

對於上述的硬件設計,對應的V4L2的devicetree如下:

&amba_pl {

    /delete-node/ axis_broadcasterhdmi_input_axis_broadcaster_0@0;
    
    /* media-ctl prints out each node name of the video pipeline.
       hdmi_brdcst_0@0: media-ctl prints it out. */
    hdmi_brdcst_0_lb: hdmi_brdcst_0@0 {
        compatible = "xlnx,axis-broadcaster-1.1";
        
        hdmi_brdcst_0_ports: ports {
            #address-cells = <1>;
            #size-cells = <0>;  
        };        
    };
    
    /delete-node/ vcapaxis_broad_out1hdmi_input_axis_broadcaster_0;
    /delete-node/ vcap_hdmi_input_v_proc_ss_0;
    
    /* vcap_hdmi_brdcst_0: media-ctl prints it out. */
    vcap_hdmi_brdcst_0 {
        compatible = "xlnx,video";
        dma-names = "port0", "port1";
        dmas = <&hdmi_input_v_frmbuf_wr_1 0>, <&hdmi_input_v_frmbuf_wr_0 0>;
        
        /* vcap_hdmi_brdcst_0_ports: Linux prints it out in log. */
        vcap_hdmi_brdcst_0_ports: ports {
            #address-cells = <1>;
            #size-cells = <0>;
            
            vcap_broadcaster_0_port1: port@0 {
                direction = "input";
                reg = <1>;
                /*  Video input pipeline 1: 
                        hdmi_rx_ss --> broadcaster_0 : 1 --> v_proc_ss_0 --> v_frmbuf_wr_1
                    hdmi_rx_ss : source_to_axis_broad_in0_from_v_hdmi_rx_ss_0
                    broadcaster_0 : out 1 : port2 :: src_to_vpss0_from_broad_port2_hwout1 
                    v_proc_ss_0 @a0040000 port@0 :: sink_to_vpss0_from_broad_port2_hwout1
                    v_proc_ss_0 @a0040000 port@1 :: src_to_frmbuf_wr1_from_vpss_0
                    v_frmbuf_wr_1 @a0080000 :: hdmi_input_v_frmbuf_wr_1
                */
                sink_to_frmbuf_wr1_from_vpss_0: endpoint {
                        remote-endpoint = <&src_to_frmbuf_wr1_from_vpss_0>;
                };
            };
            
            vcap_broadcaster_0_port2: port@1 {
                direction = "input";
                reg = <0>;
                /*  Video input pipeline 0: 
                        hdmi_rx_ss --> broadcaster_0 : 0 --> v_frmbuf_wr_0
                    hdmi_rx_ss : source_to_axis_broad_in0_from_v_hdmi_rx_ss_0
                    broadcaster_0 : out 0 : port1 ::  src_to_frmbuf_wr0_from_broad_port1_hwout0
                    v_frmbuf_wr_1 @a0010000 :: hdmi_input_v_frmbuf_wr_0
                    hdmi_input_ v_frmbuf_wr_0 hdmi_input_ axis_broadcaster_0 
                */
                sink_to_frmbuf_wr0_from_broad_port1_hwout0: endpoint {
                        remote-endpoint = <&src_to_frmbuf_wr0_from_broad_port1_hwout0>;
                };                          
            };

        };
    };
};

/* hdmi_input_v_hdmi_rx_ss_0: v_hdmi_rx_ss@a0000000 */
&hdmirx_porthdmi_input_v_hdmi_rx_ss_0 {
    source_to_axis_broad_in0_from_v_hdmi_rx_ss_0: endpoint {
            remote-endpoint = <&sink_to_broad_in0__from_v_hdmi_rx_ss_0>;
    };
};

&hdmi_brdcst_0_ports{

   /delete-node/ axis_broad_port1hdmi_input_axis_broadcaster_0;
   /delete-node/ axis_broad_port2hdmi_input_axis_broadcaster_0;
   /delete-node/ axis_broad_port0hdmi_input_axis_broadcaster_0;

    axis_broad_port1_hw_output0: port@1 {
        reg = <1>;
        src_to_frmbuf_wr0_from_broad_port1_hwout0: endpoint {
            remote-endpoint = <&sink_to_frmbuf_wr0_from_broad_port1_hwout0>;
        };
    };
    axis_broad_port2_hw_output1: port@2 {
        reg = <2>;
        src_to_vpss0_from_broad_port2_hwout1: endpoint {
            remote-endpoint = <&sink_to_vpss0_from_broad_port2_hwout1>;
        };
    };
    axis_broad_port0_hw_input: port@0 {
        reg = <0>;
        sink_to_broad_in0__from_v_hdmi_rx_ss_0: endpoint {
            remote-endpoint = <&source_to_axis_broad_in0_from_v_hdmi_rx_ss_0>;
        };
    };
};

&scaler_portshdmi_input_v_proc_ss_0{

    /delete-node/ port@0;
    /delete-node/ port@1;
    
    scaler_port1_v_proc_ss_0: port@1 {
        /* For xlnx,video-format user needs to fill as per their requirement */
        reg = <1>;
        xlnx,video-format = <3>;
        xlnx,video-width = <8>;
        src_to_frmbuf_wr1_from_vpss_0: endpoint {
            remote-endpoint = <&sink_to_frmbuf_wr1_from_vpss_0>;
        };
    };
    scaler_port0_v_proc_ss_0: port@0 {
        /* For xlnx,video-format user needs to fill as per their requirement */
        reg = <0>;
        xlnx,video-format = <3>;
        xlnx,video-width = <8>;
        sink_to_vpss0_from_broad_port2_hwout1: endpoint {
            remote-endpoint = <&src_to_vpss0_from_broad_port2_hwout1>;
        };
    };
};    

上述的devicetree,使用了更短更好理解的標簽名稱。

v_proc_ss的devicetree里,port@0是輸入;port@1是輸出。
broadcaster的devicetree里,port@0是輸入;port@1和port@2是輸出。

另外,V4L2的設備號,根據"xlnx,video"設備里的port順序分配。 如果port@0在port@1后面,那么port@0也會被分配video1; 而port@1也會被分配video0.

測試環境

PetaLinux 2020.2
Linux 5.4.0
ZCU106


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM