• walkinsky
    了解作者
  • Unix_Linux
    开发工具
  • 5KB
    文件大小
  • gz
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 74
    下载次数
  • 2010-08-19 16:36
    上传日期
mpeg2的ts流解析,按照实际播放流媒体的过程来实现,从pat表分析出pmt表内容,从pmt表内容分析es流的pid,然后把video,audio内容的es 流输出相应pid名的文件。
tsdemux.tar.gz
  • tsdemux.c
    22.7KB
内容介绍
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #define TSPACKETLEN 188 #define PAT_Pid 0x00 #define PMT_MAX 8 #define PES_MAX 0x10 #define cnCRC32Size 4 #define VID 4 #define AUD 5 #define PIDINT_LIST_START_SIZE 5 #define PIDINT_LIST_INCREMENT 10 #define EVALUATE(d, s) TransData(&d, s, sizeof(d)); s += sizeof(d) #define INIT_STRUCT(_STRUCT, _STREAM) _STRUCT; \ TransData(&_STRUCT, _STREAM, sizeof(_STRUCT)); \ _STREAM += sizeof(_STRUCT) typedef enum bool{ false,true }bool; //typedef uint8_t byte; typedef unsigned char byte; //typedef long long __int64; #define __int64 long long int #define __int32 int struct TS_header_tag { unsigned char sync_byte; unsigned char transport_error_indicator; unsigned char payload_unit_start_indicator; unsigned char transport_priority; unsigned int PID; unsigned char transport_scrambling_control; unsigned char adaptation_field_control; unsigned char continuity_counter; } ; //struct TS_header_tag TS_header; struct TS_packet_header//defined in reverse order { unsigned int continuity_counter :4 ; unsigned int adaptation_field_control :2 ; unsigned int transport_scrambling_control :2 ; unsigned int PID :13 ; unsigned int transport_priority :1 ; unsigned int payload_unit_start_indicator :1 ; unsigned int transport_error_indicator :1 ; unsigned int sync_byte :8 ; }; typedef struct TS_packet_header TS_packet_header; //struct TS_packet_header TS_header; FILE *ip_file; int sync_bytes[10]; unsigned char ts_package[TSPACKETLEN]; unsigned int adaption_field_length; unsigned int pointer_field_length; struct pmt_pid_st { int *number; int *pid; int length; int size; }; struct pmt_pid_st pmt_pid; struct pes_pid_st { int *stream_type; int *pid; int *payload_start; int *continuity_counter_before; int length; int size; }; struct pes_pid_st pes_pid; void pat_parser(); void pmt_parser(); void vid_parser(int n); void program_association_section(unsigned char *buff, int leng); void program_map_section(byte* buff, int leng); void transport_packet(unsigned char *buff); unsigned short descriptor(byte *p_descriptor); void pes_packet(byte* buff, int leng,TS_packet_header *p_header); int init_pmt_list(struct pmt_pid_st *list); int init_pes_list(struct pes_pid_st *list); int add_pmt_list(struct pmt_pid_st *list, int pid, int program); int add_pes_list(struct pes_pid_st *list,int stream_type, int pid); void free_pmt_list(struct pmt_pid_st *list); void free_pes_list(struct pes_pid_st *list); void report_pmt_list(struct pmt_pid_st *list); void report_pes_list(struct pes_pid_st *list); /* void TS_header_decode() { // current_header_add = ftell(ip_file); // fread(&TS_raw_header, sizeof(TS_raw_header), 1, ip_file); // read the header TS_header.sync_byte = ts_package[0]; TS_header.transport_error_indicator = (ts_package[1] & 0x80) >> 7; TS_header.payload_unit_start_indicator = (ts_package[1] & 0x40) >> 6; TS_header.transport_priority = (ts_package[1] & 0x20) >> 5; TS_header.PID = ((ts_package[1] & 31) << 8) | ts_package[2]; TS_header.transport_scrambling_control = (ts_package[3] & 0xC0); TS_header.adaptation_field_control = (ts_package[3] & 0x30) >> 4; TS_header.continuity_counter = (ts_package[3] & 0xF); } */ void TS_header_decode(TS_packet_header *p_header,byte* buff) { *(byte *)p_header = *(buff+3); *((byte *)(p_header)+1) = *(buff+2); *((byte *)(p_header)+2) = *(buff+1); *((byte *)(p_header)+3) = *(buff); } bool TransData(void * pTarget, const unsigned char * pStream, int nBytes) { int i; if (nBytes <= 0) { return false; } if (nBytes == 1 || nBytes == 2 || (nBytes % 4) == 0) { for (i = 0; i < nBytes; i ++) { *((unsigned char*)(pTarget) + i) = *(pStream + (nBytes - i - 1)); } return true; } else { return false; } } bool find_TS_sync_byte(void) { // scan file looking for sync_bytes int sync_data = 0; // storage for data read from file int occurance = 0; // keep track of how many sync_bytes have been found long int current_file_pos = 0; // where are we? while ( !feof(ip_file) && occurance < 6) { current_file_pos = ftell(ip_file); sync_data = 0; fread(&sync_data, 1, 1, ip_file); switch (sync_data) { // if sync_byte is found then remember it in sync_bytes[] case 0x47 : sync_bytes[occurance] = current_file_pos; occurance++; fseek(ip_file,187,1); // look for next one break; default : // if byte is not equal to 0x47 occurance = 0; } } if ( occurance < 6 ) { // report error if 5 cannot be found return false; } return true; } int main(int argc, char *argv[]) { char fileName[255]; bool sync_find=false; int rsize; long long circle_num; int err; if (argc != 2) { printf("Usage:%s TSfile\n", argv[0]); return -1; } memset(fileName,0,255); strcpy(fileName, argv[1]); unsigned int i=0; err = init_pes_list(&pes_pid); if(err) return 1; err = init_pmt_list(&pmt_pid); if(err) return 1; ip_file = fopen(fileName, "rb"); if(ip_file <= 0) { printf("File %s can't be opened\n", fileName); exit(2); } sync_find = find_TS_sync_byte(); if(sync_find==false) return 0; circle_num =0; fseek(ip_file, sync_bytes[1], 0); while(1) { rsize = fread(&ts_package, sizeof(ts_package), 1, ip_file); // read the header if(feof(ip_file)||(rsize <1)) { fclose(ip_file); printf("Finished! \n"); break; } circle_num++; transport_packet(ts_package); } report_pmt_list(&pmt_pid); report_pes_list(&pes_pid); free_pmt_list(&pmt_pid); free_pes_list(&pes_pid); return 0; } int adaptation_field(unsigned char *pField) { struct _adaptation_field_data {//defined in reverse order byte adaptation_field_extension_flag :1; byte transport_private_data_flag :1; byte splicing_poing_flag :1; byte OPCR_flag :1; byte PCR_flag :1; byte elementary_stream_priority_indicator :1; byte random_access_indicator :1; byte discontinuity_indicator :1; byte adaptation_field_length; }INIT_STRUCT(adaptation_field_data, pField); return adaptation_field_data.adaptation_field_length + 1; } bool ispmt(unsigned int pid) { int i; for(i=0;i<pmt_pid.length;i++) { if(pid == pmt_pid.pid[i]) return true; } return false; } bool ispes(unsigned int pid) { int i; for(i=0;i<pes_pid.length;i++) { if(pid == pes_pid.pid[i]) return true; } return false; } void transport_packet(unsigned char *buff) { int leng = TSPACKETLEN, size; TS_packet_header transport_packet_header; // EVALUATE(transport_packet_header, buff); TS_header_decode(&transport_packet_header, buff); buff +=4; leng -= sizeof(transport_packet_header); if (transport_packet_header.transport_error_indicator || transport_packet_header.transport_scrambling_control) { return; }
评论
    相关推荐