コード例 #1
0
ファイル: sx_mgmt_video_decoder.c プロジェクト: fsmp/piracast
/**
 * Drops a given slice.
 */
static void slice_drop(
    void
    )
{
    sSX_DESC  *curr;
    sSX_DESC  *next;


    // Drop slice.
    sx_desc_put(f_cblk.slice_chain.head);

    // Reset head and tail.
    f_cblk.slice_chain.head = NULL;
    f_cblk.slice_chain.tail = NULL;

    printf("slice_dropped() invoked\n");
}
コード例 #2
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);
    }
}
コード例 #3
0
static void video_scheduler_slice_dump(
    sSX_DESC   *slice_head
    )
{
    UINT8      *curr_ptr;
    UINT32      bytes_left;
    UINT32      afc;
    UINT32      pes_byte_count;
    UINT32      payload_size;
    UINT32      start_offset;
    UINT32      copy_index;
    UINT32      pid;
    sSX_DESC   *curr_desc;
    sSX_DESC   *head_desc;


    // Consistency check.
    assert(slice_head);

    // Get descriptor.
    sSX_DESC *hw_desc = sx_desc_get();

    // Set this as another chain.
    sSX_DESC *hw_desc_head = hw_desc;

    // Get a hw buffer.
    sDECODER_HW_BUFFER * hw_buf = sx_video_sink_buf_get();
    assert(hw_buf != NULL);

    // Set payload.
    hw_desc->data = (UINT8 *) hw_buf;

    // Get first descriptor.
    //
    // First descriptor holds the timestamp and will be skipped.
    curr_desc = slice_head;

    copy_index = 0;
    do
    {
        // Get next.
        curr_desc = curr_desc->next;

        // Get current.
        curr_ptr = curr_desc->data;

        // Get data left.
        bytes_left = curr_desc->data_len;
        assert(bytes_left > sizeof(sRTP_HDR));

        // Get RTP header.
        // sRTP_HDR *rtp_hdr = (sRTP_HDR *) curr_ptr;

        // Get TS header.
        curr_ptr += sizeof(sRTP_HDR);

        // Get TS bytes left.
        bytes_left -= sizeof(sRTP_HDR);
        assert((bytes_left % sizeof(sMPEG2_TS)) == 0);

        pes_byte_count = 0;
        do
        {
            sMPEG2_TS *ts = (sMPEG2_TS *) curr_ptr;
            afc = AFC_GET(ts->hdr);
            pid = PID_GET(ts->hdr);

            if(pid == 0x1011)
            {
                if(PUSI_GET(ts->hdr))
                {
                    assert(afc == 0x01);

                    start_offset = 14;

                    payload_size = (sizeof(sMPEG2_TS_PAYLOAD) - 14);
                }
                else
                {
                    if(afc == 0x01)
                    {
                        start_offset = 0;

                        payload_size = sizeof(sMPEG2_TS_PAYLOAD);
                    }
                    else if(afc == 0x03)
                    {
                        start_offset = 1 + ts->payload.payload[0];

                        payload_size = sizeof(sMPEG2_TS_PAYLOAD) - 1 - ts->payload.payload[0];
                    }
                    else
                    {
                        assert(0);
                    }
                }

                if((copy_index + payload_size) > 81920)
                {
                    // If the hw buffer is full, just submit the current buffer.
                    hw_buf->buffer_len = copy_index;

                    // Get a new descriptor.
                    hw_desc->next = sx_desc_get();

                    // Point to the new descriptor.
                    hw_desc = hw_desc->next;

                    // Get a new buffer.
                    hw_buf = sx_video_sink_buf_get();
                    assert(hw_buf != NULL);

                    // Set new payload.
                    hw_desc->data = (UINT8 *) hw_buf;

                    // Reset index.
                    copy_index = 0;
                }

                memcpy(&hw_buf->buffer[copy_index],
                        &ts->payload.payload[start_offset],
                        payload_size);

                copy_index += payload_size;
            }

            curr_ptr += sizeof(sMPEG2_TS);
            bytes_left -= sizeof(sMPEG2_TS);

        } while (bytes_left > 0);

    } while (curr_desc->next != NULL);

    // Set length.
    hw_buf->buffer_len = copy_index;

    // Free the existing slice, minus the head (timestamp).
    sx_desc_put(slice_head->next);

    // Set slice.
    slice_head->next = hw_desc_head;

    sx_pipe_put(SX_VRDMA_SLICE_READY, slice_head);
}
コード例 #4
0
static void audio_scheduler_slice_dump(
    sSX_DESC  *slice_head
    )
{
    UINT8      *curr_ptr;
    UINT32      bytes_left;
    UINT32      afc;
    UINT32      pid;
    UINT32      pes_byte_count;
    UINT32      payload_size;
    UINT32      start_offset;
    UINT32      copy_index;
    UINT32      samples_left;
    UINT32      ms_left;
    sSX_DESC   *desc;


    static UINT8   playback_speed = 1;

    ms_left = audio_total_remaining_ms();
    if(ms_left > (100 + SX_SYSTEM_DELAY_MS))
    {
        if(playback_speed != 2)
        {
            sx_audio_sink_playback_speed_inc();

            playback_speed = 2;
        }
    }
    else if(ms_left < (50 + SX_SYSTEM_DELAY_MS))
    {
        if(playback_speed != 0)
        {
            sx_audio_sink_playback_speed_dec();

            playback_speed = 0;
        }
    }
    else
    {
        if(playback_speed != 1)
        {
            sx_audio_sink_playback_speed_reset();

            playback_speed = 1;
        }
    }

    UINT8 *buf = sx_audio_sink_buffer_get();

    copy_index = 0;

    desc = slice_head;
    do
    {
        // Get current.
        curr_ptr = desc->data;

        // Get data left.
        bytes_left = desc->data_len;
        assert(bytes_left > sizeof(sRTP_HDR));

        // Get RTP header.
        // sRTP_HDR *rtp_hdr = (sRTP_HDR *) curr_ptr;

        // Get TS header.
        curr_ptr += sizeof(sRTP_HDR);

        // Get TS bytes left.
        bytes_left -= sizeof(sRTP_HDR);
        assert((bytes_left % sizeof(sMPEG2_TS)) == 0);

        pes_byte_count = 0;
        do
        {
            sMPEG2_TS *ts = (sMPEG2_TS *) curr_ptr;

            afc = AFC_GET(ts->hdr);
            pid = PID_GET(ts->hdr);

            if(pid == 0x1100)
            {
                UINT8 stuffing = 0; 
                if(afc & 0x02)
                {
                    stuffing = 1 + ts->payload.payload[0]; 
                }

                start_offset = stuffing; 

                if(PUSI_GET(ts->hdr))
                {
                     start_offset += 20;
                }

                payload_size = sizeof(sMPEG2_TS_PAYLOAD) - start_offset;


#if 0
                if(PUSI_GET(ts->hdr))
                {
                    assert(afc == 0x01);

                    start_offset = 20;

                    payload_size = (sizeof(sMPEG2_TS_PAYLOAD) - start_offset);
                }
                else
                {
                    if(afc == 0x01)
                    {
                        start_offset = 0;

                        payload_size = sizeof(sMPEG2_TS_PAYLOAD);
                    }
                    else if(afc == 0x03)
                    {
                        start_offset = 1 + ts->payload.payload[0];

                        payload_size = sizeof(sMPEG2_TS_PAYLOAD) - start_offset;
                    }
                    else
                    {
                        assert(0);
                    }
                }
#endif 

//                printf("copy 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
//                        ts->payload.payload[start_offset],
//                        ts->payload.payload[start_offset + 1],
//                        ts->payload.payload[start_offset + 2],
//                        ts->payload.payload[start_offset + 3],
//                        ts->payload.payload[start_offset + 4],
//                        ts->payload.payload[start_offset + 5],
//                        ts->payload.payload[start_offset + 6],
//                        ts->payload.payload[start_offset + 7]);

                memcpy(&buf[copy_index],
                        &ts->payload.payload[start_offset],
                        payload_size);

                copy_index += payload_size;
            }

            curr_ptr += sizeof(sMPEG2_TS);
            bytes_left -= sizeof(sMPEG2_TS);

        } while (bytes_left > 0);

        desc = desc->next;

    } while (desc != NULL);

    sx_desc_put(slice_head);

    assert(copy_index == 1920);

//    printf("### 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
//            buf[0],
//            buf[1],
//            buf[2],
//            buf[3],
//            buf[4],
//            buf[5],
//            buf[6],
//            buf[7]);

    audio_endianness_convert((UINT16 *) buf, 960);

    // Push to decoder hardware.
    sx_audio_sink_buffer_set(buf, 1920);
}