home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- ConvAudioAndVideo.cpp
-
- 03/03/07 Xiaohong CreateFile é╠ê°Éöé≡ OPEN_ALWAYS é⌐éτ CREATE_ALWAYS é╔ò╧ìX
- 03/02/08 Xiaohong Mpeg1 Audio LayerI é╠ÅΩìçé╔ÅπÄΦé¡éóé⌐é╚éóé┼é╖
- *************************************************************************/
- #include "tompeg.h"
- #include "buffer.h"
- #include "inits.h"
- #include "timecode.h"
- #include "BitStreamStruct.h"
- #include <math.h>
- /*************************************************************************
- Definitionen
- *************************************************************************/
-
- typedef enum
- {
- STREAMS_VIDEO = 1,
- STREAMS_AUDIO,
- STREAMS_BOTH
- }STREAMTYPE;
-
- static const unsigned int bitrate_index [3][16] =
- {{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
- {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
- {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
-
- #define CLOCKS 90000.0 /* System Clock Hertz */
-
- #define LAST_SCR_BYTE_IN_PACK 9 /* No of bytes in pack */
- #define ISO11172_END 0x000001b9
- #define AUDIO_STR_0 0xc0 /* Marker Audio Stream0 */
- #define VIDEO_STR_0 0xe0 /* Marker Video Stream0 */
- #define BFRAME 3
-
- #define SEQUENCE_HEADER 0x000001b3
- #define SYNCWORD_START 0x000001
- #define SEQUENCE_END 0x000001b7
- #define PICTURE_START 0x00000100
- #define GROUP_START 0x000001b8
- #define AUDIO_SYNCWORD 0xfff
- #define SYS_HEADER_SIZE 18
- #define PACK_HEADER_SIZE 12
- #define PACKET_HEADER_SIZE 6
- #define AFTER_PACKET_LENGTH 15 /* No of non-data-bytes */
- #define TIMESTAMPS_NO 0 /* Flag NO timestamps */
- #define TIMESTAMPS_PTS 1 /* Flag PTS timestamp */
- #define TIMESTAMPS_PTS_DTS 2 /* Flag BOTH timestamps */
- #define PADDING_STR 0xbe /* Marker Padding Stream*/
- #define PACK_START 0x000001ba
- #define PACKET_START 0x000001
- #define STUFFING_BYTE 0xff
- #define MARKER_NO_TIMESTAMPS 0x0f /* Marker NO timestamps */
- #define MARKER_JUST_PTS 2 /* Marker only PTS */
- #define MARKER_SCR 2 /* Marker SCR */
- #define MARKER_PTS 3 /* Marker PTS */
- #define MARKER_DTS 1 /* Marker DTS */
- #define SYS_HEADER_START 0x000001bb
- #define SYS_HEADER_LENGTH 12 /* length of Sys Header */
- #define RESERVED_BYTE 0xff
-
- typedef struct pack_struc
- { unsigned char buf [PACK_HEADER_SIZE];
- Timecode_struc SCR;
- }Pack_struc;
-
- typedef struct sys_header_struc
- { unsigned char buf [SYS_HEADER_SIZE];
- }Sys_header_struc;
-
- static inline bool marker_bit(BitStreamStruct* bs,const unsigned int what)
- {
- if (what != bs->GetBit())
- {
- return false;
- }
- return true;
- }
-
- static inline void bcopy(unsigned char* source,unsigned char* dest,int k)
- {
- unsigned char *from, *to;
-
- from = source;
- to = dest;
-
- while(k!=0)
- {
- *to = *from;
- to++;
- from++;
- k--;
- }
- }
- /*************************************************************************
- Create_Sector
- erstellt einen gesamten Sektor.
- Kopiert in dem Sektorbuffer auch die eventuell vorhandenen
- Pack und Sys_Header Informationen und holt dann aus der
- Inputstreamdatei einen Packet voll von Daten, die im
- Sektorbuffer abgelegt werden.
-
- creates a complete sector.
- Also copies Pack and Sys_Header informations into the
- sector buffer, then reads a packet full of data from
- the input stream into the sector buffer.
- *************************************************************************/
- static inline void create_sector(Sector_struc* sector,Pack_struc* pack,Sys_header_struc* sys_header,
- unsigned int packet_size,HANDLE inputstream,unsigned char type,
- unsigned char buffer_scale,unsigned int buffer_size,bool buffers,
- Timecode_struc* PTS,Timecode_struc* DTS,unsigned char timestamps,unsigned int which_streams)
- {
- int i,j;
- unsigned char *index;
- unsigned char *size_offset;
- DWORD tmp;
- // FILE* file;
-
- index = sector->buf;
- sector->length_of_sector=0;
-
- /* soll ein Pack Header mit auf dem Sektor gespeichert werden? */
- /* Should we copy Pack Header information ? */
-
- if (pack != NULL)
- {
- i = sizeof(pack->buf);
- //memcpy(index,pack->buf,i);
- bcopy (pack->buf, index, i);
- index += i;
- sector->length_of_sector += i;
- }
-
- /* soll ein System Header mit auf dem Sektor gespeichert werden? */
- /* Should we copy System Header information ? */
-
- if (sys_header != NULL)
- {
- i = sizeof(sys_header->buf);
-
- /* only one stream? 3 bytes less in sys header */
- if (which_streams != STREAMS_BOTH)
- i -= 3;
-
- //memcpy(index,sys_header->buf,i);
- bcopy (sys_header->buf, index, i);
- index += i;
- sector->length_of_sector += i;
- }
-
- /* konstante Packet Headerwerte eintragen */
- /* write constant packet header data */
-
- *(index++) = (unsigned char)(PACKET_START)>>16;
- *(index++) = (unsigned char)(PACKET_START & 0x00ffff)>>8;
- *(index++) = (unsigned char)(PACKET_START & 0x0000ff);
- *(index++) = type;
-
- /* wir merken uns diese Position, falls sich an der Paketlaenge noch was tut */
- /* we remember this offset in case we will have to shrink this packet */
-
- size_offset = index;
- *(index++) = (unsigned char)((packet_size - PACKET_HEADER_SIZE)>>8);
- *(index++) = (unsigned char)((packet_size - PACKET_HEADER_SIZE)&0xff);
-
- *(index++) = STUFFING_BYTE;
- *(index++) = STUFFING_BYTE;
- *(index++) = STUFFING_BYTE;
-
- i = 0;
-
- if (!buffers)
- i +=2;
-
- if (timestamps == TIMESTAMPS_NO)
- i+=9;
- else if (timestamps == TIMESTAMPS_PTS)
- i+=5;
-
- for (j=0; j<i; j++)
- *(index++) = STUFFING_BYTE;
-
- /* soll Buffer Info angegeben werden ? */
- /* should we write buffer info ? */
-
- if (buffers)
- {
- *(index++) = (unsigned char) (0x40 |
- (buffer_scale << 5) | (buffer_size >> 8));
- *(index++) = (unsigned char) (buffer_size & 0xff);
- }
-
- /* PTS, PTS & DTS, oder gar nichts? */
- /* should we write PTS, PTS & DTS or nothing at all ? */
-
- switch (timestamps)
- {
- case TIMESTAMPS_NO:
- *(index++) = MARKER_NO_TIMESTAMPS;
- break;
- case TIMESTAMPS_PTS:
- PTS->buffer(MARKER_JUST_PTS, &index);
- sector->TS = *PTS;
- break;
- case TIMESTAMPS_PTS_DTS:
- PTS->buffer(MARKER_PTS, &index);
- DTS->buffer(MARKER_DTS, &index);
- sector->TS = *DTS;
- break;
- }
-
- /* Packet Daten eintragen */
- /* read in packet data */
-
- i = (packet_size - PACKET_HEADER_SIZE - AFTER_PACKET_LENGTH);
-
- if (type == PADDING_STR)
- {
- for (j=0; j<i; j++)
- *(index++)=(unsigned char) STUFFING_BYTE;
- tmp = i;
- }
- else
- {
- ReadFile(inputstream,index,sizeof(unsigned char)*i, &tmp, NULL);
- //tmp = fread (index, sizeof (unsigned char), i, inputstream);
- index += tmp;
-
- /* falls nicht genuegend Datenbytes, Paketlaenge verkuerzen */
- /* if we did not get enough data bytes, shorten the Packet length */
-
- if (tmp != (unsigned)i)
- {
- packet_size -= (i-tmp);
- *(size_offset++) = (unsigned char)((packet_size - PACKET_HEADER_SIZE)>>8);
- *(size_offset++) = (unsigned char)((packet_size - PACKET_HEADER_SIZE)&0xff);
- }
- }
-
-
- /* sonstige Strukturdaten eintragen */
- /* write other struct data */
-
- sector->length_of_sector += packet_size;
- sector->length_of_packet_data = tmp;
-
- }
-
- /*************************************************************************
- Create_Pack
- erstellt in einem Buffer die spezifischen Pack-Informationen.
- Diese werden dann spaeter von der Sector-Routine nochmals
- in dem Sektor kopiert.
-
- writes specifical pack header information into a buffer
- later this will be copied from the sector routine into
- the sector buffer
- *************************************************************************/
- static inline void create_pack(Pack_struc* pack,Timecode_struc* SCR,unsigned int mux_rate)
- {
- unsigned char *index;
-
- index = pack->buf;
-
- *(index++) = (unsigned char)((PACK_START)>>24);
- *(index++) = (unsigned char)((PACK_START & 0x00ff0000)>>16);
- *(index++) = (unsigned char)((PACK_START & 0x0000ff00)>>8);
- *(index++) = (unsigned char)(PACK_START & 0x000000ff);
- SCR->buffer(MARKER_SCR, &index);
- *(index++) = (unsigned char)(0x80 | (mux_rate >>15));
- *(index++) = (unsigned char)(0xff & (mux_rate >> 7));
- *(index++) = (unsigned char)(0x01 | ((mux_rate & 0x7f)<<1));
- pack->SCR = *SCR;
- }
-
-
- /*************************************************************************
- Create_Sys_Header
- erstelle in einem Buffer die spezifischen Sys_Header
- Informationen. Diese werden spaeter von der Sector-Routine
- nochmals zum Sectorbuffer kopiert.
-
- writes specifical system header information into a buffer
- later this will be copied from the sector routine into
- the sector buffer
- *************************************************************************/
- static inline void create_sys_header(Sys_header_struc* sys_header,unsigned int rate_bound,unsigned char audio_bound,
- unsigned char fixed,unsigned char CSPS,unsigned char audio_lock,unsigned char video_lock,
- unsigned char video_bound,
- unsigned char stream1,unsigned char buffer1_scale,unsigned int buffer1_size,
- unsigned char stream2,unsigned char buffer2_scale,unsigned int buffer2_size,
- unsigned int which_streams)
- {
- unsigned char *index;
-
- index = sys_header->buf;
-
- /* if we are not using both streams, we should clear some
- options here */
-
- //if (!(which_streams & STREAMS_AUDIO))
- //audio_bound = 0;
- //if (!(which_streams & STREAMS_VIDEO))
- //video_bound = 0;
-
- *(index++) = (unsigned char)((SYS_HEADER_START)>>24);
- *(index++) = (unsigned char)((SYS_HEADER_START & 0x00ff0000)>>16);
- *(index++) = (unsigned char)((SYS_HEADER_START & 0x0000ff00)>>8);
- *(index++) = (unsigned char)(SYS_HEADER_START & 0x000000ff);
-
- if (which_streams == STREAMS_BOTH)
- {
- *(index++) = (unsigned char)(SYS_HEADER_LENGTH >> 8);
- *(index++) = (unsigned char)(SYS_HEADER_LENGTH & 0xff);
- }
- else
- {
- *(index++) = (unsigned char)((SYS_HEADER_LENGTH-3) >> 8);
- *(index++) = (unsigned char)((SYS_HEADER_LENGTH-3) & 0xff);
- }
-
- *(index++) = (unsigned char)(0x80 | (rate_bound >>15));
- *(index++) = (unsigned char)(0xff & (rate_bound >> 7));
- *(index++) = (unsigned char)(0x01 | ((rate_bound & 0x7f)<<1));
- *(index++) = (unsigned char)((audio_bound << 2)|(fixed << 1)|CSPS);
- *(index++) = (unsigned char)((audio_lock << 7)|(video_lock << 6)|0x20|video_bound);
- *(index++) = (unsigned char)RESERVED_BYTE;
-
- if (which_streams & STREAMS_AUDIO)
- {
- *(index++) = stream1;
- *(index++) = (unsigned char) (0xc0 | (buffer1_scale << 5) | (buffer1_size >> 8));
- *(index++) = (unsigned char) (buffer1_size & 0xff);
- }
-
- if (which_streams & STREAMS_VIDEO)
- {
- *(index++) = stream2;
- *(index++) = (unsigned char) (0xc0 | (buffer2_scale << 5) | (buffer2_size >> 8));
- *(index++) = (unsigned char) (buffer2_size & 0xff);
- }
-
- }
-
- static inline TOMPGRET get_info_video(const char *video_file,
- char *video_units,
- Video_struc *video_info,
- double &startup_delay,
- unsigned int length,
- bool(* CallBack)(TOMPEG_PROCESS_PARAM,int))
- {
- static const double picture_rates [9] = { 0.0, 24000.0/1001.0, 24.0, 25.0,
- 30000.0/1001.0, 30.0, 50.0, 60000.0/1001.0, 60.0 };
- TOMPGRET ret = TR_ERR;
- HANDLE info_file = NULL;
- BitStreamStruct video_bs;
- unsigned int offset_bits=0;
- unsigned int stream_length=0;
- Vaunit_struc access_unit;
- unsigned long syncword;
- unsigned long decoding_order=0;
- unsigned long group_order=0;
- unsigned long temporal_reference=0;
- double secs_per_frame=0;
- unsigned short pict_rate;
- double DTS;
- double PTS;
- int i;
- unsigned int prozent;
- unsigned int old_prozent=0;
-
- if((info_file = CreateFile(video_units, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
- == INVALID_HANDLE_VALUE)
- {
- ret = TR_ERR_OPEN_FILE;
- goto END_OF_GET_INFO_VIDEO;
- }
- switch(video_bs.OpenBitStreamR(video_file, BUFFER_SIZE))
- {
- case BSSR_OK:
- break;
- case BSSR_OPEN_FILE_ERR:
- ret = TR_ERR_OPEN_FILE;
- goto END_OF_GET_INFO_VIDEO;
- break;
- case BSSR_ALLOC_BUFFER_ERR:
- ret = TR_ALLOC_BIT_STREAM_BUFFER_ERR;
- goto END_OF_GET_INFO_VIDEO;
- break;
- default:
- goto END_OF_GET_INFO_VIDEO;
- }
-
- if (video_bs.GetBitStream(32)==SEQUENCE_HEADER)
- {
- video_info->num_sequence++;
- video_info->horizontal_size = video_bs.GetBitStream(12);
- video_info->vertical_size = video_bs.GetBitStream(12);
- video_info->aspect_ratio = video_bs.GetBitStream(4);
- pict_rate = (unsigned short)video_bs.GetBitStream(4);
- video_info->picture_rate = pict_rate;
- video_info->bit_rate = video_bs.GetBitStream(18);
- if(!marker_bit (&video_bs, 1))
- goto END_OF_GET_INFO_VIDEO;
- video_info->vbv_buffer_size = video_bs.GetBitStream(10);
- video_info->CSPF = video_bs.GetBit();
- }
- else
- {
- goto END_OF_GET_INFO_VIDEO;
- }
-
- access_unit.empty();
- startup_delay = 2*MAX_FFFFFFFF;
-
- if (pict_rate >0 && pict_rate<9)
- secs_per_frame = 1.0 / picture_rates[pict_rate];
- else
- secs_per_frame = 1.0 / 25.0; /* invalid pict_rate info */
-
- do
- {
- if (video_bs.SeekSync(SYNCWORD_START, 24))
- {
- syncword = (SYNCWORD_START<<8) + video_bs.GetBitStream(8);
- switch (syncword)
- {
-
- case SEQUENCE_HEADER:
- video_info->num_sequence++;
- break;
-
- case GROUP_START:
- video_info->num_groups++;
- group_order=0;
- break;
-
- case PICTURE_START:
- /* skip access unit number 0 */
- if (access_unit.type != 0)
- {
- stream_length = video_bs.sstell()-32;
- access_unit.length = (stream_length - offset_bits)>>3;
- offset_bits = stream_length;
- access_unit.write_file(info_file);
- video_info->avg_frames[access_unit.type-1]+=
- access_unit.length;
- }
-
- temporal_reference = video_bs.GetBitStream(10);
- access_unit.type = video_bs.GetBitStream(3);
-
- DTS = decoding_order * secs_per_frame*CLOCKS;
- PTS = (temporal_reference - group_order + 1 + decoding_order) * secs_per_frame*CLOCKS;
-
- startup_delay=(PTS<startup_delay ? PTS : startup_delay);
-
- access_unit.DTS.make(DTS);
- access_unit.PTS.make(PTS);
- decoding_order++;
- group_order++;
-
- if ((access_unit.type>0) && (access_unit.type<5))
- video_info->num_frames[access_unit.type-1]++;
-
- prozent =(int) (((double)video_bs.sstell()/8.0/(double)length)*100.0);
- video_info->num_pictures++;
-
- if (prozent > old_prozent)
- {
- if(CallBack!=NULL)
- {
- if(!CallBack(TOMPEG_PROCESS_COMBINE,prozent/2))
- {
- ret = TR_CANCEL;
- goto END_OF_GET_INFO_VIDEO;
- }
- }
- old_prozent = prozent;
- }
-
- break;
-
- case SEQUENCE_END:
- stream_length = video_bs.sstell();
- access_unit.length = (stream_length - offset_bits)>>3;
- access_unit.write_file(info_file);
- video_info->avg_frames[access_unit.type-1]+=access_unit.length;
- offset_bits = stream_length;
- video_info->num_seq_end++;
- break;
-
- }
- }
- else
- break;
- } while (!video_bs.end_bs());
-
- video_info->stream_length = offset_bits >> 3;
- for (i=0; i<4; i++)
- if (video_info->num_frames[i]!=0)
- video_info->avg_frames[i] /= video_info->num_frames[i];
-
- if (secs_per_frame >0.0)
- video_info->comp_bit_rate = (unsigned int)ceil ((double)(video_info->stream_length)/
- (double)(video_info->num_pictures)/secs_per_frame/1250.)*25;
- else
- video_info->comp_bit_rate = 0;
-
- ret = TR_OK;
-
- END_OF_GET_INFO_VIDEO:
-
- video_bs.CloseBitStreamR();
- if(info_file!=NULL)
- CloseHandle(info_file);
-
- return ret;
- }
-
- static inline TOMPGRET get_info_audio(const char* audio_file,
- char* audio_units,
- Audio_struc* audio_info,
- double& startup_delay,
- unsigned int length,
- bool(* CallBack)(TOMPEG_PROCESS_PARAM,int))
- {
- static const double frequency [4] = {44.1, 48, 32, 0};
- static const unsigned int slots [4] = {12, 144, 0, 0};
- static const unsigned int samples [4] = {384, 1152, 0, 0};
-
- HANDLE info_file = NULL;
- TOMPGRET ret = TR_ERR;
-
- BitStreamStruct audio_bs;
- unsigned int offset_bits=0;
- unsigned int stream_length=0;
- unsigned int framesize;
- unsigned int padding_bit;
- unsigned int skip;
- unsigned int decoding_order=0;
- double PTS;
- double samples_per_second;
- Aaunit_struc access_unit;
- //unsigned long syncword;
- unsigned int i;
- unsigned int prozent;
- unsigned int old_prozent=0;
-
- if((info_file = CreateFile(audio_units, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
- == INVALID_HANDLE_VALUE)
- {
- ret = TR_ERR_OPEN_FILE;
- goto END_OF_GET_INFO_AUDIO;
- }
- switch(audio_bs.OpenBitStreamR(audio_file, BUFFER_SIZE))
- {
- case BSSR_OK:
- break;
- case BSSR_OPEN_FILE_ERR:
- ret = TR_ERR_OPEN_FILE;
- goto END_OF_GET_INFO_AUDIO;
- break;
- case BSSR_ALLOC_BUFFER_ERR:
- ret = TR_ALLOC_BIT_STREAM_BUFFER_ERR;
- goto END_OF_GET_INFO_AUDIO;
- default:
- goto END_OF_GET_INFO_AUDIO;
- }
-
-
- access_unit.empty();
-
- if (audio_bs.GetBitStream(12)==AUDIO_SYNCWORD)
- {
- if(!marker_bit (&audio_bs, 1))
- {
- goto END_OF_GET_INFO_AUDIO;
- }
- audio_info->num_syncword++;
- audio_info->layer = audio_bs.GetBitStream(2);
- audio_info->protection = audio_bs.GetBit();
- audio_info->bit_rate = audio_bs.GetBitStream(4);
- audio_info->frequency = audio_bs.GetBitStream(2);
- padding_bit = audio_bs.GetBit();
- audio_bs.GetBit();
- audio_info->mode = audio_bs.GetBitStream(2);
- audio_info->mode_extension = audio_bs.GetBitStream(2);
- audio_info->copyright = audio_bs.GetBit();
- audio_info->original_copy = audio_bs.GetBit();
- audio_info->emphasis = audio_bs.GetBitStream(2);
-
- framesize =
- (unsigned int)(bitrate_index[3-audio_info->layer][audio_info->bit_rate] /
- frequency[audio_info->frequency] * slots [3-audio_info->layer]);
- audio_info->size_frames[0] = framesize;
- audio_info->size_frames[1] = framesize+1;
-
- access_unit.length = audio_info->size_frames[padding_bit];
-
- samples_per_second = frequency [audio_info->frequency];
-
- PTS = ((double)(decoding_order * samples [3-audio_info->layer])) / samples_per_second * 90. + startup_delay;
-
- access_unit.PTS.make(PTS);
- decoding_order++;
-
- access_unit.write_file(info_file);
- audio_info->num_frames[padding_bit]++;
-
- }
- else
- {
- goto END_OF_GET_INFO_AUDIO;
- }
-
-
- do
- {
- skip=access_unit.length-4;
- if (skip & 0x1)
- audio_bs.GetBitStream(8);
- if (skip & 0x2)
- audio_bs.GetBitStream(16);
- skip=skip>>2;
-
- for (i=0;i<skip;i++)
- {
- audio_bs.GetBitStream(32);
- }
- offset_bits = audio_bs.sstell();
- if (audio_bs.GetBitStream(12)==AUDIO_SYNCWORD)
- {
- if(!marker_bit (&audio_bs, 1))
- {
- goto END_OF_GET_INFO_AUDIO;
- }
- prozent =(int) ((((double) audio_bs.sstell())/8.0/((double)length))*100.0);
- audio_info->num_syncword++;
- if (prozent > old_prozent)
- {
- if(CallBack!=NULL)
- {
- if(!CallBack(TOMPEG_PROCESS_COMBINE,prozent/2+50))
- {
- ret = TR_CANCEL;
- goto END_OF_GET_INFO_AUDIO;
- }
- }
- old_prozent = prozent;
- }
- audio_bs.GetBitStream(9);
-
- padding_bit=audio_bs.GetBit();
- access_unit.length = audio_info->size_frames[padding_bit];
-
- PTS = ((double)(decoding_order * samples [3-audio_info->layer])) / samples_per_second * 90. + startup_delay;
- access_unit.PTS.make(PTS);
-
- decoding_order++;
-
- access_unit.write_file(info_file);
- audio_info->num_frames[padding_bit]++;
-
- audio_bs.GetBitStream(9);
- }
- else
- break;
- } while (!audio_bs.end_bs());
-
- //printf ("\nDone, stream bit offset %ld.\n",offset_bits);
-
- audio_info->stream_length = offset_bits >> 3;
-
- ret = TR_OK;
-
- END_OF_GET_INFO_AUDIO:
-
- audio_bs.CloseBitStreamR();
-
- if(info_file!=NULL)
- CloseHandle(info_file);
-
- return ret;
- }
-
-
- static bool open_file(const char* name,unsigned int& bytes)
- {
- HANDLE hFile;
- if((hFile = CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
- == INVALID_HANDLE_VALUE)
- {
- return false;
- }
- bytes = (unsigned int)GetFileSize(hFile,NULL);
- CloseHandle(hFile);
-
- return true;
- }
-
- static inline bool check_files(const char* vfile,
- const char* afile,
- const char* mfile,
- unsigned int& audio_bytes,
- unsigned int& video_bytes,
- unsigned int& ptr_which_streams)
- {
-
- if (!open_file(vfile, video_bytes) || !open_file(afile, audio_bytes))
- return false;
-
- ptr_which_streams |= STREAMS_VIDEO;
- ptr_which_streams |= STREAMS_AUDIO;
-
- return true;
- }
-
- /******************************************************************
- Next_Video_Access_Unit
- holt aus dem TMP File, der die Info's ueber die Access
- Units enthaelt, die jetzt gueltige Info her. Nach
- dem Erstellen des letzten Packs sind naemlich eine
- bestimmte Anzahl Bytes und damit AU's eingelesen worden.
-
- gets information for the next access unit from the tmp
- file
- ******************************************************************/
-
- static bool next_video_access_unit(Buffer_struc* buffer,Vaunit_struc* video_au,
- unsigned int& bytes_left,
- HANDLE vunits_info,
- bool& picture_start,
- Timecode_struc* SCR_delay)
- {
-
- if (bytes_left == 0)
- return true;
-
- while (video_au->length < bytes_left)
- {
- if(!buffer->queue(video_au->length, &video_au->DTS))
- {
- return false;
- }
- bytes_left -= video_au->length;
- if (!video_au->read_file(vunits_info))
- {
- video_au->empty();
- return true;
- }
- picture_start = true;
- video_au->DTS = video_au->DTS + *SCR_delay;
- video_au->PTS = video_au->PTS + *SCR_delay;
- }
-
- if (video_au->length > bytes_left)
- {
- if(!buffer->queue(bytes_left, &video_au->DTS))
- {
- return false;
- }
- video_au->length -= bytes_left;
- picture_start = false;
- }
- else if (video_au->length == bytes_left)
- {
- if(!buffer->queue(bytes_left, &video_au->DTS))
- {
- return false;
- }
- if (!video_au->read_file(vunits_info))
- {
- video_au->empty();
- return true;
- }
- picture_start = true;
- video_au->DTS = video_au->DTS + *SCR_delay;
- video_au->PTS = video_au->PTS + *SCR_delay;
- }
- return true;
- }
-
-
- /******************************************************************
- Output_Video
- generiert Pack/Sys_Header/Packet Informationen aus dem
- Video Stream und speichert den so erhaltenen Sektor ab.
-
- generates Pack/Sys_Header/Packet information from the
- video stream and writes out the new sector
- ******************************************************************/
-
- static bool output_video (Timecode_struc* SCR,Timecode_struc* SCR_delay,
- HANDLE vunits_info,HANDLE istream_v,HANDLE ostream,
- Pack_struc* pack,Sys_header_struc* sys_header,Sector_struc* sector,Buffer_struc* buffer,Vaunit_struc* video_au,
- bool& picture_start,unsigned int& bytes_output,unsigned int mux_rate,
- unsigned long audio_buffer_size,unsigned long video_buffer_size,
- unsigned long packet_data_size,unsigned char marker_pack,unsigned int which_streams)
- {
-
- unsigned int bytes_left;
- unsigned int temp;
- Pack_struc *pack_ptr;
- Sys_header_struc *sys_header_ptr;
- unsigned char timestamps;
- DWORD dwResult;
-
-
- if (marker_pack)
- {
- create_pack (pack, SCR, mux_rate);
- create_sys_header (sys_header, mux_rate, 1, 1, 1, 1, 1, 1,
- AUDIO_STR_0, 0, audio_buffer_size/128,
- VIDEO_STR_0, 1, video_buffer_size/1024, which_streams );
- pack_ptr = pack;
- sys_header_ptr = sys_header;
- }
- else
- {
- pack_ptr = NULL;
- sys_header_ptr = NULL;
- }
-
- if (picture_start)
- {
- if (video_au->type == BFRAME)
- timestamps=TIMESTAMPS_PTS;
- else
- timestamps=TIMESTAMPS_PTS_DTS;
-
- create_sector (sector, pack_ptr, sys_header_ptr,
- packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
- istream_v, VIDEO_STR_0, 1, video_buffer_size/1024,
- true, &video_au->PTS, &video_au->DTS,
- timestamps, which_streams );
-
- bytes_left = sector->length_of_packet_data;
-
- if(!next_video_access_unit (buffer, video_au, bytes_left, vunits_info,
- picture_start, SCR_delay))
- {
- return false;
- }
-
- }
- else if (!(picture_start) && (video_au->length >= packet_data_size))
- {
- create_sector (sector, pack_ptr, sys_header_ptr,
- packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
- istream_v, VIDEO_STR_0, 1, video_buffer_size/1024,
- true, NULL, NULL,
- TIMESTAMPS_NO, which_streams );
-
- bytes_left = sector->length_of_packet_data;
-
- if(!next_video_access_unit (buffer, video_au, bytes_left, vunits_info,
- picture_start, SCR_delay))
- {
- return false;
- }
-
- }
- else if (!(picture_start) && (video_au->length < packet_data_size))
- {
- temp = video_au->length;
- if(!buffer->queue(video_au->length, &video_au->DTS))
- {
- return false;
- }
-
- /* gibt es ueberhaupt noch eine Access Unit ? */
- /* is there a new access unit anyway? */
-
- if (video_au->read_file(vunits_info))
- {
- if (video_au->type == BFRAME)
- timestamps=TIMESTAMPS_PTS;
- else
- timestamps=TIMESTAMPS_PTS_DTS;
-
- picture_start = true;
- video_au->DTS = video_au->DTS + *SCR_delay;
- video_au->PTS = video_au->PTS + *SCR_delay;
- create_sector (sector, pack_ptr, sys_header_ptr,
- packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
- istream_v, VIDEO_STR_0, 1, video_buffer_size/1024,
- true, &video_au->PTS, &video_au->DTS,
- timestamps, which_streams );
- bytes_left = sector->length_of_packet_data - temp;
-
- next_video_access_unit (buffer, video_au, bytes_left, vunits_info,
- picture_start, SCR_delay);
- }
- else
- {
- video_au->empty();
- create_sector (sector, pack_ptr, sys_header_ptr,
- packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
- istream_v, VIDEO_STR_0, 1, video_buffer_size/1024,
- true, NULL, NULL,
- TIMESTAMPS_NO, which_streams );
- }
- }
-
-
- /* Sector auf Platte schreiben */
- /* write out sector */
- WriteFile(ostream,sector->buf,sector->length_of_sector, &dwResult, NULL);
- //fwrite (sector->buf, sector->length_of_sector, 1, ostream);
- bytes_output += sector->length_of_sector;
-
- return true;
- }
-
-
- /******************************************************************
- Next_Audio_Access_Unit
- holt aus dem TMP File, der die Info's ueber die Access
- Units enthaelt, die jetzt gueltige Info her. Nach
- dem Erstellen des letzten Packs sind naemlich eine
- bestimmte Anzahl Bytes und damit AU's eingelesen worden.
-
- gets information on access unit from the tmp file
- ******************************************************************/
-
- static bool next_audio_access_unit(Buffer_struc* buffer,Aaunit_struc* audio_au,unsigned int& bytes_left,
- HANDLE aunits_info,bool& audio_frame_start,Timecode_struc* SCR_delay)
- {
-
- if (bytes_left == 0)
- return true;
-
- while (audio_au->length < bytes_left)
- {
- if(!buffer->queue(audio_au->length, &audio_au->PTS))
- {
- return false;
- }
- bytes_left -= audio_au->length;
- if (!audio_au->read_file(aunits_info))
- {
- audio_au->empty();
- return true;
- }
- audio_frame_start = true;
- audio_au->PTS = audio_au->PTS + *SCR_delay;
- }
-
- if (audio_au->length > bytes_left)
- {
- if(!buffer->queue(bytes_left, &audio_au->PTS))
- {
- return false;
- }
- audio_au->length -= bytes_left;
- audio_frame_start = false;
- }
- else if (audio_au->length == bytes_left)
- {
- if(!buffer->queue(bytes_left, &audio_au->PTS))
- {
- return false;
- }
- if (!audio_au->read_file(aunits_info))
- {
- audio_au->empty();
- return true;
- }
- audio_frame_start = true;
- audio_au->PTS = audio_au->PTS + *SCR_delay;
- }
- return true;
- }
-
- /******************************************************************
- Output_Audio
- erstellt Pack/Sys_Header/Packet Informationen aus dem
- Audio Stream und speichert den so erhaltenen Sector ab.
-
- generates Pack/Sys Header/Packet information from the
- audio stream and saves them into the sector
- ******************************************************************/
- static bool output_audio(Timecode_struc* SCR,Timecode_struc* SCR_delay,
- HANDLE aunits_info,HANDLE istream_a,HANDLE ostream,
- Pack_struc* pack,Sys_header_struc* sys_header,Sector_struc* sector,Buffer_struc* buffer,Aaunit_struc* audio_au,
- bool& audio_frame_start,unsigned int& bytes_output,unsigned int mux_rate,
- unsigned long audio_buffer_size,unsigned long video_buffer_size,
- unsigned long packet_data_size,unsigned char marker_pack,unsigned int which_streams)
- {
-
- unsigned int bytes_left;
- unsigned int temp;
- Pack_struc *pack_ptr;
- Sys_header_struc *sys_header_ptr;
- DWORD dwResult;
-
- if (marker_pack)
- {
- /* Wir generieren den Pack Header */
- /* let's generate pack header */
- create_pack (pack, SCR, mux_rate);
-
- /* Wir generieren den System Header */
- /* let's generate system header */
- create_sys_header (sys_header, mux_rate, 1, 1, 1, 1, 1, 1,
- AUDIO_STR_0, 0, audio_buffer_size/128,
- VIDEO_STR_0, 1, video_buffer_size/1024, which_streams );
- pack_ptr = pack;
- sys_header_ptr = sys_header;
- }
- else
- {
- pack_ptr = NULL;
- sys_header_ptr = NULL;
- }
-
- /* Wir generieren das Packet */
- /* Let's generate packet */
-
- /* faengt im Packet ein Audio Frame an? */
- /* does a audio frame start in this packet? */
-
- /* FALL: Packet beginnt mit neuer Access Unit */
- /* CASE: packet starts with new access unit */
- if (audio_frame_start)
- {
- create_sector (sector, pack_ptr, sys_header_ptr,
- packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
- istream_a, AUDIO_STR_0, 0, audio_buffer_size/128,
- true, &audio_au->PTS, NULL,
- TIMESTAMPS_PTS, which_streams);
-
- bytes_left = sector->length_of_packet_data;
-
- if(!next_audio_access_unit (buffer, audio_au, bytes_left, aunits_info,
- audio_frame_start, SCR_delay))
- {
- return false;
- }
- }
- else if (!(audio_frame_start) && (audio_au->length >= packet_data_size))
- {
- create_sector (sector, pack_ptr, sys_header_ptr,
- packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
- istream_a, AUDIO_STR_0, 0, audio_buffer_size/128,
- true, NULL, NULL,
- TIMESTAMPS_NO, which_streams );
-
- bytes_left = sector->length_of_packet_data;
-
- if(!next_audio_access_unit (buffer, audio_au, bytes_left, aunits_info,
- audio_frame_start, SCR_delay))
- {
- return false;
- }
- }
- else if (!(audio_frame_start) && (audio_au->length < packet_data_size))
- {
- temp = audio_au->length;
- if(!buffer->queue(audio_au->length, &audio_au->PTS))
- {
- return false;
- }
-
- /* gibt es ueberhaupt noch eine Access Unit ? */
- /* is there another access unit anyway ? */
-
- if (audio_au->read_file(aunits_info))
- {
- audio_frame_start = true;
- audio_au->PTS = audio_au->PTS + *SCR_delay;
- create_sector (sector, pack_ptr, sys_header_ptr,
- packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
- istream_a, AUDIO_STR_0, 0, audio_buffer_size/128,
- true, &audio_au->PTS, NULL,
- TIMESTAMPS_PTS, which_streams );
-
- bytes_left = sector->length_of_packet_data - temp;
-
- if(!next_audio_access_unit (buffer, audio_au, bytes_left, aunits_info,
- audio_frame_start, SCR_delay))
- {
- return false;
- }
- }
- else
- {
- audio_au->empty();
- create_sector (sector, pack_ptr, sys_header_ptr,
- packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
- istream_a, AUDIO_STR_0, 0, audio_buffer_size/128,
- true, NULL, NULL,
- TIMESTAMPS_NO, which_streams );
- }
- }
-
- /* Sector auf Platte schreiben */
- /* write out sector onto disk */
- WriteFile(ostream,sector->buf,sector->length_of_sector, &dwResult, NULL);
- // fwrite (sector->buf, sector->length_of_sector, 1, ostream);
- bytes_output += sector->length_of_sector;
-
- return true;
-
- }
-
- /******************************************************************
- Output_Padding
- erstellt Pack/Sys_Header/Packet Informationen zu einem
- Padding-Stream und speichert den so erhaltenen Sector ab.
-
- generates Pack/Sys Header/Packet information for a
- padding stream and saves the sector
- ******************************************************************/
- static inline void output_padding (Timecode_struc* SCR,HANDLE ostream,
- Pack_struc* pack,Sys_header_struc* sys_header,Sector_struc* sector,
- unsigned int* bytes_output,unsigned int mux_rate,
- unsigned long audio_buffer_size,unsigned long video_buffer_size,unsigned long packet_data_size,
- unsigned char marker_pack,unsigned int which_streams)
- {
- //unsigned int bytes_left;
- //unsigned int temp;
- Pack_struc *pack_ptr;
- Sys_header_struc *sys_header_ptr;
- DWORD dwResult;
-
- if (marker_pack)
- {
- /* Wir generieren den Pack Header */
- /* let's generate the pack header */
- create_pack (pack, SCR, mux_rate);
-
- /* Wir generieren den System Header */
- /* let's generate the system header */
- create_sys_header (sys_header, mux_rate, 1, 1, 1, 1, 1, 1,
- AUDIO_STR_0, 0, audio_buffer_size/128,
- VIDEO_STR_0, 1, video_buffer_size/1024, which_streams );
- pack_ptr = pack;
- sys_header_ptr = sys_header;
- }
- else
- {
- pack_ptr = NULL;
- sys_header_ptr = NULL;
- }
-
- /* Wir generieren das Packet */
- /* let's generate the packet */
- create_sector (sector, pack_ptr, sys_header_ptr,
- packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
- NULL, PADDING_STR, 0, 0,
- false, NULL, NULL,
- TIMESTAMPS_NO, which_streams );
-
- WriteFile(ostream,sector->buf,sector->length_of_sector, &dwResult, NULL);
- // fwrite (sector->buf, sector->length_of_sector*sizeof (unsigned char), 1,
- // ostream);
- *bytes_output += sector->length_of_sector;
-
- }
-
- static inline TOMPGRET outputstream (const char* video_file,char* video_units,Video_struc* video_info,
- const char* audio_file,char* audio_units,Audio_struc* audio_info,
- const char* multi_file,unsigned int which_streams)
- {
- HANDLE istream_v = NULL; /* Inputstream Video */
- HANDLE istream_a = NULL; /* Inputstream Audio */
- HANDLE ostream = NULL; /* Outputstream MPEG */
- HANDLE vunits_info = NULL; /* Input Video Units */
- HANDLE aunits_info = NULL; /* Input Audio Units */
- TOMPGRET ret = TR_ERR;
-
- Vaunit_struc video_au; /* Video Access Unit */
- Aaunit_struc audio_au; /* Audio Access Unit */
-
- unsigned int data_rate=0; /* AudioVideo Byterate */
- unsigned int video_rate=0;
- unsigned int audio_rate=0;
- double delay,audio_delay,video_delay;
- double clock_cycles;
- double audio_next_clock_cycles;
- double video_next_clock_cycles;
- unsigned int bytes_output;
- double dmux_rate;
- unsigned long sectors_delay,video_delay_ms,audio_delay_ms;
- unsigned int mux_rate;
- bool picture_start;
- bool audio_frame_start;
- //unsigned int bytes_left;
- unsigned int audio_bytes;
- unsigned int video_bytes;
- DWORD dwResult;
-
- unsigned int nsec_a=0;
- unsigned int nsec_v=0;
- unsigned int nsec_p=0;
-
- unsigned char* index;
-
- Timecode_struc SCR_audio_delay;
- Timecode_struc SCR_video_delay;
- Timecode_struc current_SCR;
- Timecode_struc audio_next_SCR;
- Timecode_struc video_next_SCR;
-
- Buffer_struc video_buffer;
- Buffer_struc audio_buffer;
-
- Pack_struc pack;
- Sys_header_struc sys_header;
- Sector_struc sector;
-
- unsigned long sector_size;
- unsigned long min_packet_data;
- unsigned long max_packet_data;
- unsigned long packets_per_pack;
- unsigned long audio_buffer_size;
- unsigned long video_buffer_size;
-
- unsigned long write_pack;
- bool marker_pack;
- unsigned long packet_data_size;
- int total_length;
-
- /* Oeffne alle Ein- und Ausgabefiles */
- /* Open in- and outputstream */
-
- if (which_streams & STREAMS_VIDEO)
- {
- if((istream_v = CreateFile(video_file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
- == INVALID_HANDLE_VALUE)
- {
- ret = TR_ERR_OPEN_FILE;
- goto END_OUTPUT_STREAM;
- }
- if((vunits_info = CreateFile(video_units, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE|FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
- == INVALID_HANDLE_VALUE)
- {
- ret = TR_ERR_OPEN_FILE;
- goto END_OUTPUT_STREAM;
- }
- }
- if (which_streams & STREAMS_AUDIO)
- {
- if((istream_a = CreateFile(audio_file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
- == INVALID_HANDLE_VALUE)
- {
- ret = TR_ERR_OPEN_FILE;
- goto END_OUTPUT_STREAM;
- }
- if((aunits_info = CreateFile(audio_units, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE|FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
- == INVALID_HANDLE_VALUE)
- {
- ret = TR_ERR_OPEN_FILE;
- goto END_OUTPUT_STREAM;
- }
- }
- if((ostream = CreateFile(multi_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
- == INVALID_HANDLE_VALUE)
- {
- ret = TR_ERR_OPEN_FILE;
- goto END_OUTPUT_STREAM;
- }
-
- /* Einlesen erster Access Unit Informationen */
- /* read in first access unit information */
-
- picture_start = false;
- audio_frame_start = false;
- video_au.empty();
- audio_au.empty();
-
- if (which_streams & STREAMS_AUDIO)
- {
- audio_au.read_file(aunits_info);
- audio_frame_start = true;
- }
- if (which_streams & STREAMS_VIDEO)
- {
- video_au.read_file(vunits_info);
- picture_start = true;
- }
-
- sector_size = 2048;
-
- packets_per_pack = 1;
-
- video_buffer_size = 40;
-
- audio_buffer_size = 4;
-
- write_pack = packets_per_pack;
- video_buffer_size *= 1024;
- audio_buffer_size *= 1024;
- min_packet_data = sector_size - PACK_HEADER_SIZE - SYS_HEADER_SIZE -
- PACKET_HEADER_SIZE - AFTER_PACKET_LENGTH;
- max_packet_data = sector_size - PACKET_HEADER_SIZE - AFTER_PACKET_LENGTH;
-
- if (which_streams != STREAMS_BOTH)
- {
- min_packet_data += 3;
- }
-
-
- init_buffer_struc (&video_buffer,video_buffer_size);
- init_buffer_struc (&audio_buffer,audio_buffer_size);
-
- if (which_streams & STREAMS_VIDEO)
- {
- if (video_info->bit_rate > video_info->comp_bit_rate)
- video_rate = video_info->bit_rate * 50;
- else
- video_rate = video_info->comp_bit_rate * 50;
- }
- if (which_streams & STREAMS_AUDIO)
- audio_rate = bitrate_index[3-audio_info->layer][audio_info->bit_rate]*128;
-
- data_rate = video_rate + audio_rate;
-
- dmux_rate = ceil((double)(data_rate) *
- ((double)(sector_size)/(double)(min_packet_data) +
- ((double)(sector_size)/(double)(max_packet_data) *
- (double)(packets_per_pack-1.))) / (double)(packets_per_pack) );
- data_rate = (unsigned int)ceil(dmux_rate/50.)*50;
-
- sectors_delay = 8;
-
- video_delay_ms = 0;
-
- audio_delay_ms = 0;
-
- video_delay = (double)video_delay_ms*(double)(CLOCKS/1000);
- audio_delay = (double)audio_delay_ms*(double)(CLOCKS/1000);
-
- mux_rate = (unsigned int)ceil(dmux_rate/50.);
-
- dmux_rate= mux_rate * 50.;
-
- delay = ((double)sectors_delay +
- ceil((double)video_au.length/(double)min_packet_data) +
- ceil((double)audio_au.length/(double)min_packet_data )) *
- (double)sector_size/dmux_rate*(double)CLOCKS;
-
- audio_delay += delay;
- video_delay += delay;
-
- SCR_audio_delay.make(audio_delay);
- SCR_video_delay.make(video_delay);
-
- video_au.DTS = video_au.DTS + SCR_video_delay;
- video_au.PTS = video_au.PTS + SCR_video_delay;
- audio_au.PTS = audio_au.PTS + SCR_audio_delay;
-
- bytes_output = 0;
-
- total_length = video_au.length + audio_au.length;
-
- while ((video_au.length + audio_au.length) > 0)
- {
- if (write_pack-- == packets_per_pack)
- {
- marker_pack = true;
- packet_data_size = min_packet_data;
- }
- else
- {
- marker_pack = false;
- packet_data_size = max_packet_data;
- }
-
- if(write_pack == 0)
- write_pack = packets_per_pack;
-
- audio_bytes = (audio_au.length/min_packet_data)*sector_size + (audio_au.length%min_packet_data)+(sector_size-min_packet_data);
- video_bytes = (video_au.length/min_packet_data)*sector_size + (video_au.length%min_packet_data)+(sector_size-min_packet_data);
-
- clock_cycles = (double)(bytes_output+LAST_SCR_BYTE_IN_PACK)*CLOCKS/dmux_rate;
-
- audio_next_clock_cycles = (double)(bytes_output+sector_size+audio_bytes)/dmux_rate*CLOCKS;
- video_next_clock_cycles = (double)(bytes_output+sector_size+video_bytes)/dmux_rate*CLOCKS;
-
- current_SCR.make(clock_cycles);
- audio_next_SCR.make(audio_next_clock_cycles);
- video_next_SCR.make(video_next_clock_cycles);
-
- if (which_streams & STREAMS_AUDIO)
- audio_buffer.clean(¤t_SCR);
- if (which_streams & STREAMS_VIDEO)
- video_buffer.clean(¤t_SCR);
-
- if ( (video_buffer.space() >= packet_data_size)
- && (video_au.length>0)
- && ((comp_timecode(&audio_next_SCR, &audio_au.PTS)) ||
- (audio_au.length==0) ))
- {
- if(!output_video(¤t_SCR, &SCR_video_delay, vunits_info,
- istream_v, ostream, &pack, &sys_header, §or,
- &video_buffer, &video_au, picture_start,
- bytes_output, mux_rate, audio_buffer_size, video_buffer_size,
- packet_data_size, marker_pack, which_streams))
- {
- ret = TR_OUTPUT_VIDRO_ERR;
- goto END_OUTPUT_STREAM;
- }
- }
- else if ( (audio_buffer.space() >= packet_data_size)
- && (audio_au.length>0)
- && ((comp_timecode (&video_next_SCR, &video_au.DTS)) ||
- (video_au.length==0) ))
- {
- output_audio (¤t_SCR, &SCR_audio_delay, aunits_info,
- istream_a, ostream, &pack, &sys_header, §or,
- &audio_buffer, &audio_au, audio_frame_start,
- bytes_output, mux_rate, audio_buffer_size, video_buffer_size,
- packet_data_size, marker_pack, which_streams);
- }
- else if ( (audio_buffer.space() >= packet_data_size)
- && (audio_au.length>0)
- &! comp_timecode (&audio_next_SCR, &audio_au.PTS))
- {
- output_audio(¤t_SCR, &SCR_audio_delay, aunits_info,
- istream_a, ostream, &pack, &sys_header, §or,
- &audio_buffer, &audio_au, audio_frame_start,
- bytes_output, mux_rate, audio_buffer_size, video_buffer_size,
- packet_data_size, marker_pack, which_streams);
- }
- else if ( (video_buffer.space() >= packet_data_size)
- && (video_au.length>0)
- &! comp_timecode (&video_next_SCR, &video_au.DTS))
- {
- if(!output_video(¤t_SCR, &SCR_video_delay, vunits_info,
- istream_v, ostream, &pack, &sys_header, §or,
- &video_buffer, &video_au, picture_start,
- bytes_output, mux_rate, audio_buffer_size, video_buffer_size,
- packet_data_size, marker_pack, which_streams))
- {
- ret = TR_OUTPUT_VIDRO_ERR;
- goto END_OUTPUT_STREAM;
- }
- }
- else
- {
- output_padding(¤t_SCR, ostream, &pack, &sys_header,
- §or, &bytes_output, mux_rate, audio_buffer_size,
- video_buffer_size,packet_data_size, marker_pack, which_streams);
-
- }
- }
-
-
- /* ISO 11172 END CODE schreiben */
- /* write out ISO 11172 END CODE */
- index = sector.buf;
-
- *(index++) = (unsigned char)((ISO11172_END)>>24);
- *(index++) = (unsigned char)((ISO11172_END & 0x00ff0000)>>16);
- *(index++) = (unsigned char)((ISO11172_END & 0x0000ff00)>>8);
- *(index++) = (unsigned char)(ISO11172_END & 0x000000ff);
-
- WriteFile(ostream,sector.buf,4, &dwResult, NULL);
- //fwrite (sector.buf, sizeof (unsigned char), 4, ostream);
- bytes_output += 4;
-
- ret = TR_OK;
- END_OUTPUT_STREAM:
-
- if(ostream!=NULL)
- CloseHandle(ostream);
- if(aunits_info!=NULL)
- CloseHandle(aunits_info);
- if(vunits_info!=NULL)
- CloseHandle(vunits_info);
- if(istream_a!=NULL)
- CloseHandle(istream_a);
- if(istream_v!=NULL)
- CloseHandle(istream_v);
-
-
- //if (which_streams & STREAMS_VIDEO) unlink (video_units);
- //if (which_streams & STREAMS_AUDIO) unlink (audio_units);
-
- return ret;
- }
-
- EXPORT TOMPGRET CALLBACK TOMPEG_ConvAudioAndVideo(const char *vfile,
- const char *afile,
- const char *mfile,
- bool(* CallBack)(TOMPEG_PROCESS_PARAM,int))
- {
- char video_units[260];
- char audio_units[260];
- char tmp_file_path[260];
-
- Video_struc video_info;
- Audio_struc audio_info;
- unsigned int audio_bytes, video_bytes;
- unsigned int which_streams = STREAMS_BOTH;
- double startup_delay = 0;
- TOMPGRET ret;
-
- if(!check_files(vfile, afile, mfile,
- audio_bytes, video_bytes, which_streams))
- {
- return TR_CHECK_FILE_ERR;
- }
-
- empty_video_struc (&video_info);
- empty_audio_struc (&audio_info);
-
- // êΩÄ₧âtâ@âCâïé≡ì∞ɼé╖éΘâpâXé≡ĵô╛é╖éΘ
- GetTempPath(sizeof(tmp_file_path),tmp_file_path);
-
- if (which_streams & STREAMS_VIDEO)
- {
- GetTempFileName(tmp_file_path,"tpv",0,video_units);
- //video_units=tempnam ("./","tmp_v");
- // ê╚æOé╠êΩÄ₧âtâ@âCâïé═ìφÅ£é╡é─é¿é¡
- DeleteFile(video_units);
- if((ret = get_info_video (vfile, video_units, &video_info, startup_delay,
- video_bytes,CallBack))!=TR_OK)
- {
- return ret;
- }
- }
-
- if (which_streams & STREAMS_AUDIO)
- {
- GetTempFileName(tmp_file_path,"tpa",0,audio_units);
- //audio_units=tempnam ("./","tmp_a");
- // ê╚æOé╠êΩÄ₧âtâ@âCâïé═ìφÅ£é╡é─é¿é¡
- DeleteFile(audio_units);
- if((ret = get_info_audio (afile, audio_units, &audio_info, startup_delay,
- audio_bytes,CallBack))!=TR_OK)
- {
- return ret;
- }
- }
-
- if((ret = outputstream(vfile, video_units, &video_info, afile, audio_units, &audio_info, mfile, which_streams))!=TR_OK)
- {
- return ret;
- }
-
- if(which_streams & STREAMS_VIDEO)
- DeleteFile(video_units);
-
- if(which_streams & STREAMS_AUDIO)
- DeleteFile(audio_units);
-
- return TR_OK;
- }
-
-
-