PROCESSOR-SDK-J721S2: qestion about how to design vxgraph schedule when tivxDisplayNode only used in vxgraph

Part Number: PROCESSOR-SDK-J721S2

Tool/software:

Hi, TI experts

I'm making my app base on "app_single_cam" in vision_apps.

(https://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-jacinto7/latest/exports/docs/vision_apps/docs/user_guide/group_apps_basic_demos_app_single_cam.html#autotoc_md42)

I would like to divide it into two processes, the 'capture' process and the 'display' process

I think that a 'capture' process have  CSI2-RX - VISS - LDC  -(MSC) nodes, it can be designed vx pipeline schedule design same as "app_single_cam"

capture process send  updated  vx_image by pipelining to display node process,

however, the display process only has DSS (tivxDisplayNode)  nodes.

I'm beginner to use tiovx framework,  I'm not sure how to run a vxgraph that only uses tivxDisplayNode.

anyway, I tried make display process demo for unit test like this (simplified from my source)

// make vx_image
obj->source_img = tivx_utils_create_vximage_from_bmpfile(obj->context, filename, vx_false_e);


// connect display to source
obj->display_image = obj->source_img


// make display node
memset(&obj->display_params, 0, sizeof(tivx_display_params_t));
obj->display_params.opMode = TIVX_KERNEL_DISPLAY_ZERO_BUFFER_COPY_MODE;
obj->display_params.pipeId = 0;
obj->display_params.outHeight = 1080;
obj->display_params.outWidth = 1920;
obj->display_params.posX = 0;
obj->display_params.posY = 0;

obj->display_param_obj = vxCreateUserDataObject(obj->context, "tivx_display_params_t", sizeof(tivx_display_params_t), &obj->display_params);
obj->displayNode = tivxDisplayNode(obj->graph, obj->display_param_obj, obj->display_image);


// make gragh queue param
graph_parameters_queue_params_list[graph_parameter_num].graph_parameter_index = graph_parameter_num;
graph_parameters_queue_params_list[graph_parameter_num].refs_list_size = obj->num_buf;
graph_parameters_queue_params_list[graph_parameter_num].refs_list = (vx_reference*)&(obj->display_image);

tivxSetGraphPipelineDepth(obj->graph, 1);

vxSetGraphScheduleConfig(obj->graph,
                        VX_GRAPH_SCHEDULE_MODE_QUEUE_AUTO,
                        1,
                        graph_parameters_queue_params_list
                        );


// run gragh
// start enque
vxGraphParameterEnqueueReadyRef(obj->graph, 0, (vx_reference*)&(obj->display_image), 1);

// deque
vxGraphParameterDequeueDoneRef(obj->graph, 0, (vx_reference*)&test_image, 1, &num_refs_capture);
// re enque
vxGraphParameterEnqueueReadyRef(obj->graph, 0, (vx_reference*)&test_image, 1);

when this app run,

image shows correctly in monitor, but app process hanged like this.

vxSetGraphScheduleConfig done
    79.032796 s:  VX_ZONE_INFO:[ownNodeKernelValidate:256] Validating kernel com.ti.display
    79.033254 s:  VX_ZONE_INFO:[ownNodeKernelInit:563] Calling create callback for node node_89
    79.034193 s:  VX_ZONE_INFO:[ownNodeKernelInit:583] Create callback for node node_89 completed
    79.034302 s:  VX_ZONE_INFO:[ownGraphNodeKernelInit:615] kernel init for node 0, kernel com.ti.display ...
    79.034316 s:  VX_ZONE_INFO:[ownGraphNodeKernelInit:626] kernel init for node 0, kernel com.ti.display ... done !!!
    79.042260 s:  VX_ZONE_INFO:[ownDataRefQueueEnqueueReadyRef:90] Q (queue=15, ref=4)
    79.042332 s:  VX_ZONE_INFO:[ownGraphScheduleGraph:843] Scheduling Graph (graph=18, pipe=0)
    79.042349 s:  VX_ZONE_INFO:[ownNodeKernelSchedule:800] Scheduling Node (node=7, pipe=0)
enque start ... done
    79.042431 s:  VX_ZONE_INFO:[ownDataRefQueueDequeueDoneRef:166] DQ (queue=16) .. NO BUFFER
    79.042630 s:  VX_ZONE_INFO:[ownCheckGraphCompleted:751] Graph Completed (graph=18, pipe=0)
    79.042645 s:  VX_ZONE_INFO:[ownCheckGraphCompleted:779] All Graphs Completed

my question:

Like this, do I have to operate with pipeline scheduling even if I only use the display node in graph?

or is there other way to run display node?

if pipeline scheduling is needed to run graph

can i get guide to this design?

Is there a source code in SDK that I will refer to in this use case?
  • Hi,

    May I know what is the usecase of making capture and display as part of separate processes rather than 2 graphs running on separate threads in the same process?

    Do you have a plan on how to send the data across 2 processes already for this? as the graph and context are bound to a process

    Regards,

    Nikhil

  • Hi, Nikhil

    See you again, You left an answer to my othrer question about multi processes communication.

    Thank you for showing interest.

    Nikhil said

    May I know what is the usecase of making capture and display as part of separate processes rather than 2 graphs running on separate threads in the same process?

    Our target system has serveral use case, but i don't want to make seperated app base on each use case.

    I want to divide it into basic processes and use them in combination.

    for example, capture process, DL process, network process, etc...

    The reason for dividing the processes is that each process is implemented by different teams.

    Therefore, only the communication interfaces between the processes will be standardized, while the rest will be developed by each respective team.

    I am using the "single camera demo" to build the basic process communication structure.

    Actually, video output processor is for simple validation purposes and will be removed in the final hardware.

    We have always built applications this way on other hardware.

    I naturally believe that it will also be implemented in tiovx framework.

    Nikhil said

    Do you have a plan on how to send the data across 2 processes already for this? as the graph and context are bound to a process

    yes, it is neccessary to share the data.

    my another question, i asked that i hope to use pub/sub middle ware for this commnunication.

    i only know that it is possible to share the file descriptor (FD) converted from vx_reference throgh shocket commnunication.

    if socket communication is the only option, i plan to use it for now.

    I hope you can provide an answer as to whether there are other methods available.

  • Understood. 

    In this case, then you would be having different graphs in different processes. If it is going to be a single node graph, then there is no point of pipelining. You can execute the display graph (if there is only one display node in it) once the buffer is available.

    I have responded to the other thread regarding the process communication

    Regards,

    nikhil

  • Hi Nikhil

    Thank you again for answer.

    I'm sorry, but I'd like to ask you one more question.

    I made a unit process and tested it as follows.


    image file read process (A)  -  video out process (B)

    test case 1) : success

    A process
    - open one file & makes vx_image type.
    - send vx_image to (B)

    B process
    - receive vx_image form (A)

    static vx_status app_read_msg_to_conv_img(AppObj *obj)
    {
     // Simplyfication code
     tivxMemTranslateFd(fd64, size, &ptrs, &phyAddr);
     vx_image img = vxCreateImage(obj->context,widh,height,format);
     vx_reference ref = (vx_reference)img;
     tivxReferenceImportHandle(ref, &ptrs, &size, 1);
    
     // display input link to received reference
     obj->display_image = (vx_image)ref;
    }

    - make graph & tivxDisplayNode with received vx_image

    obj->displayNode = tivxDisplayNode(obj->graph, obj->display_param_obj, obj->display_image);

    - run with  vxProcessGraph() API

    while(1) {
     vxProcessGraph(obj->graph);
     if(obj->stop_task)
            break;
    }

    test case  2) : fail

    A process
    - open 10 files & makes vx_image type.
    - send vx_images sequentially at one second intervals

    B process
    - receive 1st vx_image form (A)
    - make graph & tivxDisplayNode with received 1st vx_image
    - run with  vxProcessGraph() API
    - receive next vx_image & update display input image (just repeat call 1st function)

    while(1) {
     vxProcessGraph(obj->graph);
     if(obj->stop_task)
            break;
     app_read_msg_to_conv_img(obj); // just call again
    }

    in test case2, 1st image was shown but next image was not updated.
    (receiving FD  and converting vx_image was successful)

    In my think, I should need to use pipelining to update the input data.

    Or is there a way to update the input data with pipelining?

  • Hi,

    Instead of creating an image everytime using the below command, 

    vx_image img = vxCreateImage(obj->context,widh,height,format);

    can you use the same ref and update only the ptrs to this reference and then call process graph?

    Because, when you are creating a node, the display image would have used a ref that you created and it expects the same ref.

    Regards,

    Nikhil

  • Hi, Nikhil

    I followed your advice and it was succeeded.

    Thank you for your help!