#![allow(unused_imports)] #![allow(unused_variables)] use clap::{App, Arg}; use himpp::mpi::vdec::{ VdecChn, VdecChnAttrBuilder, VdecModParam, VdecStream, VideoDisplayMode as VdecVideoDisplayMode, VideoMode as VdecVideoMode, }; use himpp::mpi::venc::{VencChn, VencChnAttrBuilder, VencModParam, VencModType, VencStreamPacks}; use himpp::{ hifb, himipi::{ComboDevAttrBuilder, DataType as MipiDataType, LaneDivideMode, MipiReceiver}, mpi::hdmi::{HdmiCore, HdmiId, HdmiPortBuilder}, mpi::sys::{SysBinder, SysManager, ViVpssMode}, mpi::types::{DynamicRange, PixelFormat, Rect, Size, VideoInterface, VideoStandard, WdrMode}, mpi::vb::{VbConfigBuilder, VbManager, VbRemapMode, VbUid}, mpi::vi::{ ViChn, ViChnAttrBuilder, ViDev, ViDevAttrBuilder, ViDumpType, ViPipe, ViPipeAttrBuilder, ViRephaseMode, }, mpi::vo::{VoChn, VoChnAttrBuilder, VoDev, VoLayer, VoPubAttrBuilder, VoVideoLayerAttrBuilder}, mpi::vpss::{ VpssChn, VpssChnAttrBuilder, VpssChnMode, VpssCropInfo, VpssGrp, VpssGrpAttrBuilder, }, mpi::{sys, vb}, }; use pavo_traits::AlignUpwards; use poller::{EventContext, Events, Poller}; use std::convert::TryInto; use std::fs::File; use std::io::prelude::*; use std::sync::Arc; fn main() -> Result<(), Box> { let matches = App::new("vi-vpss-venc-vdec") .version("1.0") .author("Varphone Wong ") .about("The example of pipeline: VI -> VPSS -> VENC -> VDEC -> VO") .arg( Arg::with_name("framerate") .short("f") .long("framerate") .help("Set the Video Framerate") .takes_value(true), ) .arg( Arg::with_name("vi-size") .short("v") .long("vi-size") .help("Set the Video Input Size") .takes_value(true), ) .get_matches(); let fps: u32 = matches .value_of("framerate") .unwrap_or("25") .parse() .unwrap(); let vi_size = Size::from(matches.value_of("vi-size").unwrap_or("1280x720")); let vb_pool1 = (vi_size.width * vi_size.height * 3 / 2).align_upwards(64); let vb_pool2 = (vi_size.width * vi_size.height * 2).align_upwards(64); let vb_conf = VbConfigBuilder::new() .pool(vb_pool1.into(), 8, VbRemapMode::None, "") .pool(vb_pool2.into(), 8, VbRemapMode::None, "") .build(); let _vb_mgr = VbManager::new(&vb_conf, &[(VbUid::VDEC, &vb_conf)]); let _sys_mgr = SysManager::with_align(64, Some(_vb_mgr)); let vi_vpss_modes = [ ViVpssMode::BothOffline, ViVpssMode::BothOffline, ViVpssMode::BothOffline, ViVpssMode::BothOffline, ViVpssMode::BothOffline, ViVpssMode::BothOffline, ViVpssMode::BothOffline, ViVpssMode::BothOffline, ]; _sys_mgr.set_vi_vpss_mode(&vi_vpss_modes).unwrap(); let vo_attr = VoPubAttrBuilder::new() .with_bg_color(0x0000ffff) .with_video_interface(VideoInterface::Hdmi) .with_video_standard(VideoStandard::Hd1080p60) .build(); let vo_dev0 = Arc::new(VoDev::new(0, &vo_attr)); let vo_vl_attr = VoVideoLayerAttrBuilder::with_current(0) .with_disp_rect(Rect::new(0, 0, 1920, 1080)) .with_image_size(Size::new(1920, 1080)) .with_disp_framerate(60) .with_pixel_format(PixelFormat::YvuSemiPlanar420) .with_double_frame(false) .with_cluster_mode(false) .with_dynamic_range(DynamicRange::Sdr8) .build(); let vo_vl0 = Arc::new(VoLayer::new(0, &vo_vl_attr, Arc::clone(&vo_dev0))); vo_vl0.set_buf_len(3).unwrap(); vo_vl0.enable().unwrap(); let vo_chn0_attr = VoChnAttrBuilder::with_current(0, &vo_vl0) .with_priority(0) .with_disp_rect(Rect::new(0, 0, 960, 540)) .build(); let vo_chn0 = Arc::new(VoChn::new(0, &vo_chn0_attr, Arc::clone(&vo_vl0))); vo_chn0.show()?; let vo_chn1_attr = VoChnAttrBuilder::with_current(1, &vo_vl0) .with_priority(0) .with_disp_rect(Rect::new(960, 0, 960, 540)) .build(); let vo_chn1 = Arc::new(VoChn::new(1, &vo_chn1_attr, Arc::clone(&vo_vl0))); vo_chn1.show()?; let vo_chn2_attr = VoChnAttrBuilder::with_current(2, &vo_vl0) .with_priority(0) .with_disp_rect(Rect::new(0, 540, 960, 540)) .build(); let vo_chn2 = Arc::new(VoChn::new(2, &vo_chn2_attr, Arc::clone(&vo_vl0))); vo_chn2.show()?; let vo_chn3_attr = VoChnAttrBuilder::with_current(3, &vo_vl0) .with_priority(0) .with_disp_rect(Rect::new(960, 540, 960, 540)) .build(); let vo_chn3 = Arc::new(VoChn::new(3, &vo_chn3_attr, Arc::clone(&vo_vl0))); vo_chn3.show()?; let hdmi_core = Arc::new(HdmiCore::new()); let hdmi_port = HdmiPortBuilder::with_dvi_1080p60(HdmiId::Hdmi0, Arc::clone(&hdmi_core)).build(); hdmi_port.start().unwrap(); assert_eq!(Arc::strong_count(&hdmi_core), 2); let mipi_rx = MipiReceiver::new(); assert!(mipi_rx.set_hs_mode(LaneDivideMode::Mode8)); // 4+4+4+2+2 assert!(mipi_rx.enable_mipi_clock(0)); assert!(mipi_rx.reset_mipi(0)); assert!(mipi_rx.enable_sensor_clock(0)); assert!(mipi_rx.reset_sensor(0)); let mipi_attr = ComboDevAttrBuilder::new(0) .with_mipi() .with_size(vi_size.width, vi_size.height) .with_data_type(MipiDataType::Yuv4228Bit) .with_lanes([0, 1, 2, 3, -1, -1, -1, -1]) .build(); assert!(mipi_rx.set_dev_attr(&mipi_attr)); assert!(mipi_rx.unreset_mipi(0)); assert!(mipi_rx.unreset_sensor(0)); let vi_dev_attr = ViDevAttrBuilder::new() .with_mipi_yuv422() .with_multiplex(1) .with_component_mask([0xff000000, 0x00ff0000]) .with_progressive() .with_yuv() .with_yuv_uyvy() .with_size(vi_size) .with_bas_scale(vi_size) .with_bas_rephase(ViRephaseMode::None, ViRephaseMode::None) .with_wdr(WdrMode::None, vi_size.height) .build(); let vi_dev0 = Arc::new(ViDev::new(0, Some(&vi_dev_attr))); #[cfg(not(feature = "hi3559av100"))] vi_dev0.bind_mipi(0).unwrap(); vi_dev0.bind_pipes(&[0, 1]).unwrap(); let vi_pipe_attr = ViPipeAttrBuilder::new_yuv422_3dnr_rfr() .with_max_size(vi_size) .build(); let vi_pipe0 = Arc::new(ViPipe::new(0, &vi_pipe_attr)); let vi_pipe1 = Arc::new(ViPipe::new(1, &vi_pipe_attr)); let vi_chn_attr = ViChnAttrBuilder::new_yuv422_sdr8_linear() .with_size(vi_size) .build(); let _vi_chn0 = ViChn::new(0, Some(&vi_chn_attr), Arc::clone(&vi_pipe0)); let _vi_chn1 = ViChn::new(0, Some(&vi_chn_attr), Arc::clone(&vi_pipe1)); // vi_pipe0.set_dump_attr(true, 3, ViDumpType::Yuv); vi_pipe0.set_vc_number(0).unwrap(); vi_pipe0.start().unwrap(); // vi_pipe1.set_dump_attr(true, 3, ViDumpType::Yuv); vi_pipe1.set_vc_number(1).unwrap(); vi_pipe1.start().unwrap(); let vpss_grp_attr = VpssGrpAttrBuilder::new().with_max_size(vi_size).build(); let vpss_grp0 = Arc::new(VpssGrp::new(0, &vpss_grp_attr)); let vpss_crop = VpssCropInfo::with_abs(Rect::with_size(vi_size)); vpss_grp0.set_crop(&vpss_crop).unwrap(); let vpss_chn_attr = VpssChnAttrBuilder::new() .with_mode(VpssChnMode::User) .with_size(vi_size) .build(); let vpss_chn0 = Arc::new(VpssChn::new(0, &vpss_chn_attr, Arc::clone(&vpss_grp0))); let vpss_chn1 = Arc::new(VpssChn::new(1, &vpss_chn_attr, Arc::clone(&vpss_grp0))); vpss_grp0.start().unwrap(); let mut mod_param = VencModParam::with_current(VencModType::H265e)?; mod_param.h265e_mut().set_one_stream_buffer(1); mod_param.apply()?; let venc_chn_attr = VencChnAttrBuilder::with_h265_720p(25).build(); let venc_chn0 = Arc::new(VencChn::new(0, &venc_chn_attr)); venc_chn0.start_recv_frame(-1)?; let vdec_chn_attr = VdecChnAttrBuilder::new() .with_h265() .with_mode(VdecVideoMode::Stream) .with_max_size(vi_size) .with_stream_buf_size(1280 * 1280 * 3 / 2) .with_frame_buf_size((1280 * 720 * 2).try_into().unwrap()) .with_frame_buf_count(8) .with_ref_frame_num(3) .with_tempral_mvp(true) // .with_tmv_buf_size(1280*720) .build(); let vdec_chn0 = Arc::new(VdecChn::new(0, &vdec_chn_attr)); vdec_chn0.set_display_mode(VdecVideoDisplayMode::Preview)?; vdec_chn0.reset()?; vdec_chn0.start_recv_stream()?; let _b1 = SysBinder::new(&vi_pipe0, &vpss_grp0); let _b2 = SysBinder::new(&vpss_chn0, &venc_chn0); let _b3 = SysBinder::new(&vpss_chn1, &vo_chn0); let _b4 = SysBinder::new(&vdec_chn0, &vo_chn1); let mut poller = Poller::new()?; poller.add(0, Events::new().read(), None).unwrap(); // poller // .add( // vpss_chn0.get_fd().unwrap(), // Events::new().read(), // Some(Arc::clone(&vpss_chn0) as EventContext), // ) // .unwrap(); poller .add( venc_chn0.get_fd().unwrap(), Events::new().read(), Some(Arc::clone(&venc_chn0) as EventContext), ) .unwrap(); // poller // .add( // vdec_chn0.get_fd().unwrap(), // Events::new().read(), // Some(Arc::clone(&vdec_chn0) as EventContext), // ) // .unwrap(); println!("Press enter to exit ..."); 'outer: loop { let events = poller.pull_events(1000).unwrap(); for (_fd, _events, ctx) in events.iter() { match ctx { Some(ref v) => { if let Some(chn) = v.downcast_ref::() { let info = chn.get_frame(0).unwrap(); let vf = info.video_frame(); // let mut file = File::create("/tmp/foo.yuv").unwrap(); let planes = vf.plane_memories(); println!( "New Frame: chn={}, size={}, pts={}", chn, vf.size(), vf.pts() ); for a in 0..planes.len() { // file.write(planes[a].as_bytes()).unwrap(); } } else if let Some(chn) = v.downcast_ref::() { let (stream, packs) = chn.get_stream(0, None).unwrap(); // println!("New Byte Stream: {:?}, {:?}", stream, packs); let sp = VencStreamPacks::new( Arc::clone(v).downcast::().unwrap(), stream, packs, ); for p in sp.packs() { let b = &p.as_bytes()[p.offset()..]; println!("{:02x?}", &b[..16]); let s = VdecStream::with_bytes(b); vdec_chn0.send_stream(&s, -1); } } } None => { if _fd == &0 { break 'outer; } } } } } Ok(()) }