This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDA4VEN-Q1: Mosaic Node failing to process two images

Part Number: TDA4VEN-Q1


Tool/software:

Hi,

I have a custom pipeline pictured below:

EDIT: I have made a new picture that more accurately resembles the pipeline that I am testing with

I'm having trouble with the Mosaic node.  I'm building these two pipelines by hand (similar to app single cam twice).  They have the same resolution and the same bit depth.  I put the output of MSC0 and MSC1 into their own unique object arrays.  I'm configuring the mosaic node as follows:

static void set_img_mosaic_params(ImgMosaicObj *imgMosaicObj, vx_uint32 in_width, vx_uint32 in_height, vx_int32 numCh)
{
    vx_int32 idx, ch;
    vx_int32 grid_size = 2;

    imgMosaicObj->out_width    = 1920;
    imgMosaicObj->out_height   = 1080;

    imgMosaicObj->num_inputs   = numCh;

    idx = 0;

    tivxImgMosaicParamsSetDefaults(&imgMosaicObj->params);

    for(ch = 0; ch < numCh; ch++)
    {
        vx_int32 winX = ch%grid_size;
        vx_int32 winY = ch/grid_size;

        imgMosaicObj->params.windows[idx].startX  = (winX * (in_width/grid_size));
        imgMosaicObj->params.windows[idx].startY  = (winY * (in_height/grid_size));
        imgMosaicObj->params.windows[idx].width   = in_width/grid_size;
        imgMosaicObj->params.windows[idx].height  = in_height/grid_size;
        imgMosaicObj->params.windows[idx].input_select   = ch;

        imgMosaicObj->params.windows[idx].channel_select = 0;

        idx++;
    }

    imgMosaicObj->params.num_windows  = idx;

    /* Number of time to clear the output buffer before it gets reused */
    imgMosaicObj->params.clear_count  = NUM_BUFS;
}

// In the main method:
{
// ...
    vx_uint16 resized_width, resized_height;
    appIssGetResizeParams(IMX728_OUT_WIDTH, IMX728_OUT_HEIGHT, 1920, 1080, &resized_width, &resized_height);

    set_img_mosaic_params(&obj->graph_obj->mosiacObj, resized_width, resized_height, 2);
    status = app_init(obj->graph_obj);
// ...
}

// Later - in create graph
    vx_uint16 resized_width, resized_height;
    appIssGetResizeParams(IMX728_OUT_WIDTH, IMX728_OUT_HEIGHT, 1920, 1080, &resized_width, &resized_height);
    vx_image output_template = vxCreateImage(obj->context, resized_width, resized_height, VX_DF_IMAGE_NV12);
    obj->mosiacObj.input_arr[0] = vxCreateObjectArray(obj->context, (vx_reference) output_template, 1);
    vxReleaseImage(&output_template);
    
    vx_image output_template2 = vxCreateImage(obj->context, resized_width, resized_height, VX_DF_IMAGE_NV12);
    obj->mosiacObj.input_arr[1] = vxCreateObjectArray(obj->context, (vx_reference) output_template2, 1);
    vxReleaseImage(&output_template2);
    
    ...
    
    app_create_graph_img_mosaic(obj->graph, &obj->mosiacObj, NULL);
    tivxSetNodeParameterNumBufByIndex(obj->mosiacObj.node, 1, NUM_BUFS);

and I get this output:

```

[MCU2_0] 86.341393 s: VX_ZONE_ERROR: [tivxMemRegionTranslate:52] Invalid memtype
[MCU2_0] 86.341436 s: VX_ZONE_ERROR: [tivxMemShared2PhysPtr:334] Invalid mem_heap_region -1662795120
[MCU2_0] 86.341556 s: VX_ZONE_ERROR: [tivxKernelImgMosaicMscDrvSubmit:1075] Failed to Submit Request: -2
[MCU2_0] 86.407941 s: VX_ZONE_ERROR: [tivxMemRegionTranslate:52] Invalid memtype
[MCU2_0] 86.407983 s: VX_ZONE_ERROR: [tivxMemShared2PhysPtr:334] Invalid mem_heap_region -1662795120
[MCU2_0] 86.408129 s: VX_ZONE_ERROR: [tivxMemRegionTranslate:52] Invalid memtype
[MCU2_0] 86.408156 s: VX_ZONE_ERROR: [tivxMemShared2PhysPtr:334] Invalid mem_heap_region -1662795120
[MCU2_0] 86.408197 s: VX_ZONE_ERROR: [tivxKernelImgMosaicMscDrvSubmit:1075] Failed to Submit Request: -2

```

Have I misunderstood how the mosaic node works?

  • Hi Stuart,

    Your mosaic node configurations seems to be correct.

    the error shows that there is memory corruption happening in mcu2_0 core. can you disable aewb1 node and connect the output directly to ldc1 node from viss1 node and check if this issue solves.

    Regards,
    Gokul

  • Gokul,

    I have disabled the AEWB node for both pipelines.

    The LDC node was actually never on, but was only there as an example.

    I also disabled the MSC node in case that was changing something.

    I'm still getting these errors:
    ```
    [MCU2_0] 17540.121375 s: VX_ZONE_ERROR: [tivxMemRegionTranslate:52] Invalid memtype
    [MCU2_0] 17540.121417 s: VX_ZONE_ERROR: [tivxMemShared2PhysPtr:334] Invalid mem_heap_region -1313357168
    [MCU2_0] 17540.121517 s: VX_ZONE_ERROR: [tivxKernelImgMosaicMscDrvSubmit:1075] Failed to Submit Request
    [MCU2_0] 17540.188060 s: VX_ZONE_ERROR: [tivxMemRegionTranslate:52] Invalid memtype
    [MCU2_0] 17540.188098 s: VX_ZONE_ERROR: [tivxMemShared2PhysPtr:334] Invalid mem_heap_region -1313357168
    [MCU2_0] 17540.188202 s: VX_ZONE_ERROR: [tivxKernelImgMosaicMscDrvSubmit:1075] Failed to Submit Request
    [MCU2_0] 17540.254719 s: VX_ZONE_ERROR: [tivxMemRegionTranslate:52] Invalid memtype
    [MCU2_0] 17540.254760 s: VX_ZONE_ERROR: [tivxMemShared2PhysPtr:334] Invalid mem_heap_region -1313357168
    [MCU2_0] 17540.254867 s: VX_ZONE_ERROR: [tivxKernelImgMosaicMscDrvSubmit:1075] Failed to Submit Request
    ```

    I can see the image output on the display and update a few times before crashing.

  • I should note a couple things:

    The sensor outputs contexts interleaved, so it will stagger the frame for pipeline 1 and the frame for pipeline 2 by a few milliseconds (equal to 1/framerate).

    The sensor output is large.  It's got a native resolution of 3856 x 2176.

    I do not always get invald memtype and mem_heap_region errors, but I always get "failed to submit request".

    I've also failed to indicate what my end goal is.  I want to display text on the screen.  Unfortunately I've used both of the available image pipes on the J722S for displaying the output images, and any attempt to use a third display pipe for graphics results in failure to create the graph.  I am trying to use the mosaic node to combine the two existing outputs into one display node so I can use the other display pipe for grpahics.

  • Hi Stuart,

    How did you manage to get 2 virtual channel output form imx728 ? and also as per diagram capture_nodes are from different openvx context ?

    And what are these 2 channels giving as output, can you create single capture node ?

    I do not always get invald memtype and mem_heap_region errors, but I always get "failed to submit request".

    Something is corrupting in the mcu2_0, we faced this issue when aewb node is there with AE:off so I asked to remove the aewb node.

    I've also failed to indicate what my end goal is.  I want to display text on the screen.  Unfortunately I've used both of the available image pipes on the J722S for displaying the output images, and any attempt to use a third display pipe for graphics results in failure to create the graph.  I am trying to use the mosaic node to combine the two existing outputs into one display node so I can use the other display pipe for grpahics.

    This should be fine and we have sdk demos like multi_cam, front_camera to do similar usecase. Can I get more info on the sensor and how sensor is giving you output in 2 channels.

    Also share your openvx graph's dot output to verify if the graph is created properly.

    Regards,
    Gokul

  • How did you manage to get 2 virtual channel output form imx728 ? and also as per diagram capture_nodes are from different openvx context ?

    With a multi-context mode, the sensor is capable of outputting different virtual channels for a given context.

    Context 0 outputs on VC0

    Context 1 outputs on VC1

    I'm creating two CSIRX nodes - so I believe I end up with 2 csirx contexts.

    And what are these 2 channels giving as output, can you create single capture node ?

    I could make it one CSIRX capture node, they are both outputting at the same data rate, line count, data type, etc.  Just 2 different VCs.  The only thing that needs to be different between the graphs is exposure control, and also I need to have independent global / local tone mapping.  If you can show me how I might accomplish this I can rework my usecase :)

    Also share your openvx graph's dot output to verify if the graph is created properly.

    See attached:

    digraph dual_capture_graph {
    
      ColorScheme [shape=none, margin=0, label=<
    
            <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
    
            <TR><TD bgcolor="brown">CAPTURE2</TD></TR>
            <TR><TD bgcolor="blanchedalmond">VPAC_VISS1</TD></TR>
            <TR><TD bgcolor="antiquewhite">VPAC_MSC1</TD></TR>
            <TR><TD bgcolor="burlywood">DISPLAY1</TD></TR>
            </TABLE>>];
    
    
    
    /* List of Nodes */
    _capture_node(1) [label = "capture_node(1)", shape=box, color=brown, style=filled]
    _viss_node(1) [label = "viss_node(1)", shape=box, color=blanchedalmond, style=filled]
    _capture_node(0) [label = "capture_node(0)", shape=box, color=brown, style=filled]
    _viss_node(0) [label = "viss_node(0)", shape=box, color=blanchedalmond, style=filled]
    _mosaic_node [label = "mosaic_node", shape=box, color=antiquewhite, style=filled]
    _display_node(0) [label = "display_node(0)", shape=box, color=burlywood, style=filled]
    
    /* List of Data References */
    user_data_object_122 [shape=record , label="{user_data_object_122  }"]
    cap_buf_in[3](1) [shape=record , label="{cap_buf_in[3](1)  }"]
    viss_cfg(1) [shape=record , label="{viss_cfg(1)  }"]
    user_data_object_125 [shape=record , label="{user_data_object_125  }"]
    cap_buf_in[3](1) [shape=record , label="{cap_buf_in[3](1)  }"]
    viss_img_out(1) [shape=record , label="{viss_img_out(1)  | [in] mosaic_in(1)}"]
    mosaic_in(1) [shape=record , label="{mosaic_in(1)  }"]
    mosaic_in(1) [shape=record , label="{mosaic_in(1)  }"]
    user_data_object_124 [shape=record , label="{user_data_object_124  }"]
    user_data_object_107 [shape=record , label="{user_data_object_107  }"]
    cap_buf_in[3](0) [shape=record , label="{cap_buf_in[3](0)  }"]
    viss_cfg(0) [shape=record , label="{viss_cfg(0)  }"]
    user_data_object_110 [shape=record , label="{user_data_object_110  }"]
    cap_buf_in[3](0) [shape=record , label="{cap_buf_in[3](0)  }"]
    viss_img_out(0) [shape=record , label="{viss_img_out(0)  | [in] display_params(0)}"]
    display_params(0) [shape=record , label="{display_params(0)  }"]
    display_params(0) [shape=record , label="{display_params(0)  }"]
    user_data_object_109 [shape=record , label="{user_data_object_109  }"]
    mosaic_node_config [shape=record , label="{mosaic_node_config  }"]
    mosaic_img_out [shape=record , label="{mosaic_img_out  }"]
    user_data_object_128 [shape=record , label="{user_data_object_128  }"]
    
    
    user_data_object_122 -> _capture_node(1) 
    _capture_node(1) -> cap_buf_in[3](1) 
    viss_cfg(1) -> _viss_node(1) 
    null_viss_node(1)_1 [label="NULL"]
    null_viss_node(1)_1 -> _viss_node(1) 
    user_data_object_125 -> _viss_node(1) 
    cap_raw_in(1) -> _viss_node(1) 
    null_viss_node(1)_4 [label="NULL"]
    _viss_node(1) -> null_viss_node(1)_4 
    null_viss_node(1)_5 [label="NULL"]
    _viss_node(1) -> null_viss_node(1)_5 
    _viss_node(1) -> viss_img_out(1) 
    null_viss_node(1)_7 [label="NULL"]
    _viss_node(1) -> null_viss_node(1)_7 
    null_viss_node(1)_8 [label="NULL"]
    _viss_node(1) -> null_viss_node(1)_8 
    _viss_node(1) -> user_data_object_124 
    null_viss_node(1)_10 [label="NULL"]
    _viss_node(1) -> null_viss_node(1)_10 
    null_viss_node(1)_11 [label="NULL"]
    _viss_node(1) -> null_viss_node(1)_11 
    null_viss_node(1)_12 [label="NULL"]
    _viss_node(1) -> null_viss_node(1)_12 
    user_data_object_107 -> _capture_node(0) 
    _capture_node(0) -> cap_buf_in[3](0) 
    viss_cfg(0) -> _viss_node(0) 
    null_viss_node(0)_1 [label="NULL"]
    null_viss_node(0)_1 -> _viss_node(0) 
    user_data_object_110 -> _viss_node(0) 
    cap_raw_in(0) -> _viss_node(0) 
    null_viss_node(0)_4 [label="NULL"]
    _viss_node(0) -> null_viss_node(0)_4 
    null_viss_node(0)_5 [label="NULL"]
    _viss_node(0) -> null_viss_node(0)_5 
    _viss_node(0) -> viss_img_out(0) 
    null_viss_node(0)_7 [label="NULL"]
    _viss_node(0) -> null_viss_node(0)_7 
    null_viss_node(0)_8 [label="NULL"]
    _viss_node(0) -> null_viss_node(0)_8 
    _viss_node(0) -> user_data_object_109 
    null_viss_node(0)_10 [label="NULL"]
    _viss_node(0) -> null_viss_node(0)_10 
    null_viss_node(0)_11 [label="NULL"]
    _viss_node(0) -> null_viss_node(0)_11 
    null_viss_node(0)_12 [label="NULL"]
    _viss_node(0) -> null_viss_node(0)_12 
    mosaic_node_config -> _mosaic_node 
    _mosaic_node -> mosaic_img_out 
    null_mosaic_node_2 [label="NULL"]
    null_mosaic_node_2 -> _mosaic_node 
    display_params(0) -> _mosaic_node 
    mosaic_in(1) -> _mosaic_node 
    user_data_object_128 -> _display_node(0) 
    mosaic_img_out -> _display_node(0) 
    
    }
    
    digraph dual_capture_graph {
    
      ColorScheme [shape=none, margin=0, label=<
    
            <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
    
            <TR><TD bgcolor="brown">CAPTURE2</TD></TR>
            <TR><TD bgcolor="blanchedalmond">VPAC_VISS1</TD></TR>
            <TR><TD bgcolor="antiquewhite">VPAC_MSC1</TD></TR>
            <TR><TD bgcolor="burlywood">DISPLAY1</TD></TR>
            </TABLE>>];
    
    
    
    /* List of nodes ( Pipeline = 0 )*/
    n_54 [shape=record, label="{capture_node(1)|pipe 0|desc 54}", style=filled, fillcolor=brown]
    n_58 [shape=record, label="{viss_node(1)|pipe 0|desc 58}", style=filled, fillcolor=blanchedalmond]
    n_38 [shape=record, label="{capture_node(0)|pipe 0|desc 38}", style=filled, fillcolor=brown]
    n_42 [shape=record, label="{viss_node(0)|pipe 0|desc 42}", style=filled, fillcolor=blanchedalmond]
    n_59 [shape=record, label="{mosaic_node|pipe 0|desc 59}", style=filled, fillcolor=antiquewhite]
    n_61 [shape=record, label="{display_node(0)|pipe 0|desc 61}", style=filled, fillcolor=burlywood]
    
    /* List of nodes ( Pipeline = 1 )*/
    n_62 [shape=record, label="{capture_node(1)|pipe 1|desc 62}", style=filled, fillcolor=brown]
    n_65 [shape=record, label="{viss_node(1)|pipe 1|desc 65}", style=filled, fillcolor=blanchedalmond]
    n_68 [shape=record, label="{capture_node(0)|pipe 1|desc 68}", style=filled, fillcolor=brown]
    n_71 [shape=record, label="{viss_node(0)|pipe 1|desc 71}", style=filled, fillcolor=blanchedalmond]
    n_74 [shape=record, label="{mosaic_node|pipe 1|desc 74}", style=filled, fillcolor=antiquewhite]
    n_77 [shape=record, label="{display_node(0)|pipe 1|desc 77}", style=filled, fillcolor=burlywood]
    
    /* List of nodes ( Pipeline = 2 )*/
    n_63 [shape=record, label="{capture_node(1)|pipe 2|desc 63}", style=filled, fillcolor=brown]
    n_66 [shape=record, label="{viss_node(1)|pipe 2|desc 66}", style=filled, fillcolor=blanchedalmond]
    n_69 [shape=record, label="{capture_node(0)|pipe 2|desc 69}", style=filled, fillcolor=brown]
    n_72 [shape=record, label="{viss_node(0)|pipe 2|desc 72}", style=filled, fillcolor=blanchedalmond]
    n_75 [shape=record, label="{mosaic_node|pipe 2|desc 75}", style=filled, fillcolor=antiquewhite]
    n_78 [shape=record, label="{display_node(0)|pipe 2|desc 78}", style=filled, fillcolor=burlywood]
    
    /* List of nodes ( Pipeline = 3 )*/
    n_64 [shape=record, label="{capture_node(1)|pipe 3|desc 64}", style=filled, fillcolor=brown]
    n_67 [shape=record, label="{viss_node(1)|pipe 3|desc 67}", style=filled, fillcolor=blanchedalmond]
    n_70 [shape=record, label="{capture_node(0)|pipe 3|desc 70}", style=filled, fillcolor=brown]
    n_73 [shape=record, label="{viss_node(0)|pipe 3|desc 73}", style=filled, fillcolor=blanchedalmond]
    n_76 [shape=record, label="{mosaic_node|pipe 3|desc 76}", style=filled, fillcolor=antiquewhite]
    n_79 [shape=record, label="{display_node(0)|pipe 3|desc 79}", style=filled, fillcolor=burlywood]
    
    /* Dependency of nodes within pipeline (Pipeline = 0) */
    n_54 -> n_58 [style=dashed]
    n_54 -> n_58 [style=dashed, color=gray]
    n_58 -> n_59 [style=dashed]
    n_38 -> n_42 [style=dashed]
    n_38 -> n_42 [style=dashed, color=gray]
    n_42 -> n_59 [style=dashed]
    n_42 -> n_59 [style=dashed, color=gray]
    n_58 -> n_59 [style=dashed, color=gray]
    n_59 -> n_61 [style=dashed]
    n_59 -> n_61 [style=dashed, color=gray]
    
    /* Dependency of nodes within pipeline (Pipeline = 1) */
    n_62 -> n_65 [style=dashed]
    n_62 -> n_65 [style=dashed, color=gray]
    n_65 -> n_74 [style=dashed]
    n_68 -> n_71 [style=dashed]
    n_68 -> n_71 [style=dashed, color=gray]
    n_71 -> n_74 [style=dashed]
    n_71 -> n_74 [style=dashed, color=gray]
    n_65 -> n_74 [style=dashed, color=gray]
    n_74 -> n_77 [style=dashed]
    n_74 -> n_77 [style=dashed, color=gray]
    
    /* Dependency of nodes within pipeline (Pipeline = 2) */
    n_63 -> n_66 [style=dashed]
    n_63 -> n_66 [style=dashed, color=gray]
    n_66 -> n_75 [style=dashed]
    n_69 -> n_72 [style=dashed]
    n_69 -> n_72 [style=dashed, color=gray]
    n_72 -> n_75 [style=dashed]
    n_72 -> n_75 [style=dashed, color=gray]
    n_66 -> n_75 [style=dashed, color=gray]
    n_75 -> n_78 [style=dashed]
    n_75 -> n_78 [style=dashed, color=gray]
    
    /* Dependency of nodes within pipeline (Pipeline = 3) */
    n_64 -> n_67 [style=dashed]
    n_64 -> n_67 [style=dashed, color=gray]
    n_67 -> n_76 [style=dashed]
    n_70 -> n_73 [style=dashed]
    n_70 -> n_73 [style=dashed, color=gray]
    n_73 -> n_76 [style=dashed]
    n_73 -> n_76 [style=dashed, color=gray]
    n_67 -> n_76 [style=dashed, color=gray]
    n_76 -> n_79 [style=dashed]
    n_76 -> n_79 [style=dashed, color=gray]
    
    /* List of nodes ( Pipeline = 0 )*/
    ln_54 [shape=record, label="{capture_node(1)|pipe 0|desc 54}", style=filled, fillcolor=brown]
    ln_58 [shape=record, label="{viss_node(1)|pipe 0|desc 58}", style=filled, fillcolor=blanchedalmond]
    ln_38 [shape=record, label="{capture_node(0)|pipe 0|desc 38}", style=filled, fillcolor=brown]
    ln_42 [shape=record, label="{viss_node(0)|pipe 0|desc 42}", style=filled, fillcolor=blanchedalmond]
    ln_59 [shape=record, label="{mosaic_node|pipe 0|desc 59}", style=filled, fillcolor=antiquewhite]
    ln_61 [shape=record, label="{display_node(0)|pipe 0|desc 61}", style=filled, fillcolor=burlywood]
    
    /* List of nodes ( Pipeline = 1 )*/
    ln_62 [shape=record, label="{capture_node(1)|pipe 1|desc 62}", style=filled, fillcolor=brown]
    ln_65 [shape=record, label="{viss_node(1)|pipe 1|desc 65}", style=filled, fillcolor=blanchedalmond]
    ln_68 [shape=record, label="{capture_node(0)|pipe 1|desc 68}", style=filled, fillcolor=brown]
    ln_71 [shape=record, label="{viss_node(0)|pipe 1|desc 71}", style=filled, fillcolor=blanchedalmond]
    ln_74 [shape=record, label="{mosaic_node|pipe 1|desc 74}", style=filled, fillcolor=antiquewhite]
    ln_77 [shape=record, label="{display_node(0)|pipe 1|desc 77}", style=filled, fillcolor=burlywood]
    
    /* List of nodes ( Pipeline = 2 )*/
    ln_63 [shape=record, label="{capture_node(1)|pipe 2|desc 63}", style=filled, fillcolor=brown]
    ln_66 [shape=record, label="{viss_node(1)|pipe 2|desc 66}", style=filled, fillcolor=blanchedalmond]
    ln_69 [shape=record, label="{capture_node(0)|pipe 2|desc 69}", style=filled, fillcolor=brown]
    ln_72 [shape=record, label="{viss_node(0)|pipe 2|desc 72}", style=filled, fillcolor=blanchedalmond]
    ln_75 [shape=record, label="{mosaic_node|pipe 2|desc 75}", style=filled, fillcolor=antiquewhite]
    ln_78 [shape=record, label="{display_node(0)|pipe 2|desc 78}", style=filled, fillcolor=burlywood]
    
    /* List of nodes ( Pipeline = 3 )*/
    ln_64 [shape=record, label="{capture_node(1)|pipe 3|desc 64}", style=filled, fillcolor=brown]
    ln_67 [shape=record, label="{viss_node(1)|pipe 3|desc 67}", style=filled, fillcolor=blanchedalmond]
    ln_70 [shape=record, label="{capture_node(0)|pipe 3|desc 70}", style=filled, fillcolor=brown]
    ln_73 [shape=record, label="{viss_node(0)|pipe 3|desc 73}", style=filled, fillcolor=blanchedalmond]
    ln_76 [shape=record, label="{mosaic_node|pipe 3|desc 76}", style=filled, fillcolor=antiquewhite]
    ln_79 [shape=record, label="{display_node(0)|pipe 3|desc 79}", style=filled, fillcolor=burlywood]
    
    /* Dependency of nodes across pipeline ( Pipeline = 0 ) */
    ln_64 -> ln_54 [style=dashed]
    ln_67 -> ln_58 [style=dashed]
    ln_70 -> ln_38 [style=dashed]
    ln_73 -> ln_42 [style=dashed]
    ln_76 -> ln_59 [style=dashed]
    ln_79 -> ln_61 [style=dashed]
    
    /* Dependency of nodes across pipeline ( Pipeline = 1 ) */
    ln_54 -> ln_62 [style=dashed]
    ln_58 -> ln_65 [style=dashed]
    ln_38 -> ln_68 [style=dashed]
    ln_42 -> ln_71 [style=dashed]
    ln_59 -> ln_74 [style=dashed]
    ln_61 -> ln_77 [style=dashed]
    
    /* Dependency of nodes across pipeline ( Pipeline = 2 ) */
    ln_62 -> ln_63 [style=dashed]
    ln_65 -> ln_66 [style=dashed]
    ln_68 -> ln_69 [style=dashed]
    ln_71 -> ln_72 [style=dashed]
    ln_74 -> ln_75 [style=dashed]
    ln_77 -> ln_78 [style=dashed]
    
    /* Dependency of nodes across pipeline ( Pipeline = 3 ) */
    ln_63 -> ln_64 [style=dashed]
    ln_66 -> ln_67 [style=dashed]
    ln_69 -> ln_70 [style=dashed]
    ln_72 -> ln_73 [style=dashed]
    ln_75 -> ln_76 [style=dashed]
    ln_78 -> ln_79 [style=dashed]
    
    /* List of Data References */
    d_53 [shape=record , label="{user_data_object_122   | size 216 | desc 53}"]
    d_45 [shape=record , label="{cap_buf_in[3](1)    | desc 45}"]
    d_55 [shape=record , label="{viss_cfg(1)   | size 112 | desc 55}"]
    d_57 [shape=record , label="{user_data_object_125   | size 41995 | desc 57}"]
    d_45 [shape=record , label="{cap_buf_in[3](1)    | desc 45}"]
    d_26 [shape=record , label="{viss_img_out(1)  | [in] mosaic_in(1) | size 12585984 | desc 26}"]
    d_25 [shape=record , label="{mosaic_in(1)    | desc 25}"]
    d_25 [shape=record , label="{mosaic_in(1)    | desc 25}"]
    d_56 [shape=record , label="{user_data_object_124   | size 24640 | desc 56}"]
    d_37 [shape=record , label="{user_data_object_107   | size 216 | desc 37}"]
    d_29 [shape=record , label="{cap_buf_in[3](0)    | desc 29}"]
    d_39 [shape=record , label="{viss_cfg(0)   | size 112 | desc 39}"]
    d_41 [shape=record , label="{user_data_object_110   | size 41995 | desc 41}"]
    d_29 [shape=record , label="{cap_buf_in[3](0)    | desc 29}"]
    d_24 [shape=record , label="{viss_img_out(0)  | [in] display_params(0) | size 12585984 | desc 24}"]
    d_23 [shape=record , label="{display_params(0)    | desc 23}"]
    d_23 [shape=record , label="{display_params(0)    | desc 23}"]
    d_40 [shape=record , label="{user_data_object_109   | size 24640 | desc 40}"]
    d_17 [shape=record , label="{mosaic_node_config   | size 1424 | desc 17}"]
    d_18 [shape=record , label="{mosaic_img_out   | size 3110400 | desc 18}"]
    d_60 [shape=record , label="{user_data_object_128   | size 44 | desc 60}"]
    
    d_data_ref_q_171 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_171|bufs 4}"]
    d_29 [shape=record , label="{cap_buf_in[3](0)    | desc 29}"]
    d_29 -> d_data_ref_q_171
    d_30 [shape=record , label="{cap_raw_in(0)  | [in] cap_buf_in[3](0) | size 16873856 | desc 30}"]
    d_29 [shape=record , label="{cap_buf_in[3](0)    | desc 29}"]
    d_30 -> d_29 [style=dashed]
    d_31 [shape=record , label="{object_array_101    | desc 31}"]
    d_31 -> d_data_ref_q_171
    d_32 [shape=record , label="{raw_image_102  | [in] object_array_101 | size 16873856 | desc 32}"]
    d_31 [shape=record , label="{object_array_101    | desc 31}"]
    d_32 -> d_31 [style=dashed]
    d_33 [shape=record , label="{object_array_103    | desc 33}"]
    d_33 -> d_data_ref_q_171
    d_34 [shape=record , label="{raw_image_104  | [in] object_array_103 | size 16873856 | desc 34}"]
    d_33 [shape=record , label="{object_array_103    | desc 33}"]
    d_34 -> d_33 [style=dashed]
    d_35 [shape=record , label="{object_array_105    | desc 35}"]
    d_35 -> d_data_ref_q_171
    d_36 [shape=record , label="{raw_image_106  | [in] object_array_105 | size 16873856 | desc 36}"]
    d_35 [shape=record , label="{object_array_105    | desc 35}"]
    d_36 -> d_35 [style=dashed]
    d_data_ref_q_172 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_172|bufs 4}"]
    d_45 [shape=record , label="{cap_buf_in[3](1)    | desc 45}"]
    d_45 -> d_data_ref_q_172
    d_46 [shape=record , label="{cap_raw_in(1)  | [in] cap_buf_in[3](1) | size 16873856 | desc 46}"]
    d_45 [shape=record , label="{cap_buf_in[3](1)    | desc 45}"]
    d_46 -> d_45 [style=dashed]
    d_47 [shape=record , label="{object_array_116    | desc 47}"]
    d_47 -> d_data_ref_q_172
    d_48 [shape=record , label="{raw_image_117  | [in] object_array_116 | size 16873856 | desc 48}"]
    d_47 [shape=record , label="{object_array_116    | desc 47}"]
    d_48 -> d_47 [style=dashed]
    d_49 [shape=record , label="{object_array_118    | desc 49}"]
    d_49 -> d_data_ref_q_172
    d_50 [shape=record , label="{raw_image_119  | [in] object_array_118 | size 16873856 | desc 50}"]
    d_49 [shape=record , label="{object_array_118    | desc 49}"]
    d_50 -> d_49 [style=dashed]
    d_51 [shape=record , label="{object_array_120    | desc 51}"]
    d_51 -> d_data_ref_q_172
    d_52 [shape=record , label="{raw_image_121  | [in] object_array_120 | size 16873856 | desc 52}"]
    d_51 [shape=record , label="{object_array_120    | desc 51}"]
    d_52 -> d_51 [style=dashed]
    
    d_data_ref_q_173 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_173|bufs 4}"]
    d_25 [shape=record , label="{mosaic_in(1)    | desc 25}"]
    d_25 -> d_data_ref_q_173
    d_26 [shape=record , label="{viss_img_out(1)  | [in] mosaic_in(1) | size 12585984 | desc 26}"]
    d_25 [shape=record , label="{mosaic_in(1)    | desc 25}"]
    d_26 -> d_25 [style=dashed]
    d_80 [shape=record , label="{image_162   | size 12585984 | desc 80}"]
    d_80 -> d_data_ref_q_173
    d_81 [shape=record , label="{image_163   | size 12585984 | desc 81}"]
    d_81 -> d_data_ref_q_173
    d_82 [shape=record , label="{image_164   | size 12585984 | desc 82}"]
    d_82 -> d_data_ref_q_173
    d_data_ref_q_174 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_174|bufs 4}"]
    d_23 [shape=record , label="{display_params(0)    | desc 23}"]
    d_23 -> d_data_ref_q_174
    d_24 [shape=record , label="{viss_img_out(0)  | [in] display_params(0) | size 12585984 | desc 24}"]
    d_23 [shape=record , label="{display_params(0)    | desc 23}"]
    d_24 -> d_23 [style=dashed]
    d_83 [shape=record , label="{image_165   | size 12585984 | desc 83}"]
    d_83 -> d_data_ref_q_174
    d_84 [shape=record , label="{image_166   | size 12585984 | desc 84}"]
    d_84 -> d_data_ref_q_174
    d_85 [shape=record , label="{image_167   | size 12585984 | desc 85}"]
    d_85 -> d_data_ref_q_174
    d_data_ref_q_175 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_175|bufs 4}"]
    d_18 [shape=record , label="{mosaic_img_out   | size 3110400 | desc 18}"]
    d_18 -> d_data_ref_q_175
    d_86 [shape=record , label="{image_168   | size 3110400 | desc 86}"]
    d_86 -> d_data_ref_q_175
    d_87 [shape=record , label="{image_169   | size 3110400 | desc 87}"]
    d_87 -> d_data_ref_q_175
    d_88 [shape=record , label="{image_170   | size 3110400 | desc 88}"]
    d_88 -> d_data_ref_q_175
    
    
    /* List of data reference queues */
    d_113 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_171|bufs 4|pipe 0|in_nodes 1|desc 113 }"]
    d_115 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_171|bufs 4|pipe 1|in_nodes 1|desc 115 }"]
    d_117 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_171|bufs 4|pipe 2|in_nodes 1|desc 117 }"]
    d_119 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_171|bufs 4|pipe 3|in_nodes 1|desc 119 }"]
    d_123 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_172|bufs 4|pipe 0|in_nodes 1|desc 123 }"]
    d_125 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_172|bufs 4|pipe 1|in_nodes 1|desc 125 }"]
    d_127 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_172|bufs 4|pipe 2|in_nodes 1|desc 127 }"]
    d_129 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_172|bufs 4|pipe 3|in_nodes 1|desc 129 }"]
    
    d_133 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_173|bufs 4|pipe 0|in_nodes 1|desc 133 }"]
    d_134 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_173|bufs 4|pipe 1|in_nodes 1|desc 134 }"]
    d_135 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_173|bufs 4|pipe 2|in_nodes 1|desc 135 }"]
    d_136 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_173|bufs 4|pipe 3|in_nodes 1|desc 136 }"]
    d_138 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_174|bufs 4|pipe 0|in_nodes 1|desc 138 }"]
    d_139 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_174|bufs 4|pipe 1|in_nodes 1|desc 139 }"]
    d_140 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_174|bufs 4|pipe 2|in_nodes 1|desc 140 }"]
    d_141 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_174|bufs 4|pipe 3|in_nodes 1|desc 141 }"]
    d_143 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_175|bufs 4|pipe 0|in_nodes 1|desc 143 }"]
    d_144 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_175|bufs 4|pipe 1|in_nodes 1|desc 144 }"]
    d_145 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_175|bufs 4|pipe 2|in_nodes 1|desc 145 }"]
    d_146 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_175|bufs 4|pipe 3|in_nodes 1|desc 146 }"]
    
    
    /* Dependency of nodes within pipeline (Pipeline = 0) */
    d_53 -> n_54 
    n_54 -> d_123 
    d_55 -> n_58 
    d_57 -> n_58 
    d_123 -> n_58 
    n_58 -> d_133 
    n_58 -> d_56 
    d_37 -> n_38 
    n_38 -> d_113 
    d_39 -> n_42 
    d_41 -> n_42 
    d_113 -> n_42 
    n_42 -> d_138 
    n_42 -> d_40 
    d_17 -> n_59 
    n_59 -> d_143 
    d_138 -> n_59 
    d_133 -> n_59 
    d_60 -> n_61 
    d_143 -> n_61 
    
    /* Dependency of nodes within pipeline (Pipeline = 1) */
    d_53 -> n_62 
    n_62 -> d_125 
    d_55 -> n_65 
    d_57 -> n_65 
    d_125 -> n_65 
    n_65 -> d_134 
    n_65 -> d_56 
    d_37 -> n_68 
    n_68 -> d_115 
    d_39 -> n_71 
    d_41 -> n_71 
    d_115 -> n_71 
    n_71 -> d_139 
    n_71 -> d_40 
    d_17 -> n_74 
    n_74 -> d_144 
    d_139 -> n_74 
    d_134 -> n_74 
    d_60 -> n_77 
    d_144 -> n_77 
    
    /* Dependency of nodes within pipeline (Pipeline = 2) */
    d_53 -> n_63 
    n_63 -> d_127 
    d_55 -> n_66 
    d_57 -> n_66 
    d_127 -> n_66 
    n_66 -> d_135 
    n_66 -> d_56 
    d_37 -> n_69 
    n_69 -> d_117 
    d_39 -> n_72 
    d_41 -> n_72 
    d_117 -> n_72 
    n_72 -> d_140 
    n_72 -> d_40 
    d_17 -> n_75 
    n_75 -> d_145 
    d_140 -> n_75 
    d_135 -> n_75 
    d_60 -> n_78 
    d_145 -> n_78 
    
    /* Dependency of nodes within pipeline (Pipeline = 3) */
    d_53 -> n_64 
    n_64 -> d_129 
    d_55 -> n_67 
    d_57 -> n_67 
    d_129 -> n_67 
    n_67 -> d_136 
    n_67 -> d_56 
    d_37 -> n_70 
    n_70 -> d_119 
    d_39 -> n_73 
    d_41 -> n_73 
    d_119 -> n_73 
    n_73 -> d_141 
    n_73 -> d_40 
    d_17 -> n_76 
    n_76 -> d_146 
    d_141 -> n_76 
    d_136 -> n_76 
    d_60 -> n_79 
    d_146 -> n_79 
    
    
    }
    
    digraph dual_capture_graph {
    
    d_113 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_171|bufs 4|pipe 0|in_nodes 1|desc 113 }"]
    d_115 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_171|bufs 4|pipe 1|in_nodes 1|desc 115 }"]
    d_117 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_171|bufs 4|pipe 2|in_nodes 1|desc 117 }"]
    d_119 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_171|bufs 4|pipe 3|in_nodes 1|desc 119 }"]
    dq_cmd_114 [shape=record, label="{response cmd|desc 113}", style=filled]
    d_113 -> dq_cmd_114
    
    d_113 -> queue_122 [label="release"]
    
    queue_121 -> d_113 [label="acquire"]
    
    dq_cmd_116 [shape=record, label="{response cmd|desc 115}", style=filled]
    d_115 -> dq_cmd_116
    
    d_115 -> queue_122 [label="release"]
    
    queue_121 -> d_115 [label="acquire"]
    
    dq_cmd_118 [shape=record, label="{response cmd|desc 117}", style=filled]
    d_117 -> dq_cmd_118
    
    d_117 -> queue_122 [label="release"]
    
    queue_121 -> d_117 [label="acquire"]
    
    dq_cmd_120 [shape=record, label="{response cmd|desc 119}", style=filled]
    d_119 -> dq_cmd_120
    
    d_119 -> queue_122 [label="release"]
    
    queue_121 -> d_119 [label="acquire"]
    
    queue_122 -> dequeue_0 [label="done"]
    
    enqueue_0 -> queue_121 [label="ready"]
    
    d_123 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_172|bufs 4|pipe 0|in_nodes 1|desc 123 }"]
    d_125 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_172|bufs 4|pipe 1|in_nodes 1|desc 125 }"]
    d_127 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_172|bufs 4|pipe 2|in_nodes 1|desc 127 }"]
    d_129 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_172|bufs 4|pipe 3|in_nodes 1|desc 129 }"]
    dq_cmd_124 [shape=record, label="{response cmd|desc 123}", style=filled]
    d_123 -> dq_cmd_124
    
    d_123 -> queue_132 [label="release"]
    
    queue_131 -> d_123 [label="acquire"]
    
    dq_cmd_126 [shape=record, label="{response cmd|desc 125}", style=filled]
    d_125 -> dq_cmd_126
    
    d_125 -> queue_132 [label="release"]
    
    queue_131 -> d_125 [label="acquire"]
    
    dq_cmd_128 [shape=record, label="{response cmd|desc 127}", style=filled]
    d_127 -> dq_cmd_128
    
    d_127 -> queue_132 [label="release"]
    
    queue_131 -> d_127 [label="acquire"]
    
    dq_cmd_130 [shape=record, label="{response cmd|desc 129}", style=filled]
    d_129 -> dq_cmd_130
    
    d_129 -> queue_132 [label="release"]
    
    queue_131 -> d_129 [label="acquire"]
    
    queue_132 -> dequeue_1 [label="done"]
    
    enqueue_1 -> queue_131 [label="ready"]
    
    d_133 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_173|bufs 4|pipe 0|in_nodes 1|desc 133 }"]
    d_134 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_173|bufs 4|pipe 1|in_nodes 1|desc 134 }"]
    d_135 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_173|bufs 4|pipe 2|in_nodes 1|desc 135 }"]
    d_136 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_173|bufs 4|pipe 3|in_nodes 1|desc 136 }"]
    d_133 -> queue_137 [label="release"]
    
    queue_137 -> d_133 [label="acquire"]
    
    d_134 -> queue_137 [label="release"]
    
    queue_137 -> d_134 [label="acquire"]
    
    d_135 -> queue_137 [label="release"]
    
    queue_137 -> d_135 [label="acquire"]
    
    d_136 -> queue_137 [label="release"]
    
    queue_137 -> d_136 [label="acquire"]
    
    d_25 [shape=record , label="{mosaic_in(1)    | desc 25}"]
    d_25 -> queue_137
    
    d_80 [shape=record , label="{image_162   | size 12585984 | desc 80}"]
    d_80 -> queue_137
    
    d_81 [shape=record , label="{image_163   | size 12585984 | desc 81}"]
    d_81 -> queue_137
    
    d_82 [shape=record , label="{image_164   | size 12585984 | desc 82}"]
    d_82 -> queue_137
    
    d_138 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_174|bufs 4|pipe 0|in_nodes 1|desc 138 }"]
    d_139 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_174|bufs 4|pipe 1|in_nodes 1|desc 139 }"]
    d_140 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_174|bufs 4|pipe 2|in_nodes 1|desc 140 }"]
    d_141 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_174|bufs 4|pipe 3|in_nodes 1|desc 141 }"]
    d_138 -> queue_142 [label="release"]
    
    queue_142 -> d_138 [label="acquire"]
    
    d_139 -> queue_142 [label="release"]
    
    queue_142 -> d_139 [label="acquire"]
    
    d_140 -> queue_142 [label="release"]
    
    queue_142 -> d_140 [label="acquire"]
    
    d_141 -> queue_142 [label="release"]
    
    queue_142 -> d_141 [label="acquire"]
    
    d_23 [shape=record , label="{display_params(0)    | desc 23}"]
    d_23 -> queue_142
    
    d_83 [shape=record , label="{image_165   | size 12585984 | desc 83}"]
    d_83 -> queue_142
    
    d_84 [shape=record , label="{image_166   | size 12585984 | desc 84}"]
    d_84 -> queue_142
    
    d_85 [shape=record , label="{image_167   | size 12585984 | desc 85}"]
    d_85 -> queue_142
    
    d_143 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_175|bufs 4|pipe 0|in_nodes 1|desc 143 }"]
    d_144 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_175|bufs 4|pipe 1|in_nodes 1|desc 144 }"]
    d_145 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_175|bufs 4|pipe 2|in_nodes 1|desc 145 }"]
    d_146 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_175|bufs 4|pipe 3|in_nodes 1|desc 146 }"]
    d_143 -> queue_147 [label="release"]
    
    queue_147 -> d_143 [label="acquire"]
    
    d_144 -> queue_147 [label="release"]
    
    queue_147 -> d_144 [label="acquire"]
    
    d_145 -> queue_147 [label="release"]
    
    queue_147 -> d_145 [label="acquire"]
    
    d_146 -> queue_147 [label="release"]
    
    queue_147 -> d_146 [label="acquire"]
    
    d_18 [shape=record , label="{mosaic_img_out   | size 3110400 | desc 18}"]
    d_18 -> queue_147
    
    d_86 [shape=record , label="{image_168   | size 3110400 | desc 86}"]
    d_86 -> queue_147
    
    d_87 [shape=record , label="{image_169   | size 3110400 | desc 87}"]
    d_87 -> queue_147
    
    d_88 [shape=record , label="{image_170   | size 3110400 | desc 88}"]
    d_88 -> queue_147
    
    
    }
    
    digraph dual_capture_graph {
    
      ColorScheme [shape=none, margin=0, label=<
    
            <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
    
            <TR><TD bgcolor="brown">CAPTURE2</TD></TR>
            <TR><TD bgcolor="blanchedalmond">VPAC_VISS1</TD></TR>
            <TR><TD bgcolor="antiquewhite">VPAC_MSC1</TD></TR>
            <TR><TD bgcolor="burlywood">DISPLAY1</TD></TR>
            </TABLE>>];
    
    
    
    /* List of nodes ( Pipeline = 0 )*/
    n_54 [shape=record, label="{capture_node(1)|pipe 0|desc 54}", style=filled, fillcolor=brown]
    n_58 [shape=record, label="{viss_node(1)|pipe 0|desc 58}", style=filled, fillcolor=blanchedalmond]
    n_38 [shape=record, label="{capture_node(0)|pipe 0|desc 38}", style=filled, fillcolor=brown]
    n_42 [shape=record, label="{viss_node(0)|pipe 0|desc 42}", style=filled, fillcolor=blanchedalmond]
    n_59 [shape=record, label="{mosaic_node|pipe 0|desc 59}", style=filled, fillcolor=antiquewhite]
    n_61 [shape=record, label="{display_node(0)|pipe 0|desc 61}", style=filled, fillcolor=burlywood]
    
    /* Dependency of nodes within pipeline (Pipeline = 0) */
    n_54 -> n_58 [style=dashed]
    n_54 -> n_58 [style=dashed, color=gray]
    n_58 -> n_59 [style=dashed]
    n_38 -> n_42 [style=dashed]
    n_38 -> n_42 [style=dashed, color=gray]
    n_42 -> n_59 [style=dashed]
    n_42 -> n_59 [style=dashed, color=gray]
    n_58 -> n_59 [style=dashed, color=gray]
    n_59 -> n_61 [style=dashed]
    n_59 -> n_61 [style=dashed, color=gray]
    
    /* List of data reference queues */
    d_113 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_171|bufs 4|pipe 0|in_nodes 1|desc 113 }"]
    d_123 [shape=record, style=filled , fillcolor=yellow, label="{data_ref_q_172|bufs 4|pipe 0|in_nodes 1|desc 123 }"]
    
    d_133 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_173|bufs 4|pipe 0|in_nodes 1|desc 133 }"]
    d_138 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_174|bufs 4|pipe 0|in_nodes 1|desc 138 }"]
    d_143 [shape=record, style=filled , fillcolor=lightgrey, label="{data_ref_q_175|bufs 4|pipe 0|in_nodes 1|desc 143 }"]
    
    
    /* Dependency of nodes within pipeline (Pipeline = 0) */
    d_53 -> n_54 
    n_54 -> d_123 
    d_55 -> n_58 
    d_57 -> n_58 
    d_123 -> n_58 
    n_58 -> d_133 
    n_58 -> d_56 
    d_37 -> n_38 
    n_38 -> d_113 
    d_39 -> n_42 
    d_41 -> n_42 
    d_113 -> n_42 
    n_42 -> d_138 
    n_42 -> d_40 
    d_17 -> n_59 
    n_59 -> d_143 
    d_138 -> n_59 
    d_133 -> n_59 
    d_60 -> n_61 
    d_143 -> n_61 
    
    
    }
    

  • Hi Stuart,

    Sorry for the late reply, because of festival holidays last week.

    I'm creating two CSIRX nodes - so I believe I end up with 2 csirx contexts.

    Okay, should be fine I was confused with openvx context.

    If you can show me how I might accomplish this I can rework my usecase :)

    You can use same csirx node for both virtual channels, and configure different dcc configs for each viss nodes (replicated), direct examples are not there,

    you can refer to multicam_demo for using single csirx to capture 2 channels of data, 

    for viss_node create you have to do some changes,

    since the viss_node is replicated for 2 channels coming from csirx you have to create an object_array for both parameter 0 and 2 ( configuration and dcc_buf)

    each element of the object_array corresponds to the camera channel and populate the data accordingly.

    and make the replicate flag to be true for both 0 and 2nd parameter 

    Coming back to the graph output you shared, buffers from viss node to mosaic node is not created properly,

    the output of viss_node is an image and input for mosaic node is an object_array, here in your graph only one buffer is created properly and the other 3 buffers are not.

    set the replicate flag for the viss_output_arr, this will create the buffers properly.

    I hope you are updating obj-<mosaicObj.num_inputs = 2;  in your code 

    can you share the snippet of viss_node creation part and the buffers creation part for viss_output_arr

    Regards,
    Gokul

  • Gokul - thank you for your reply.  I have a lot of questions.

    It does look like using replicate will fix my issues - but I'd appreciate if you answer my questions so I can learn what's going on.

    0: Yes, I'm using mosaicObj.num_inputs = 2.  I've refactored the code a fair bit, see #4

    1: How do I get a visual output of the dot graph?  That looks really handy.  :)

    2: What is replicating doing in this example?

    Inside of multi-cam, it connects the output of the VISS node by using "vxGetObjectArrayItem" and pulling out the first image in the array.  Then it uses that same array reference to pass the input to the mosaic node. 

    It looks like what's happening is that by duplicating the VISS node, it's able to write to subsequent indices inside of that object array output, which can then seamlessly be passed into the mosaicing node.

    How come I can't reproduce the same behavior by just using vxGetObjectArrayItem() for both VISS nodes?

    3: If I replicate, I may need different VISS DCC buffers, but most importantly, I'd need different AEWB behavior.

    Ideally, I want AEWB on context 0, and only AWB on context 1.  I assume I can do this the same way via replication.

    4: I refactored a lot of code.  VISS code looks like app single cam mostly.  See details below

    Mosaic configuration :

    #if DC_MOSAIC
    static void app_configure_mosiac_node(AppObj *obj)
    {
        ImgMosaicObj *imgMosaicObj = &obj->imgMosaicObj;
        // I don't know why they do it this way.  It's weird.  Input width should be 3856x2176
        vx_uint16 in_width = obj->usecase_configs[0].pipe_params.msc.output_width;
        vx_uint16 in_height = obj->usecase_configs[0].pipe_params.msc.output_height;
        printf("in width : %d in height: %d\n", in_width, in_height);
    
        vx_int32 idx, ch;
        vx_int32 grid_size = 2;
    
        imgMosaicObj->out_width    = DISPLAY_WIDTH;
        imgMosaicObj->out_height   = DISPLAY_HEIGHT;
    
        // Set to 1 for single array input
        imgMosaicObj->num_inputs   = 2;
    
        idx = 0;
    
        tivxImgMosaicParamsSetDefaults(&imgMosaicObj->params);
    
        for(ch = 0; ch < UC_NUM_PIPELINES; ch++)
        {
            vx_int32 winX = ch%grid_size;
            vx_int32 winY = ch/grid_size;
    
            imgMosaicObj->params.windows[idx].startX  = (winX * (in_width/grid_size));
            imgMosaicObj->params.windows[idx].startY  = (winY * (in_height/grid_size));
            imgMosaicObj->params.windows[idx].width   = in_width/grid_size;
            imgMosaicObj->params.windows[idx].height  = in_height/grid_size;
    
            imgMosaicObj->params.windows[idx].input_select   = ch;
            imgMosaicObj->params.windows[idx].channel_select = 0;
            idx++;
        }
    
        imgMosaicObj->params.num_windows  = idx;
    
        /* Number of time to clear the output buffer before it gets reused */
        imgMosaicObj->params.clear_count  = NUM_BUFS;
    }
    #endif

    Configuration of mosaic input array / VISS output (I set DC_MOSAIC to 1 when I want it to turn on the mosaic node stuff)

    #define DC_MOSAIC 0
    #if DC_MOSAIC
        // Remove LDC and MSC from params
        obj->usecase_configs[0].pipe_params.aewb.en = false;
        obj->usecase_configs[0].pipe_params.ldc.en = false;
        obj->usecase_configs[0].pipe_params.msc.en = false;
    
        obj->usecase_configs[1].pipe_params.aewb.en = false;
        obj->usecase_configs[1].pipe_params.ldc.en = false;
        obj->usecase_configs[1].pipe_params.msc.en = false;
    
        // Create mosaic array object
        vx_uint32 img_width  = obj->usecase_configs[0].sensor_params.sensorInfo.raw_params.width;
        vx_uint32 img_height = obj->usecase_configs[0].sensor_params.sensorInfo.raw_params.height;
        vx_image output_img = vxCreateImage(obj->context, img_width, img_height, VX_DF_IMAGE_NV12);
    
        status = vxGetStatus((vx_reference)output_img);
        if(status != VX_SUCCESS) {
            printf("Failed to allocate mosaic array image object\n");
            return status;
        }
    
        obj->imgMosaicObj.input_arr[0] = vxCreateObjectArray(obj->context, (vx_reference)output_img, 1);
        obj->imgMosaicObj.input_arr[1] = vxCreateObjectArray(obj->context, (vx_reference)output_img, 1);
        vxSetReferenceName((vx_reference)obj->imgMosaicObj.input_arr[0], "mosaic_in(0)");
        vxSetReferenceName((vx_reference)obj->imgMosaicObj.input_arr[1], "mosaic_in(1)");
    
        vxReleaseImage(&output_img);
    
        status = vxGetStatus((vx_reference)obj->imgMosaicObj.input_arr[0]);
        if(status != VX_SUCCESS) {
            printf("[VISS-MODULE] Unable to create Mosaic input array! \n");
            return status;
        }
    
        // Assign mosaic input images to output of viss nodes
        obj->pipes[0]->viss_obj.y8_r8_c2 =  (vx_image)vxGetObjectArrayItem(obj->imgMosaicObj.input_arr[0], 0);
        obj->pipes[1]->viss_obj.y8_r8_c2 =  (vx_image)vxGetObjectArrayItem(obj->imgMosaicObj.input_arr[1], 0);
    #endif

    Below, if the image output buffer for VISS named 'y8_r8_c2' is populated, it will not create the image buffer, but instead just use it as is:

    VISS node creation.

    vx_status app_create_viss(vx_context ctx, vx_graph graph, tivx_raw_image raw_in, const dc_viss_params *params, dc_viss_obj *obj)
    {
        if(params->en == false) {
            printf("%s[%d] disabled - skipping\n", __func__, __LINE__);
            return VX_SUCCESS;
        }
    
        vx_status status = VX_SUCCESS;
        vx_uint32 sensor_dcc_enabled = 1;
    
        const vx_char dcc_viss_user_data_object_name[] = "dcc_viss";
        uint8_t * dcc_viss_buf;
        vx_map_id dcc_viss_buf_map_id;
        vx_uint32 image_width;
        vx_uint32 image_height;
        int32_t dcc_buff_size = 0;
        int32_t dcc_buff_size_driver;
    
    #ifdef x86_64
        int32_t dcc_buff_size_fs;
    #endif
        vx_uint32 sensor_wdr_enabled = params->sensor_wdr_mode;
    
        tivxQueryRawImage(raw_in, TIVX_RAW_IMAGE_WIDTH, &image_width, sizeof(vx_uint32));
        tivxQueryRawImage(raw_in, TIVX_RAW_IMAGE_HEIGHT, &image_height, sizeof(vx_uint32));
        // printf("%s[%d] Input width: %d input height: %d\n", __func__, __LINE__, image_width, image_height);
    
        obj->num_viss_out_buf = 3;
        if (obj->y8_r8_c2 == NULL) {
            obj->y8_r8_c2 = vxCreateImage(ctx, image_width, image_height, VX_DF_IMAGE_NV12);
        }
    
        vx_uint32 out_width, out_height;
        vxQueryImage(obj->y8_r8_c2, VX_IMAGE_WIDTH, &out_width, sizeof(vx_uint32));
        vxQueryImage(obj->y8_r8_c2, VX_IMAGE_HEIGHT, &out_height, sizeof(vx_uint32));
        printf("%s[%d] out width: %d out height: %d\n", __func__, __LINE__, out_width, out_height);
    
        obj->uv8_g8_c3 = NULL;
    
        obj->y12 = NULL;
        obj->uv12_c1 = NULL;
    
    #if 0
    #ifdef VPAC3
        /* YUV8 output from dual CC for HV and MV */
        if (obj->vpac3_dual_fcp_enable == 1U)
        {
            obj->y12 = vxCreateImage(ctx, image_width, image_height, VX_DF_IMAGE_NV12);
            obj->uv12_c1 = NULL;
        }
    #endif
    #endif
        obj->s8_b8_c4 = NULL;
        obj->histogram = NULL;
    
        /* VISS Initialize parameters */
        tivx_vpac_viss_params_init(&obj->viss_params);
        // STB FIX
        obj->viss_params.sensor_dcc_id = params->dcc_id;
        printf("app_create_viss : sensor_dcc_id = %d \n", obj->viss_params.sensor_dcc_id);
        obj->viss_params.fcp[0].ee_mode = 0;
        obj->viss_params.fcp[0].mux_output0 = 0;
        obj->viss_params.fcp[0].mux_output1 = 0;
        obj->viss_params.fcp[0].mux_output2 = 4;
        obj->viss_params.fcp[0].mux_output3 = 0;
        obj->viss_params.fcp[0].mux_output4 = 3;
        obj->viss_params.h3a_in = 3;
        obj->viss_params.h3a_aewb_af_mode = 0;
        obj->viss_params.channel_id = params->virtual_channel;
        obj->viss_params.fcp[0].chroma_mode = 0;
    
    #if 0
    #if defined(VPAC3) || defined(VPAC3L)
        if(obj->cac_enable == 1U)
        {
            obj->viss_params.bypass_cac = 0;  /* CAC on */
        }
        else
        {
            obj->viss_params.bypass_cac = 1;  /* CAC off */
        }
    #endif
    
    #ifdef VPAC3
        /* turn on dual FCP, and NV12 output */
        if (obj->vpac3_dual_fcp_enable == 1U)
        {
            obj->viss_params.fcp1_config = 1; /* RAWFE --> FCP1 */
            
            /* HV pipeline 8bit YUV output on output0 and output 1 */
            obj->viss_params.fcp[0].mux_output0 = 0;
            obj->viss_params.fcp[0].mux_output1 = 0;
            obj->viss_params.fcp[0].mux_output2 = TIVX_VPAC_VISS_MUX2_NV12;
            obj->viss_params.fcp[0].mux_output3 = TIVX_VPAC_VISS_MUX2_NV12;
            obj->viss_params.fcp[0].mux_output4 = 0;
    
            /* Mapping for FCP output to select FCP1 or FCP2 for the output muxes */
            obj->viss_params.output_fcp_mapping[0] = TIVX_VPAC_VISS_MAP_FCP_OUTPUT(TIVX_VPAC_VISS_FCP1,TIVX_VPAC_VISS_FCP_OUT2);
            obj->viss_params.output_fcp_mapping[1] = TIVX_VPAC_VISS_MAP_FCP_OUTPUT(TIVX_VPAC_VISS_FCP1,TIVX_VPAC_VISS_FCP_OUT3);
            obj->viss_params.output_fcp_mapping[2] = TIVX_VPAC_VISS_MAP_FCP_OUTPUT(TIVX_VPAC_VISS_FCP0,TIVX_VPAC_VISS_FCP_OUT0);
            obj->viss_params.output_fcp_mapping[3] = TIVX_VPAC_VISS_MAP_FCP_OUTPUT(TIVX_VPAC_VISS_FCP0,TIVX_VPAC_VISS_FCP_OUT1);
            obj->viss_params.output_fcp_mapping[4] = 0;
    
            /* MV pipeline 8bit YUV output on output2 and output 3 */
            obj->viss_params.fcp[1].mux_output0 = TIVX_VPAC_VISS_MUX2_NV12;
            obj->viss_params.fcp[1].mux_output1 = TIVX_VPAC_VISS_MUX2_NV12;
            obj->viss_params.fcp[1].mux_output2 = 0;
            obj->viss_params.fcp[1].mux_output3 = 0;
            obj->viss_params.fcp[1].mux_output4 = 0;
    
            obj->viss_params.fcp[1].ee_mode = 0;
            obj->viss_params.fcp[1].chroma_mode = 0;
        }
    #endif
    #endif
        obj->viss_params.enable_ctx = 1;
        obj->viss_params.bypass_glbce = 0;
        obj->viss_params.bypass_nsf4 = 0;
        obj->configuration = vxCreateUserDataObject(ctx, "tivx_vpac_viss_params_t", sizeof(tivx_vpac_viss_params_t), &obj->viss_params);
    
        /* Create h3a_aew_af output buffer (uninitialized) */
        obj->h3a_aew_af = vxCreateUserDataObject(ctx, "tivx_h3a_data_t", sizeof(tivx_h3a_data_t), NULL);
    
        if(sensor_dcc_enabled)
        {
            dcc_buff_size_driver = appIssGetDCCSizeVISS(params->sensor_name, sensor_wdr_enabled);
            if(dcc_buff_size_driver > 0)
            {
                dcc_buff_size += dcc_buff_size_driver;
            }
            else
            {
                dcc_buff_size_driver = 0;
            }
    
    #ifdef x86_64
            dcc_buff_size_fs = obj->fs_dcc_numbytes_viss;
            if(dcc_buff_size_fs > 0)
            {
                dcc_buff_size += dcc_buff_size_fs;
            }
    #endif
    
            if(dcc_buff_size<=0)
            {
                printf("Invalid DCC size for VISS. Disabling DCC \n");
                obj->dcc_param_viss = NULL;
            }
            else
            {
                obj->dcc_param_viss = vxCreateUserDataObject(
                    ctx,
                    (const vx_char*)&dcc_viss_user_data_object_name,
                    dcc_buff_size,
                    NULL
                );
                vxMapUserDataObject(
                        obj->dcc_param_viss,
                        0,
                        dcc_buff_size,
                        &dcc_viss_buf_map_id,
                        (void **)&dcc_viss_buf,
                        VX_WRITE_ONLY,
                        VX_MEMORY_TYPE_HOST,
                        0
                    );
    
                if(dcc_buff_size_driver > 0)
                {
                    status = appIssGetDCCBuffVISS(params->sensor_name, sensor_wdr_enabled, dcc_viss_buf, dcc_buff_size_driver);
                    if(status != VX_SUCCESS)
                    {
                        printf("Couldn't get VISS DCC buffer from sensor driver \n");
                    }
                }
    
    #ifdef x86_64
    
                if(dcc_buff_size_fs> 0)
                {
                    memcpy(dcc_viss_buf+dcc_buff_size_driver, obj->fs_dcc_buf_viss, dcc_buff_size_fs);
                }
    #endif
                if(obj->dcc_param_viss)
                {
                    vxUnmapUserDataObject(obj->dcc_param_viss, dcc_viss_buf_map_id);
                }
            }
        }else
        {
            obj->dcc_param_viss = NULL;
        }
    
        obj->node_viss = tivxVpacVissNode(
                                    graph,
                                    obj->configuration,
                                    NULL,
                                    obj->dcc_param_viss,
                                    raw_in, obj->y12, NULL,
                                    obj->y8_r8_c2, NULL, NULL,
                                    obj->h3a_aew_af, NULL, NULL, NULL
                );
    
        vxSetReferenceName((vx_reference)obj->node_viss, "VISS_Processing");
    
        if(VX_SUCCESS == status)
        {
            vxSetNodeTarget(obj->node_viss, VX_TARGET_STRING, TIVX_TARGET_VPAC_VISS1);
            tivxSetNodeParameterNumBufByIndex(obj->node_viss, 6u, NUM_BUFS);
        }
        else
        {
            printf("app_create_viss failed \n");
            return -1;
        }
    
        return status;
    }
    

    Is the issue related to this "tixSetNodeParameterNumBufByIndex" function - like here:

    #if DC_MOSAIC
        // Create mosaic node here
        status = app_create_graph_img_mosaic(obj->graph, &obj->imgMosaicObj, NULL);
        vxSetReferenceName((vx_reference)obj->imgMosaicObj.output_image[0], "mosaic_img_out");
        tivxSetNodeParameterNumBufByIndex(obj->imgMosaicObj.node, 1u, NUM_BUFS);
    

    and here:

        if(VX_SUCCESS == status)
        {
            vxSetNodeTarget(obj->node_viss, VX_TARGET_STRING, TIVX_TARGET_VPAC_VISS1);
            tivxSetNodeParameterNumBufByIndex(obj->node_viss, 6u, NUM_BUFS);
        }

  • Hi Stuart,

    1: How do I get a visual output of the dot graph?  That looks really handy.  :)

    You can refer to this page https://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-jacinto7/latest/exports/docs/tiovx/docs/user_guide/JPEG_TOOL.html
    or use the online tool https://dreampuf.github.io/GraphvizOnline

    2: What is replicating doing in this example?

    There is a known issue when two nodes are connected where one node give output as image and the following node takes object array as input the buffers are not created correctly by the framework. Making it as replicated will check if the image has any parent object which is the obj_arr and hence will allocate buffers for the obj_array instead of image.

    How come I can't reproduce the same behavior by just using vxGetObjectArrayItem() for both VISS nodes?

    in multi_cam demo by default it is replicated so there it works fine, as explained earlier making it as replicated even though you have single instance of node is required to solve this issue.

    3: If I replicate, I may need different VISS DCC buffers, but most importantly, I'd need different AEWB behavior.

    Yes, making the dcc buffer as a part of object_arr you can provide different buffers to different viss_node operating on channel 0 and channel 1.

    Read more on the replicate in the docs

    Is the issue related to this "tixSetNodeParameterNumBufByIndex" function - like here:

    I don't this there is any issues in here, your graph output will tell the number of buffers created for each outputs of node this way we can verify if the api is working or not. In your graph's dot output all the outputs have buffer depth of 4, the problem is among 4 (1-obj_arr, 3-image).

    Can you try these changes with aewb node disabled and check if the pipeline is working fine.

    Regards,
    Gokul

  • Hi Gokul,

    I moved everything over to a app_multi_cam style pipeline, and it mosaicing worked fine with my dual context camera.  Thank you.

    I have a follow up question, because I'm going to run into this problem again.  Suppose I have the same situation - single sensor multiple contexts, but this time one of the contexts has a different resolution.  Will it be possible to display both of those images onto the screen as well as have graphics? Is there a 3rd display pipeline available on the TDA4VEN that works differently? Or is there a way to make mosaicing work with two images of different resolutions?

    Thank you again!

  • Hi Stuart,

    Will it be possible to display both of those images onto the screen as well as have graphics?

    There are only 2 pipelines available per instance in tda4ven so you have to use mosaic node to combine 2 images.
    Mosaic can take images with different resolutions as it internally uses MSC to downscale the image to fit within the window and the internal scaler is configured as per the input image dimensions and window dimensions .
    But you might have to split the images into two different obj_arrays and give it as two different input to mosaic node.

    Regards,
    Gokul

  • Gokul - thank you.  That is what I was trying to do originally and failed.  I think the mistake I made is that I will need 2 different arrays of obj_array, since it needs 2 dimensions of images: one from the different captures, one for the pipeline buffering.  Is this right?

    Thank you again for all your help.