Esempio n. 1
0
/**
 * Updates program clock reference time.
 *
 * @param arg
 */
void pcr_update_thread(
    void * arg
    )
{
    sSX_DESC   *desc;
    UINT64      pcr_time;
    UINT64      pcr_received_time;
    UINT64      curr_time;


    while(1)
    {
        desc = sx_pipe_get(SX_VRDMA_PCR);
        if(desc == NULL)
        {
            goto cleanup;
        }

        sSLICE_HDR *hdr = (sSLICE_HDR *) desc->data;

        // Update PCR time.
        pcr_time = hdr->timestamp;

        // Free descriptor.
        sx_desc_put(desc);

        // Cache received time.
        pcr_received_time = sink_time_get();

        cleanup:

        // Get current time.
        curr_time = sink_time_get();

        pthread_mutex_lock(&f_cblk.lock);

        f_cblk.curr_time = pcr_time + (curr_time - pcr_received_time) - SX_SYSTEM_AUDIO_SOURCE_DELAY_MS - SX_SYSTEM_DELAY_MS;

        pthread_mutex_unlock(&f_cblk.lock);

        usleep(2*1000);
    }
}
Esempio n. 2
0
/**
 * Slice packing thread.
 *
 * @param arg
 */
void slice_packing_thread(
    void * arg
    )
{
    sSX_DESC   *desc;


    desc = NULL;
    while(1)
    {
        UINT32 len = sx_pipe_len_get(SX_VRDMA_SLICE_READY);
        if(len >= 10)
        {
            // More than enough. Try again next iteration.
            goto next_iter;
        }

        UINT32  slices_to_dump = 10 - len;
        do
        {
            desc = sx_pipe_get(SX_VRDMA_SLICE);
            if(desc == NULL)
            {
                goto next_iter;
            }

            // Dump slice.
            video_scheduler_slice_dump(desc);

            slices_to_dump--;

        } while (slices_to_dump > 0);

        next_iter:

        usleep(2*1000);
    }
}
Esempio n. 3
0
// --------------------------------------------------------
// decoder_thread
//      Decoder thread
//
//  Description:
//      This function defines the decoder thread.
//
void video_scheduler_thread(
    void * arg
    )
{
    sSX_DESC   *desc;
    UINT64      slice_present_time;


    desc = NULL;
    while(1)
    {
        while(1)
        {
            // -------------------
            // Get slice.
            // -------------------

            // Get slice.
            if(desc == NULL)
            {
                desc = sx_pipe_get(SX_VRDMA_SLICE_READY);
                if(desc == NULL)
                {
                    goto next_iter;
                }

                sSLICE_HDR *hdr = (sSLICE_HDR *) desc->data;

                // Get PTS.
                slice_present_time = ((sSLICE_HDR *) desc->data)->timestamp;
            }

            UINT64  estimated_source_time = estimated_source_time_get();
            UINT8 present = (estimated_source_time > slice_present_time) ? 1 : 0;

            if(!present)
            {
                goto next_iter;
            }

            // -------------------
            // Present slice.
            // -------------------

            sSX_DESC *curr = desc->next;
            sSX_DESC *next;
            do
            {
                sx_video_sink_buf_set((sDECODER_HW_BUFFER *) curr->data);

                next = curr->next;

                free(curr);

                curr = next;

            } while (curr != NULL);

            free(desc->data);
            free(desc);

            // Set descriptor pointer to NULL.
            desc = NULL;
        }

        next_iter:

        usleep(1*1000);
    }
}
Esempio n. 4
0
// --------------------------------------------------------
// decoder_thread
//      Decoder thread
//
//  Description:
//      This function defines the decoder thread.
//
void audio_scheduler_thread(
    void * arg
    )
{
    sSX_DESC   *desc;


    while(1)
    {
        if(f_cblk.state == STATE_INACTIVE)
        {
            UINT32 len = sx_pipe_len_get(SX_VRDMA_LPCM_SLICE);
            if(len > (SX_SYSTEM_DELAY_MS / 10))
            {
                f_cblk.state = STATE_ACTIVE;

                printf("(audio_scheduler): Transition to active. [len = %u]\n", len);

                goto next_iter;
            }
        }
        else
        {
            UINT32  data_left_ms = sx_pipe_len_get(SX_VRDMA_LPCM_SLICE) * 10;
            UINT32  queued_ms = sx_audio_sink_ms_left_get();

            if((data_left_ms + queued_ms) == 0)
            {
                f_cblk.state = STATE_INACTIVE;

                printf("(audio_scheduler): Transition to inactive.\n");

                goto next_iter;
            }

            if(queued_ms < 200)
            {
                UINT32  slices_to_queue = (200 - queued_ms + 10) / 10;
                do
                {
                    // Get slice.
                    desc = sx_pipe_get(SX_VRDMA_LPCM_SLICE);
                    if(desc == NULL)
                    {
                        goto next_iter;
                    }

                    // Dump slice.
                    audio_scheduler_slice_dump(desc);

                    slices_to_queue--;

                } while(slices_to_queue > 0);
            }
        }

        next_iter:

        usleep(5*1000);
    }
}