📄 user_data_task.c
字号:
/* * Copyright (c) 2004, 2005 Koninklijke Philips Electronics N V. Includes code * copyright (c) 2004 by VCom Electronics Inc; copyright transferred by verbal * agreement between Tim Meakin and Jonathan Coxhead, November 2004. All rights * reserved. * * This source code and any compilation or derivative thereof is the proprietary * information of Koninklijke Philips Electronics N V and is confidential in * nature. Under no circumstances is this software to be exposed to or placed * under an Open Source License of any type without the express written * permission of Koninklijke Philips Electronics N V. * * ############################################################################# * * Module: %name: user_data_task.c % %version: 1 % * * %date_created: Fri Mar 11 11:55:27 2005 % %created_by: jcoxhead % * * %date_modified: Fri Jun 14 11:31:56 2002 % * * ############################################################################# *//* -------------------------------------------------------------------------- * * DESCRIPTION: Task to handle User Data extracted by MPEG Video Decoder. * * -------------------------------------------------------------------------- */#define DBG_DISABLE_ALL#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#include <psos.h>#include <tmNxTypes.h>#include <tmosal.h>#include <tmMainStreaming.h>#include <tmml.h>#include <tmDbg.h>#include <tmdlGpio.h>#include "tmalDemuxMpegTS.h"#include "user_data_task.h"//---------------------------------------------------------------------------// Defines and Macros//---------------------------------------------------------------------------#define GPIO_ENABLE_PIN_ID 36#define GPIO_CLOCK_PIN_ID 40#define GPIO_DATA_PIN_ID 39#define EIA_608_ADVANCED_TELEVISION_CLOSED_CAPTIONING 0x03#define EIA_608_ADDITIONAL_DATA 0x04#define LUMINANCE_PAM_DATA 0x05#define MAX_NUM_CC_DATA_BYTES 256 // :TODO: verify#define RECTANGULAR_PULSE_SHAPE 0x00#define RAISED_COSINE_PULSE_SHAPE 0x01#define PARTIAL_RESPONSE_CODING_PULSE_SHAPE 0x02#define PULL_LOW 0x00#define PULL_HIGH 0x01//---------------------------------------------------------------------------// Global Data//---------------------------------------------------------------------------//---------------------------------------------------------------------------// Function Prototypes//---------------------------------------------------------------------------static tmErrorCode_t parseUserDataPacket( UInt8 *pPacket, UInt32 pktLength );//---------------------------------------------------------------------------// Functions//---------------------------------------------------------------------------//---------------------------------------------------------------------------voiduserDataTask( pVoid pArgs ){ UInt32 in_packets = 0; UInt32 packetSize = 0; UInt32 i = 0; UInt32 taskID = 0; ptmAvPacket_t packetPtr = Null; UInt8 *pPacketStart = Null; ptaskArgs_t userDataTaskArgsPtr = (ptaskArgs_t)pArgs; taskArgs_t userDataTaskArgs;#ifndef TURN_OFF_FILE_WRITES Int fd = 0; Int8 filename[128];#endif // TURN_OFF_FILE_WRITES DBG_ISR_PRINT( (dbgTsDemux, DBG_INTERNAL_ENTER, "userDataTask") ) // Make local copy of parameters passed in on the stack userDataTaskArgs.instance = userDataTaskArgsPtr->instance; userDataTaskArgs.fullQ = userDataTaskArgsPtr->fullQ; userDataTaskArgs.emptyQ = userDataTaskArgsPtr->emptyQ; strcpy( userDataTaskArgs.fileName, userDataTaskArgsPtr->fileName ); // Obtain the task identifier t_ident( (char *)0, 0, &taskID ); DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_4, "userDataTask ID=0x%x", taskID) ) EQ_ERRCHK( userDataTaskArgs.instance, 0 )#ifndef TURN_OFF_FILE_WRITES filename[0] = '\0'; if ( userDataTaskArgs.fileName != Null ) { strcpy( filename, userDataTaskArgs.fileName ); if ( (fd = open( filename, OPEN_FLAGS, 0644 )) == -1 ) { NOT_EQ_ERRCHK( fd, fd ) tmosalTaskExit(); } }#endif // TURN_OFF_FILE_WRITES // Loop forever for ( ;; ) { // Wait to receive a full packet from an input connection queue ERRCHK( qDataInGetFull( userDataTaskArgs.fullQ, False, &packetPtr ) ) // Check if we have been ordered to kill ourself if ( bKilluserDataTask == True ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1, "userDataTask: Received kill signal, exiting") ) tmosalTaskExit(); } for ( i = 0; i < packetPtr->buffersInUse; i++ ) { pPacketStart = packetPtr->buffers[i].data; packetSize = packetPtr->buffers[i].dataSize; in_packets ++; DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_4, "userDataTask: Size of input packet=%d", packetSize) ) // Parse the packet of user data parseUserDataPacket( pPacketStart, packetSize );#ifndef TURN_OFF_FILE_WRITES if ( fd && (packetSize != write( fd, pPacketStart, packetSize )) ) { NOT_EQ_ERRCHK( errno, 0 ) }#endif // TURN_OFF_FILE_WRITES } // Return an empty packet to an input connection queue ERRCHK( qDataInPutEmpty( userDataTaskArgs.emptyQ, packetPtr ) ) } // end loop}//---------------------------------------------------------------------------//---------------------------------------------------------------------------static tmErrorCode_tparseUserDataPacket( UInt8 *pPacket, UInt32 pktLength ){ Int i = 0; Int j = 0; UInt8 userDataType = 0; UInt8 markerBits = 0; UInt16 numOutputBytes = 0; UInt8 outputBuffer[MAX_NUM_CC_DATA_BYTES]; DBG_ISR_PRINT( (dbgTsDemux, DBG_INTERNAL_ENTER, "parseUserDataPacket") ) if ( pktLength < ( i + 4) ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1, "parseUserDataPacket: Error: User data packet is too " "small, discarding packet") ) goto _return; } // Check for User Data Start Code if ( (pPacket[i] != 0x00) || (pPacket[i+1] != 0x00) || (pPacket[i+2] != 0x01) || (pPacket[i+3] != 0xB2) ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_4, "parseUserDataPacket: Warning: User data start code not " "found") ) } else { // Set index to position of first byte of ATSC Identifier i += 4; } if ( pktLength < (i + 4) ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1, "parseUserDataPacket: Error: User data packet is too " "small to check for ATSC Identifier, discarding packet") ) goto _return; } // Check for ATSC Identifier if ( (pPacket[i] != 0x47) || (pPacket[i+1] != 0x41) || (pPacket[i+2] != 0x39) || (pPacket[i+3] != 0x34) ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_4, "parseUserDataPacket: ATSC identifier not found in user " "data packet, discarding packet") ) goto _return; } else { // Set index to position of user data type code byte i += 4; } if ( pktLength < (i + 1) ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1, "parseUserDataPacket: Error: User data packet is too " "small to check for User Data Type Code, discarding " "packet") ) goto _return; } // Check the User Data Type Code userDataType = pPacket[i]; switch ( userDataType ) { case EIA_608_ADVANCED_TELEVISION_CLOSED_CAPTIONING: { UInt8 processEmDataFlag = 0; UInt8 processCcDataFlag = 0; UInt8 additionalDataFlag = 0; UInt8 ccCount = 0; DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_4, "parseUserDataPacket: User data type code=0x%x: " "EIA 608 Advanced Television Closed Captioning", userDataType) ) // Set index to position of data flags/CC count byte i++; if ( pktLength < (i + 1) ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1, "parseUserDataPacket: User data packet is too small " "to check for data flags/CC count, discarding packet") ) goto _return; } processEmDataFlag = (pPacket[i] >> 7) & 0x01; // Emergency message data present processCcDataFlag = (pPacket[i] >> 6) & 0x01; // Closed captioning data present additionalDataFlag = (pPacket[i] >> 5) & 0x01; // Additional data present ccCount = pPacket[i] & 0x1F; // Number of closed captioning bytes if ( (processEmDataFlag || (ccCount > 0)) && (pktLength < (i + 2)) ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1, "parseUserDataPacket: User data packet is too small " "to check for Emergency Message data, discarding " "packet") ) goto _return; } // Set index to position of emergency message data byte i++; if ( processEmDataFlag ) { /* Put user data type code and emergency message data byte into output buffer */ // :TODO: verify how we want to send these bytes outputBuffer[numOutputBytes++] = userDataType; outputBuffer[numOutputBytes++] = pPacket[i]; DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_2, "parseUserDataPacket: Found emergency message data " "byte=0x%x", pPacket[i]) ) } // Set index to start of first set of Closed Captioning data bytes i++; if ( (ccCount > 0) && (pktLength < (i + (ccCount * 3))) ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1, "parseUserDataPacket: User data packet is too small " "to check for CC data, discarding packet") ) goto _return; } if ( processCcDataFlag ) { for ( j = 0; j < ccCount; j++ ) { UInt8 ccValidFlag = 0; UInt8 ccType = 0; markerBits = (pPacket[i] >> 3) & 0x1F; // Marker bits ccValidFlag = (pPacket[i] >> 2) & 0x01; // Closed captioning valid flag ccType = pPacket[i] & 0x03; // Closed captioning data type if ( markerBits != 0x1F ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_4, "parseUserDataPacket: Error: Invalid marker " "bits found for CC data, discarding data") ) // Set index to start of next set of Closed Captioning data bytes i += 3; continue; } if ( ccValidFlag ) { /* Put user data type code, CC type and data bytes into output buffer */ // :TODO: verify how we want to send these bytes outputBuffer[numOutputBytes++] = userDataType; outputBuffer[numOutputBytes++] = ccType; outputBuffer[numOutputBytes++] = pPacket[i+1]; outputBuffer[numOutputBytes++] = pPacket[i+2]; DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_4, "parseUserDataPacket: Found CC type=0x%x, " "CC data bytes=0x%x, 0x%x", ccType, pPacket[i+1], pPacket[i+2]) ) } // Set index to start of next set of Closed Captioning data bytes i += 3; } // end for loop } else { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_4, "parseUserDataPacket: process_cc_data_flag not set, " "discarding any CC data in packet") ) // Set index to 1 past the end of Closed Captioning data bytes i += (ccCount * 3); } if ( pktLength < (i + 1) ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1, "parseUserDataPacket: User data packet is too small " "to check for marker bits after CC data, discarding " "packet") ) goto _return; } markerBits = pPacket[i]; if ( markerBits != 0xFF ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_4, "parseUserDataPacket: Error: Invalid marker " "bits=0x%x found after CC data", markerBits) ) } if ( additionalDataFlag ) { DBG_ISR_PRINT( (dbgTsDemux, DBG_LEVEL_1,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -