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.

Run two encode codecs from the same application

Hello all,

I am working on DM6446 building codec run remotely on the DSP using codec engine framework.

I am working using the videnc_copy example with the arm application in the examples to run the videnc_copy codec (runs remotely on dsp) using video thread that calls the encoder

I want to use two videnc_copy codecs each one runs through a thread.

i made a copy for videnc_copy codec and build it successfully,  then added the two codecs (the original and the copy) to the codec.cfg for the server successfully.

My problem is from the ARM application how to distinguish between the two codecs, how to invoke each one separately.

Regards 

  • Mostafa,

    It's not clear if you want to run two different codecs on the DSP or two instances of the same codec. If you do want two different codecs, then you would create an engine with two different codecs and give each one a different name. Later, you could create an instance of each by specifying the respective codec name. If you just want two instances of the same codec, then you simply call create twice giving the same name each time.

    For example, use Engine_open to get an Engine_Handle to the server running on the DSP.

    ce = Engine_open(engineName, NULL, NULL);

    Then use this handle along with the encoder name in a call to VIDENC_create to create an instance of the encoder on the DSP. Call create twice with the same encoder name to create two instances of the same encoder.

    enc1 = VIDENC_create(ce, "EncodeAlpha", NULL);
    enc2 = VIDENC_create(ce, "EncodeAlpha", NULL);

    Or use two different encoder names to create one instance of each type.

    enc1 = VIDENC_create(ce, "EncodeAlpha", NULL);
    enc2 = VIDENC_create(ce, "EncodeBeta", NULL);

    Now use the respective encoder handles in your VIDENC_process calls to schedule work to the respective codec instances running on the DSP.

    Note that each codec instance will be running in its own task on the DSP. The task is created when the application calls VIDENC_create.

    Here are some helpful links, in case you have not already found them. There are additional links at the bottom of each page.

    Codec Engine Overview
    Codec Engine Server Integration User Guide

    ~Ramsey

  • Hello Ramsey,
    Thanks a lot for replying,
    I am using two different encoder like your second example, then should I name the codecs in the codec.cfg file in the server to "EncodeAlpha" and "EncodeBeta" so that the app can distinguish them? am I getting this right?
    another thing i want to run each codec in a single thread and i want to make the first one writes its output to a buffer that will be the input for the second codec in the second thread. how can i manage this shared buffer? and where to create it to be available for both threads.
    Regards
  • Mostafa,

    Yes, I think you understand. You would name your two codecs in the DSP's codec.cfg file when defining your algorithms. Something like the following:

    Server = xdc.useModule('ti.sdo.ce.Server');

    Server.algs = [
        { name: "EncodeAlpha", ..., threadAttrs: { stackSize: 0x1000, priority: 5 } },
        { name: "EncodeBeta",  ..., threadAttrs: { stackSize:  0xC00, priority: 5 } }
    ];

    Each codec instance will have its own task (task = thread on DSP). This happens when you call VIDENC_create. You can specify properties such as stack size and task priority when defining your algorithm array.

    Unfortunately, Codec Engine does not support "chaining" on the server side. Fundamentally, it is a frame based process model. But you can achieve your goal by passing the output buffer of your first process call as the input buffer of the second process call. You would do this on the ARM side. So, for each input frame, you will make two process calls. Depending on the details of your codec, you might need to modify some of the buffer descriptor properties when passing the output of the first process call as the input of the second process call.

    while (frame = getNextFrame()) {
        inBufDesc1 = ...; /* take values as needed from frame */
        inArgs1 = ...;
        VIDENC_process(enc1, &inBufDesc1, &outBufDesc1, &inArgs1, &outArgs1);

        inBufDesc2 = ...; /* take values as needed from outBufDesc1 */
        inArgs2 = ...;    /* take values as needed from outArgs1 */
        VIDENC_process(enc2, &inBufDesc2, &outBufDesc2, &inArgs2, &outArgs2);
    }

    This approach will achieve a simple "chaining" of data. However, the ARM application will block in the call to VIDENC_procsss while the DSP is processing the data. If you have other useful work which can be done on the ARM while the DSP is processing the data, you might consider using the non-blocking process call: VIDENC_processAsync. This is a more advanced usage. I would only use this approach if needed.

    ~Ramsey

  • Hello Ramsey,
    Thanks again for your great help,
    one more thing, suppose the two encoders (Alpha and Beta) run each on a single thread. One thread for calling VIDENC_process for Alpha encoder and the second thread dealing with Beta encoder. So how to make the output buffer for the first encoder available for the second encoder (taking in consideration each one runs in a thread) . If possible to share a buffer this way how to do this?.
    Also, should some synchronization technique used to block the second encoder from reading from the buffer until the first encoder writes to it ?.
    Best regards.
  • Mostafa,

    Are you saying that on the ARM side, you have two threads?

    The typical setup is to use one thread on the ARM side to invoke both VIDENC_process calls as detailed above. On the DSP side, the respective codecs will each run in their own task. Back on the ARM side, the first call to VIDENC_process will block until the DSP side is finished. On the ARM side, when the first call to VIDENC_process returns, you know that the DSP side work has completed and your output buffer contains the results. You can then pass that output buffer to the next VIDENC_process call.

    Is there some special reason you need to have two threads running on the ARM side? If so, then you will need to use some native Linux synchronizing techniques. A semaphore is a typical object used for this. There are many sources for writing multithreaded Linux applications.

    But keep in mind, if you are trying to pipeline your two codecs with the hope of having each codec running in parallel, they will still be serialized on the DSP side. The DSP is a single processor which can run only one task at a time. You might get some benefit if your codec is blocked on I/O (in which case the other codec would get a chance to run), but a better approach would be to use the non-blocking VIDENC_processAsync call instead of using two threads on the ARM.

    ~Ramsey

  • Hello Ramsey
    Yes i want two run two threads on ARM each one process a codec.
    My original codec is a sequential algorithm (i.e. every module in the algorithm must wait the result of its previous module and so on ..) so i was thinking to try dividing this algorithm into two blocks or modules and run each one through a codec runs by a thread in ARM. I know that the second codec must wait the result of the first one but meanwhile the first codec will process the next frame. Do you think this technique will speed up my processing cause i need to enhance execution time of the algorithm. I am also wondering really how the h264 encoder and decoder run in real time producing 30 fps taking in consideration that i am working with the vicp too.
    Regards
  • Mostafa,

    I don't think that having two threads on the ARM will improve you overall performance by much (maybe just a little depending on I/O blocking on the DSP). Keep in mind that each VIDENC_process call on the ARM will result in a task running on the DSP. For example, when your second thread on the ARM calls VIDENC_process, it will block and wait for the DSP to complete its work. At this point, your first thread on the ARM will get a chance to run. You are hoping that the first thread will start processing on the next frame while the second thread is waiting for the DSP to finish.

    If you first thread is doing local work on the ARM, then yes, you will get a benefit. However, if your first thread simply calls VIDENC_process for the next frame, that will result in a message sent to the DSP to process the next frame. However, the DSP will still be working on the VIDENC_process call from your second ARM thread, so first ARM thread will also be blocked until the DSP finishes working on the VIDENC_process call from the second ARM thread.

    I work on the IPC team. For specific codec questions, try the Multimedia Software Codecs forum.

    ~Ramsey

  • Ramsey,
    Thanks a lot for being so helpful
    OK I understand now that every VIDENC_process call from the ARM thread to the DSP will block untill the other processing on the DSP finishes.
    So, can i make remote codecs with local codecs from the same application. I can configure the codecs as you know from the codec.cfg file and they are consumed by the DSP server and available for the ARM application. If this is available, how to add a local codecs that run with remote ones?
    And how to manage the priority for each codec in this case if i have two codecs run on DSP and one codec runs on ARM as i want to minimize the blocking time for each one as possible.
    Regards
  • Mostafa,

    I would guess that you can create a second Codec Engine for the ARM and call Engine_open on it. This would give you a new handle for invoking codecs in your ARM based engine. But this would be part of your ARM application. It would have nothing to do with your DSP configuration.

    There is no scheduling coordination between the ARM and DSP processors. When talking about task priorities for the DSP, it affects only the tasks running on the DSP, not the ARM. Similar situation for ARM side threads. However, keep in mind that the SYS/BIOS scheduler is a real-time priority based scheduler and the Linux scheduler is a time-sliced based scheduler. They behave quite differently.

    Our Codec Engine expert is on holiday. I would suggest starting a new thread in January regarding specific Codec Engine questions.

    ~Ramsey