/*****************************************************************************
* bits.h
*****************************************************************************/
struct bits_buffer
{
int i_size;
int i_data; //得到最后字节的位置
unsigned char i_mask;
unsigned char *p_data;
} ;
static inline int bits_initwrite( bits_buffer *p_buffer, int i_size, unsigned char* p_data )
{
p_buffer->i_size = i_size;
p_buffer->i_data = 0;
p_buffer->i_mask = 0x80;
p_buffer->p_data = p_data;
p_buffer->p_data[0] = 0;
if( !p_buffer->p_data )
{
if( !( p_buffer->p_data=new unsigned char [i_size] ) )
{
return( -1 );
}
else
{
return( 0 );
}
}
else
{
return( 0 );
}
}
static inline void bits_align( bits_buffer *p_buffer )
{
if( p_buffer->i_mask != 0x80 && p_buffer->i_data < p_buffer->i_size )
{
p_buffer->i_mask = 0x80;
p_buffer->i_data++;
p_buffer->p_data[p_buffer->i_data] = 0x00;
}
}
static inline void bits_write( bits_buffer *p_buffer,
int i_count, unsigned long i_bits )
{
while( i_count > 0 )
{
i_count--;
if( ( i_bits >> i_count )&0x01 )
{
p_buffer->p_data[p_buffer->i_data] |= p_buffer->i_mask;
}
else
{
p_buffer->p_data[p_buffer->i_data] &= ~p_buffer->i_mask;
}
p_buffer->i_mask >>= 1;
if( p_buffer->i_mask == 0 )
{
p_buffer->i_data++;
p_buffer->i_mask = 0x80;
}
}
}
static inline void bits_read( bits_buffer *p_buffer,
int i_count, unsigned long i_bits )
{
while( i_count > 0 )
{
i_count--;
if( ( p_buffer->p_data[p_buffer->i_data] >> i_count )&0x01 )
{
i_bits |= p_buffer->i_mask;
}
else
{
i_bits &= ~p_buffer->i_mask;
}
p_buffer->i_mask >>= 1;
if( p_buffer->i_mask == 0 )
{
p_buffer->i_data++;
p_buffer->i_mask = 0x80;
}
}
}
static inline void bits_Tempread( bits_buffer *p_buffer,
int i_count, unsigned long i_bits )
{
int data=p_buffer->i_data;
unsigned char mask=p_buffer->i_mask;
while( i_count > 0 )
{
i_count--;
if( ( p_buffer->p_data[p_buffer->i_data] >> i_count )&0x01 )
{
i_bits |= p_buffer->i_mask;
}
else
{
i_bits &= ~p_buffer->i_mask;
}
p_buffer->i_mask >>= 1;
if( p_buffer->i_mask == 0 )
{
p_buffer->i_data++;
p_buffer->i_mask = 0x80;
}
}
p_buffer->i_data=data;
p_buffer->i_mask=mask;
}
static inline next_start_code(bits_buffer *p_buffer)
{
bits_align(p_buffer);
/* Check if we are at the start code.
If not there is zero byte stuffing */
/* check starting code or skip zero byte stuffing */
long result;
bits_Tempread(p_buffer,24,result);
while(!(result==0x000001))
{
bits_read(p_buffer,1,result);
bits_Tempread(p_buffer,24,result);
}
}
DefPara.h
#pragma once
#include <stdlib.h> /* calloc(), malloc(), free() */
#include <string.h>
#define PES_PROGRAM_STREAM_MAP 0xbc
#define PES_PRIVATE_STREAM_1 0xbd
#define PES_PADDING 0xbe
#define PES_PRIVATE_STREAM_2 0xbf
#define PES_ECM 0xb0
#define PES_EMM 0xb1
#define PES_PROGRAM_STREAM_DIRECTORY 0xff
#define PES_DSMCC_STREAM 0xf2
#define PES_ITU_T_H222_1_TYPE_E_STREAM 0xf8
#define __MIN(a, b) ( ((a) < (b)) ? (a) : (b) )
#define UNKNOWN_ES 0x00
#define VIDEO_ES 0x01
#define AUDIO_ES 0x02
#define SPU_ES 0x03
#define NAV_ES 0x04
typedef DWORD mtime;
typedef unsigned int uint32;
typedef unsigned char uchar;
/* for mux */
typedef struct buffer_t
{
uchar *p_buffer;
int i_size;
DWORD i_dts;
DWORD i_pts;
buffer_t* p_next;
}
PES_PARA,ES_PARA,TS_PARA;
typedef struct TSParamer
{
int i_pid;
int i_stream_type;
int i_stream_id;
mtime i_pes_dts;
mtime i_pes_length;
} TSPARAMER;
// ESToTS.h: interface for the ESToTS class.
//
//////////////////////////////////////////////////////////////////////
#pragma once
#include "bits.h"
#include "DefPara.h"
class ESToTS
{
public:
bool m_bFileOpen;
HRESULT hr;
HRESULT OpenFile(FILE*);
HRESULT WriteFile(TS_PARA *TsBuffer);
HRESULT PESToTS(PES_PARA *p_pes,TSPARAMER *p_stream);
HRESULT EstoPES( ES_PARA *p_es, //ES Stream Data
int i_stream_id, //Allocter the strean ID
int b_mpeg2 );
HRESULT GetES(uchar* buffer, int length);
int InitPESHeader(unsigned char *p_hdr,
DWORD i_pts, //PTS
DWORD i_dts, //DTS
int i_es_size, //ES Streamdata length
int i_stream_id, //Strean ID
int i_private_id, //Addtion parater data
int b_mpeg2 );
ESToTS();
virtual ~ESToTS();
FILE *fd;
};
- // ESToTS.cpp: implementation of the ESToTS class.
- //
- //////////////////////////////////////////////////////////////////////
-
- #include "stdafx.h"
- #include "ParkertTS.h"
- #include "ESToTS.h"
- #include <io.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
- #include "string.h"
-
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
-
- #define PES_PAYLOAD_SIZE_MAX 2048
-
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
-
- ESToTS::ESToTS(): hr(S_OK),m_bFileOpen(false)
- {
-
- }
-
- ESToTS::~ESToTS()
- {
-
- }
-
- int ESToTS::InitPESHeader(unsigned char *p_hdr,
- DWORD i_pts, //PTS
- DWORD i_dts, //DTS
- int i_es_size, //ES Streamdata length
- int i_stream_id, //Strean ID
- int i_private_id, //Addtion parater data
- int b_mpeg2 )
- {
- bits_buffer bits;
- int i_extra = 0;
-
- /* For PES_PRIVATE_STREAM_1 there is an extra header after the pes header */
- /* i_private_id != -1 because TS use 0xbd without private_id */
- if( i_stream_id == PES_PRIVATE_STREAM_1 && i_private_id != -1 )
- {
- i_extra = 1;
- if( ( i_private_id & 0xf0 ) == 0x80 )
- {
- i_extra += 3;
- }
- }
-
-
- bits_initwrite( &bits, 30, p_hdr );
-
- /* add start code */
- bits_write( &bits, 24, 0x01 );
- bits_write( &bits, 8, i_stream_id );
- switch( i_stream_id )
- {
- case PES_PROGRAM_STREAM_MAP:
- case PES_PADDING:
- case PES_PRIVATE_STREAM_2:
- case PES_ECM:
- case PES_EMM:
- case PES_PROGRAM_STREAM_DIRECTORY:
- case PES_DSMCC_STREAM:
- case PES_ITU_T_H222_1_TYPE_E_STREAM:
- /* add pes data size */
- bits_write( &bits, 16, i_es_size );
- bits_align( &bits );
- return( bits.i_data );
-
- default:
- /* arg, a little more difficult */
- if( b_mpeg2 )
- {
- int i_pts_dts;
-
- if( i_pts > 0 && i_dts > 0 )
- {
- bits_write( &bits, 16, i_es_size + i_extra+ 13 );
- i_pts_dts = 0x03;
- }
- else if( i_pts > 0 )
- {
- bits_write( &bits, 16, i_es_size + i_extra + 8 );
- i_pts_dts = 0x02;
- }
- else
- {
- bits_write( &bits, 16, i_es_size + i_extra + 3 );
- i_pts_dts = 0x00;
- }
-
- bits_write( &bits, 2, 0x02 ); // mpeg2 id
- bits_write( &bits, 2, 0x00 ); // pes scrambling control
- bits_write( &bits, 1, 0x00 ); // pes priority
- bits_write( &bits, 1, 0x00 ); // data alignement indicator
- bits_write( &bits, 1, 0x00 ); // copyright
- bits_write( &bits, 1, 0x00 ); // original or copy
-
- bits_write( &bits, 2, i_pts_dts ); // pts_dts flags
- bits_write( &bits, 1, 0x00 ); // escr flags
- bits_write( &bits, 1, 0x00 ); // es rate flag
- bits_write( &bits, 1, 0x00 ); // dsm trick mode flag
- bits_write( &bits, 1, 0x00 ); // additional copy info flag
- bits_write( &bits, 1, 0x00 ); // pes crc flag
- bits_write( &bits, 1, 0x00 ); // pes extention flags
- if( i_pts_dts == 0x03 )
- {
- bits_write( &bits, 8, 0x0a ); // header size -> pts and dts
- }
- else if( i_pts_dts == 0x02 )
- {
- bits_write( &bits, 8, 0x05 ); // header size -> pts
- }
- else
- {
- bits_write( &bits, 8, 0x00 ); // header size -> 0
- }
-
- /* write pts */
- if( i_pts_dts & 0x02 )
- {
- bits_write( &bits, 4, i_pts_dts ); // '0010' or '0011'
- bits_write( &bits, 3, i_pts >> 30 );
- bits_write( &bits, 1, 0x01 ); // marker
- bits_write( &bits, 15, i_pts >> 15 );
- bits_write( &bits, 1, 0x01 ); // marker
- bits_write( &bits, 15, i_pts );
- bits_write( &bits, 1, 0x01 ); // marker
- }
- /* write i_dts */
- if( i_pts_dts & 0x01 )
- {
- bits_write( &bits, 4, 0x01 ); // '0001'
- bits_write( &bits, 3, i_dts >> 30 );
- bits_write( &bits, 1, 0x01 ); // marker
- bits_write( &bits, 15, i_dts >> 15 );
- bits_write( &bits, 1, 0x01 ); // marker
- bits_write( &bits, 15, i_dts );
- bits_write( &bits, 1, 0x01 ); // marker
- }
- }
- else /* MPEG1 */
- {
- int i_pts_dts;
-
- if( i_pts > 0 && i_dts > 0 )
- {
- bits_write( &bits, 16, i_es_size + i_extra + 10 /* + stuffing */ );
- i_pts_dts = 0x03;
- }
- else if( i_pts > 0 )
- {
- bits_write( &bits, 16, i_es_size + i_extra + 5 /* + stuffing */ );
- i_pts_dts = 0x02;
- }
- else
- {
- bits_write( &bits, 16, i_es_size + i_extra + 1 /* + stuffing */);
- i_pts_dts = 0x00;
- }
-
- /* FIXME: Now should be stuffing */
-
- /* No STD_buffer_scale and STD_buffer_size */
-
- /* write pts */
- if( i_pts_dts & 0x02 )
- {
- bits_write( &bits, 4, i_pts_dts ); // '0010' or '0011'
- bits_write( &bits, 3, i_pts >> 30 );
- bits_write( &bits, 1, 0x01 ); // marker
- bits_write( &bits, 15, i_pts >> 15 );
- bits_write( &bits, 1, 0x01 ); // marker
- bits_write( &bits, 15, i_pts );
- bits_write( &bits, 1, 0x01 ); // marker
- }
- /* write i_dts */
- if( i_pts_dts & 0x01 )
- {
- bits_write( &bits, 4, 0x01 ); // '0001'
- bits_write( &bits, 3, i_dts >> 30 );
- bits_write( &bits, 1, 0x01 ); // marker
- bits_write( &bits, 15, i_dts >> 15 );
- bits_write( &bits, 1, 0x01 ); // marker
- bits_write( &bits, 15, i_dts );
- bits_write( &bits, 1, 0x01 ); // marker
- }
- if( !i_pts_dts )
- {
- bits_write( &bits, 8, 0x0F );
- }
-
- }
-
- /* now should be stuffing */
- /* and then pes data */
-
- bits_align( &bits );
- if( i_stream_id == PES_PRIVATE_STREAM_1 && i_private_id != -1 )
- {
- bits_write( &bits, 8, i_private_id );
- if( ( i_private_id&0xf0 ) == 0x80 )
- {
- bits_write( &bits, 24, 0 ); // ac3
- }
- }
- bits_align( &bits );
- return( bits.i_data );
- }
-
- }
-
-
- HRESULT ESToTS::GetES(uchar* buffer, int length)
- {
- int i_stream_id=23;
- int b_video =VIDEO_ES;
-
- ES_PARA *m_es;
- //(m_es,0,sizeof(ES_PARA));
- m_es = (ES_PARA *)malloc( sizeof(ES_PARA) );
-
-
- DWORD i_pts=0, i_dts=0;
- m_es->i_dts =0;
- m_es->i_pts =0;
- m_es->i_size =length;
- m_es->p_buffer =buffer;
- m_es->p_next =NULL;
- hr=EstoPES(m_es,i_stream_id,1);
- if(FAILED(hr))
- AfxMessageBox("EstoPES Failed");
- return hr;
- }
-
- HRESULT ESToTS::EstoPES(ES_PARA *p_es, //ES Stream Data
- int i_stream_id, //Allocter the strean ID
- int b_mpeg2 )
- {
- mtime i_pts, i_dts, i_length;
- PES_PARA *p_pes;
- uchar *p_data;
- int i_size;
- int i_private_id = -1;
-
- unsigned char header[30]; // PES header + extra < 30 (more like 17)
- int i_pes_payload;
- int i_pes_header;
- int i_pes_count = 1;
- p_pes = (ES_PARA *)malloc( sizeof(ES_PARA) );
-
- /* HACK for private stream 1 in ps */
- if( ( i_stream_id >> 8 ) == PES_PRIVATE_STREAM_1 )
- {
- i_private_id = i_stream_id & 0xff;
- i_stream_id = PES_PRIVATE_STREAM_1;
- }
-
- i_pts = p_es->i_pts <= 0 ? 0 : p_es->i_pts * 9 / 100; // 90000 units clock
- i_dts = p_es->i_dts <= 0 ? 0 : p_es->i_dts * 9 / 100; // 90000 units clock
-
- i_size = p_es->i_size;
- p_data = p_es->p_buffer;
- do
- {
- i_pes_payload = __MIN( i_size, PES_PAYLOAD_SIZE_MAX );
- //得到头文件的最后一字的位置
- i_pes_header = InitPESHeader( header, i_pts, i_dts, i_pes_payload,
- i_stream_id, i_private_id, b_mpeg2 );
-
- // only first PES has a dts/pts
- i_dts = 0;
- i_pts = 0;
-
- //把PES头写入PES域
-
- uchar* buffer=new uchar[i_pes_payload+i_pes_header];
- memset(buffer,0,i_pes_payload+i_pes_header);
-
- memcpy(buffer,header,i_pes_header);
- // for(int i =0;i<i_pes_header;i++)
- // *buffer++=header[i];
- // memcpy(p_pes->p_buffer,header,i_pes_header);
- //把ES数据写入PES域
-
- // for(i=0;i<i_pes_payload;i++)
- // *buffer++=*p_data++;
-
- memcpy(buffer+i_pes_header,p_data,i_pes_payload);
- // memcpy(p_pes->p_buffer+i_pes_header,p_data,i_pes_payload);
-
- //把PES数据写入TS文件中
- TSPARAMER *m_tspara;
- m_tspara = (TSPARAMER *)malloc( sizeof(TSPARAMER) );
- m_tspara->i_pid=i_stream_id;
- m_tspara->i_stream_id=i_stream_id;
- m_tspara->i_pes_length=p_pes->i_size=i_pes_payload;
- m_tspara->i_stream_type=VIDEO_ES;
- p_pes->p_buffer=buffer;
-
- hr=PESToTS(p_pes,m_tspara);
- if(FAILED(hr))
- AfxMessageBox("Failed Copy PES to Ts");
- i_size-=i_pes_payload;
- }
- while(i_size==0);
-
- return hr;
-
- }
-
- HRESULT ESToTS::PESToTS(PES_PARA *p_pes,TSPARAMER *p_stream)
- {
- uchar *p_data;
- int i_size;
- int b_new_pes;
-
- /* get PES total size */
- i_size = p_pes->i_size;
- p_data = p_pes->p_buffer;
-
- b_new_pes = 1;
-
- for( ;; )
- {
- int b_adaptation_field;
- int i_copy;
- TS_PARA *p_ts;
- int i_continuity_counter=0;
- p_ts=(TS_PARA*)malloc(sizeof(TS_PARA));
-
- i_copy = __MIN( i_size, 184 );
- b_adaptation_field = i_size < 184 ? 1 : 0;
-
- uchar buffer[188];
- buffer[0] = 0x47;
- buffer[1] = ( b_new_pes ? 0x40 : 0x00 )| ( ( p_stream->i_pid >> 8 )&0x1f );
- buffer[2] = p_stream->i_pid & 0xff;
- buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )| i_continuity_counter;
-
-
- //写入TS头标志
- // p_ts->p_buffer[0] = 0x47;
- // p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )| ( ( p_stream->i_pid >> 8 )&0x1f );
- // p_ts->p_buffer[2] = p_stream->i_pid & 0xff;
- // p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )| i_continuity_counter;
-
- b_new_pes = 0;
- i_continuity_counter = (i_continuity_counter+1)%16;
-
- if( b_adaptation_field )
- {
- int i_stuffing = 184 - i_copy;
- int i;
-
- // p_ts->p_buffer[4] = i_stuffing - 1;
- buffer[4] = i_stuffing - 1;
- if( i_stuffing > 1 )
- {
- // p_ts->p_buffer[5] = 0x00;
- buffer[5]=0x00;
- for( i = 6; i < 6 + i_stuffing - 2; i++ )
- {
- buffer[i]=0xff;
- // p_ts->p_buffer[i] = 0xff;
- }
- }
- }
- /* copy payload */
- // memcpy( p_ts->p_buffer+(188 - i_copy), p_data, i_copy );
- memcpy( buffer+(188 - i_copy), p_data, i_copy );
- p_ts->p_buffer=buffer;
- hr=WriteFile(p_ts);
- if(FAILED(hr))
- {
- AfxMessageBox("WriteFile Fasiled");
- return hr;
- }
-
-
- p_data += i_copy;
- i_size -= i_copy;
-
- if( i_size <= 0 )
- {
- break;
- }
- }
- return hr;
- }
-
- HRESULT ESToTS::WriteFile(TS_PARA *TsBuffer)
- {
- if(!m_bFileOpen)
- {
- if (!(fd = fopen("D:\\zzl.ts","w")))
- {
- AfxMessageBox("Couldn't open parameter file");
- return 0;
- }
- m_bFileOpen=true;
- }
- fwrite( TsBuffer->p_buffer, sizeof( char ), 188, fd );
- }
-
- HRESULT ESToTS::OpenFile( FILE * fd)
- {
- int fh, count, total = 0;
- char buf[2028];
- if( (fh = _open( "c:\\test1.m2v", _O_RDONLY )) == - 1 )
- {
- AfxMessageBox( "Open failed");
- exit( 1 );
- }
- /* Cycle until end of file reached: */
- do
- {
- /* Attempt to read in 10 bytes: */
- if( (count = _read( fh, buf, 2028 )) == -1 )
- {
- perror( "Read error" );
- break;
- }
- /* Total actual bytes read */
- hr=GetES((uchar *)buf,2028);
- if(FAILED (hr))
- AfxMessageBox("GetES Failed");
-
- total += count;
- }
- while( _eof( fh ) );
- _close( fh );
- return hr;
- }
|