⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file_capture_decoder.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2006 Videon Central, Inc.                                 **
**  All rights reserved.                                                    **
**                                                                          **
**  The computer program contained herein contains proprietary information  **
**  which is the property of Videon Central, Inc.  The program may be used  **
**  and/or copied only with the written permission of Videon Central, Inc.  **
**  or in accordance with the terms and conditions stipulated in the        **
**  agreement/contract under which the programs have been supplied.         **
**                                                                          **
******************************************************************************
*****************************************************************************/
/**
 * @file file_capture_decoder.cpp
 *
 * $Revision: 1.30 $ 
 *
 * File Capture Decoder - provides a sample decoder which captures all decode
 *                        data and writes it to a file.
 *
 */

#include <string.h>
#include <time.h>
#include "file_capture_decoder.h"
#include "arch.h"
#include "error.h"
#include "dbgprint.h"




/********************************************************************************
                                    CONSTANTS
 ********************************************************************************/

#define     DBG_FILE_CAPTURE_DECODER        DBG_VERBOSE
#define     DBG_ON(x)                       (DBG_FILE_CAPTURE_DECODER >= x)


#define     FILE_CAPTURE_DECODER_THREAD_STACK_SIZE                              2048

#define     FILE_CAPTURE_DECODER_DECODE_DONE_EVENT_TIMEOUT_IN_SECONDS           5    
#define     FILE_CAPTURE_DECODER_PRESENTATION_START_EVENT_TIMEOUT_IN_SECONDS    2

#define     FILE_CAPTURE_DECODER_MPEG_STATUS_THRESHOLD_IN_BYTES                 2*1024*1024
#define     FILE_CAPTURE_DECODER_PCM_STATUS_THRESHOLD_IN_BYTES                  48*1024

#define     FILE_CAPTURE_ROOT_DIRECTORY     ""






/**
 *******************************************************************************
 *  FileCaptureDecoderThread is the entry point for the thread which pretends to
 *  decode the captured data by sending presentation start and decode finished
 *  event notifications after pre-defined timeouts.
 *
 *  @param      parameter   pointer to the FileCaptureDecoder instance to be monitored
 *
 *  @return     VDVD_SUCCESS
 *******************************************************************************/
ULONG  FileCaptureDecoderThread ( void* parameter )
{
    FileCaptureDecoder*     decoder = (FileCaptureDecoder*)parameter;

    BOOLEAN                 presentationStarted     = FALSE;
    uint32                  startReceivedDataTime   = 0;
    uint32                  endReceivedDataTime     = 0;
    uint32                  elapsedTime             = 0;


    presentationStarted = FALSE;

    while ( decoder->m_threadExitRequest == FALSE ) 
    {
        // Poll to see if we have received any data
        if ( decoder->m_receivedDataFlag == TRUE ) 
        {
            endReceivedDataTime = (uint32)time(NULL);
            decoder->m_receivedDataFlag = FALSE;

            if ( startReceivedDataTime == 0 )
            {
                startReceivedDataTime = endReceivedDataTime;
            }
        }


        // if we have received some data, and have not yet sent presentation 
        // started notification check for presentation start timeout 
        if (( startReceivedDataTime > 0 ) && ( presentationStarted == FALSE))
        {
            elapsedTime = (ULONG)time(NULL) - startReceivedDataTime;
            if ( elapsedTime >= FILE_CAPTURE_DECODER_PRESENTATION_START_EVENT_TIMEOUT_IN_SECONDS )
            {
                presentationStarted = TRUE;
                decoder->Notify(DECODE_EVENT_PRESENTATION_START);
            }
        }


        // if we have received some data check for decode finished timeout 
        if ( endReceivedDataTime > 0 ) 
        {
            elapsedTime = (ULONG)time(NULL) - endReceivedDataTime;
            if ( elapsedTime >= FILE_CAPTURE_DECODER_DECODE_DONE_EVENT_TIMEOUT_IN_SECONDS )
            {
                decoder->Notify(DECODE_EVENT_DECODE_DONE);
                startReceivedDataTime   = 0;
                endReceivedDataTime     = 0;
                presentationStarted     = FALSE;
            }
        }


        OS_TaskDelay(OS_WAIT_1S / 10);
    }

    return ( VDVD_SUCCESS );
}






/**
 *******************************************************************************
 *  FileCaptureDecoder::FileCaptureDecoder    initialize members to known state
 *
 *******************************************************************************/
FileCaptureDecoder::FileCaptureDecoder ( void )
{
    m_name                                              = NULL;
    m_threadId                                          = (ULONG)OS_FAILURE;
    m_threadExitRequest                                 = FALSE;
    m_receivedDataFlag                                  = FALSE;
    
    m_statusUpdateThreshold                             = 0;
    m_numberOfBuffersReceived                           = 0;
    m_numberOfBuffersAvailableToRelease                 = 0;
    m_numberOfBytesReceived                             = 0;
    m_numberOfBytesReceviedSinceLastUserNotification    = 0;

    m_fileHandle                                        = 0;
    m_sequenceNumber                                    = 0;

    m_video_pts                                         = 0;
    m_video_stc                                         = 0;
    m_audio_pts                                         = 0;
    m_audio_stc                                         = 0;

    memset(&m_decoderSettings,0,sizeof(m_decoderSettings));
    m_decoderSettings.streamType = DECODER_STREAM_TYPE_UNKNOWN;
}







/**
 *******************************************************************************
 *  FileCaptureDecoder::Create  allocate resources needed
 *
 *  @param      name        decoder name, prefix for output files
 *
 *  @return     If the function succeeds, the return value is VDVD_SUCCESS.
 *******************************************************************************/
VDVD_ERROR   FileCaptureDecoder::Create ( const char* name )
{
    AutoMutex   autoMutex(&m_mutex);

    VDVD_ASSERT_ERROR( (IsReferenced()==TRUE), VDVD_ERROR_OBJECT_HAS_INVALID_STATE );

    VDVD_RAISE_ERROR( Decoder::Create( "FileCaptureDecoder" ) );

    m_threadId = OS_TaskSpawnParam("FileCaptureDecoderThread", 
                                    OS_TASK_NORMAL_PRIORITY, 
                                    FILE_CAPTURE_DECODER_THREAD_STACK_SIZE, 
                                    FileCaptureDecoderThread, 
                                    (void*)this, 
                                    NULL);

    VDVD_ASSERT_ERROR( (m_threadId==(ULONG)OS_FAILURE), VDVD_ERROR_PLATFORM_FAILED );

    m_name                                              = name;
    m_threadExitRequest                                 = FALSE;
    m_receivedDataFlag                                  = FALSE;
    
    m_statusUpdateThreshold                             = 0;
    m_numberOfBuffersReceived                           = 0;
    m_numberOfBuffersAvailableToRelease                 = 0;
    m_numberOfBytesReceived                             = 0;
    m_numberOfBytesReceviedSinceLastUserNotification    = 0;
    m_sequenceNumber                                    = 0;
    m_video_pts                                         = 0;
    m_video_stc                                         = 0;
    m_audio_pts                                         = 0;
    m_audio_stc                                         = 0;

    return ( VDVD_SUCCESS );
}






/**
 *******************************************************************************
 *  FileCaptureDecoder::Create  frees resources allocated
 *
 *  @return     If the function succeeds, the return value is VDVD_SUCCESS.
 *******************************************************************************/
VDVD_ERROR   FileCaptureDecoder::Destroy ( void )
{
    AutoMutex   autoMutex(&m_mutex);
    int         result;

    VDVD_ASSERT_ERROR( (IsReferenced()==FALSE), VDVD_ERROR_OBJECT_HAS_INVALID_STATE );

    if ( m_threadId != (ULONG)OS_FAILURE )
    {
        m_threadExitRequest = TRUE;
        OS_TaskJoin(m_threadId);
        OS_TaskDelete(m_threadId);
        m_threadId = (ULONG)OS_FAILURE;
    }

    if ( m_fileHandle != 0 ) 
    {
        result = FILE_CLOSE(m_fileHandle);
        VDVD_ASSERT_ERROR( (result==-1), VDVD_ERROR_PLATFORM_FAILED );
    }

    VDVD_RAISE_ERROR( Decoder::Destroy() );

    return ( VDVD_SUCCESS );
}





/**
 *******************************************************************************
 *  FileCaptureDecoder::CloseOutputFile   If currently writing decode data to a file,
 *  the file is closed. If no data has been written the sequence number is 
 *  re-used for the next file.
 *
 *  @return     If the function succeeds, the return value is VDVD_SUCCESS.
 *******************************************************************************/
VDVD_ERROR   FileCaptureDecoder::CloseOutputFile ( void )
{
    int     result;
    int64   fileLength;

    VDVD_ASSERT_ERROR( (IsReferenced()==FALSE), VDVD_ERROR_OBJECT_HAS_INVALID_STATE );

    if ( m_fileHandle != 0 ) 
    {
        fileLength = FILE_SEEK( m_fileHandle, 0, SEEK_END);
        VDVD_ASSERT_ERROR( (fileLength==-1), VDVD_ERROR_PLATFORM_FAILED );

        if ( fileLength == 0 ) 
        { 
            // repeat sequence number if no data was delivered to decoder
            m_sequenceNumber--;
        }

        result = FILE_CLOSE( m_fileHandle );
        VDVD_ASSERT_ERROR( (result==-1), VDVD_ERROR_PLATFORM_FAILED );

        m_fileHandle = 0;
    }

    return ( VDVD_SUCCESS );
}






/**
 *******************************************************************************
 *  FileCaptureDecoder::Setup   prepares decoder for type of stream
 *
 *  @param      settings        type of stream to decode
 *
 *  @return     If the function succeeds, the return value is VDVD_SUCCESS.
 *******************************************************************************/
VDVD_ERROR   FileCaptureDecoder::Setup( DECODER_SETTINGS_TYPE* settings )
{
    AutoMutex           autoMutex(&m_mutex);
    char                filename[512];
    int64               result      = 0;
    unsigned long int   fileLength  = 0;
    char*               extension   = NULL;


    VDVD_ASSERT_ERROR( (IsReferenced()==FALSE), VDVD_ERROR_OBJECT_HAS_INVALID_STATE );

    switch ( settings->streamType ) 
    {
        case DECODER_STREAM_TYPE_MPEG2:     
            extension = "mpeg"; 
            m_statusUpdateThreshold = FILE_CAPTURE_DECODER_MPEG_STATUS_THRESHOLD_IN_BYTES;
        break;

        case DECODER_STREAM_TYPE_PCM:       
            extension = "raw";  
            m_statusUpdateThreshold = FILE_CAPTURE_DECODER_PCM_STATUS_THRESHOLD_IN_BYTES;
        break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -