home *** CD-ROM | disk | FTP | other *** search
/ Netrunner 2004 October / NETRUNNER0410.ISO / regular / dctm.lzh / DCTM / source.lzh / source / ConvAudioAndVideo.Cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2003-03-08  |  45.7 KB  |  1,556 lines

  1. /*************************************************************************
  2.     ConvAudioAndVideo.cpp
  3.  
  4.     03/03/07    Xiaohong    CreateFile é╠ê°Éöé≡ OPEN_ALWAYS é⌐éτ CREATE_ALWAYS é╔ò╧ìX
  5.     03/02/08    Xiaohong    Mpeg1 Audio LayerI é╠ÅΩìçé╔ÅπÄΦé¡éóé⌐é╚éóé┼é╖
  6. *************************************************************************/
  7. #include "tompeg.h"
  8. #include "buffer.h"
  9. #include "inits.h"
  10. #include "timecode.h"
  11. #include "BitStreamStruct.h"
  12. #include <math.h>
  13. /*************************************************************************
  14.     Definitionen
  15. *************************************************************************/
  16.  
  17. typedef enum
  18. {
  19.     STREAMS_VIDEO = 1,
  20.     STREAMS_AUDIO,
  21.     STREAMS_BOTH
  22. }STREAMTYPE;
  23.  
  24. static const unsigned int bitrate_index [3][16] =
  25.     {{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
  26.      {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
  27.      {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
  28.  
  29. #define CLOCKS                90000.0        /* System Clock Hertz    */
  30.  
  31. #define LAST_SCR_BYTE_IN_PACK    9            /* No of bytes in pack    */
  32. #define ISO11172_END            0x000001b9
  33. #define AUDIO_STR_0                0xc0        /* Marker Audio Stream0    */
  34. #define VIDEO_STR_0                0xe0        /* Marker Video Stream0    */
  35. #define BFRAME                  3
  36.  
  37. #define SEQUENCE_HEADER     0x000001b3
  38. #define SYNCWORD_START        0x000001
  39. #define SEQUENCE_END        0x000001b7
  40. #define PICTURE_START        0x00000100
  41. #define GROUP_START            0x000001b8
  42. #define AUDIO_SYNCWORD        0xfff
  43. #define SYS_HEADER_SIZE            18
  44. #define PACK_HEADER_SIZE        12
  45. #define PACKET_HEADER_SIZE        6
  46. #define AFTER_PACKET_LENGTH        15        /* No of non-data-bytes    */
  47. #define TIMESTAMPS_NO            0        /* Flag NO timestamps    */
  48. #define TIMESTAMPS_PTS            1        /* Flag PTS timestamp    */
  49. #define TIMESTAMPS_PTS_DTS        2        /* Flag BOTH timestamps    */
  50. #define PADDING_STR                0xbe        /* Marker Padding Stream*/
  51. #define PACK_START                0x000001ba
  52. #define PACKET_START            0x000001
  53. #define STUFFING_BYTE            0xff
  54. #define MARKER_NO_TIMESTAMPS    0x0f        /* Marker NO timestamps    */
  55. #define MARKER_JUST_PTS            2        /* Marker only PTS    */
  56. #define MARKER_SCR                2        /* Marker SCR        */
  57. #define MARKER_PTS                3        /* Marker PTS        */
  58. #define MARKER_DTS                1        /* Marker DTS        */
  59. #define SYS_HEADER_START        0x000001bb
  60. #define SYS_HEADER_LENGTH        12        /* length of Sys Header    */
  61. #define RESERVED_BYTE            0xff
  62.  
  63. typedef struct pack_struc
  64. {   unsigned char  buf [PACK_HEADER_SIZE];
  65.     Timecode_struc SCR;
  66. }Pack_struc;
  67.  
  68. typedef struct sys_header_struc
  69. {   unsigned char  buf [SYS_HEADER_SIZE];
  70. }Sys_header_struc;
  71.  
  72. static inline bool marker_bit(BitStreamStruct* bs,const unsigned int what)
  73. {
  74.     if (what != bs->GetBit())
  75.     {
  76.         return false;
  77.     }
  78.     return true;
  79. }
  80.  
  81. static inline void bcopy(unsigned char* source,unsigned char* dest,int k)
  82. {
  83.     unsigned char *from, *to;
  84.  
  85.     from = source;
  86.     to = dest;
  87.  
  88.     while(k!=0)
  89.     {
  90.         *to = *from;
  91.         to++;
  92.         from++;
  93.         k--;
  94.     }
  95. }
  96. /*************************************************************************
  97.     Create_Sector
  98.     erstellt einen gesamten Sektor.
  99.     Kopiert in dem Sektorbuffer auch die eventuell vorhandenen
  100.     Pack und Sys_Header Informationen und holt dann aus der
  101.     Inputstreamdatei einen Packet voll von Daten, die im
  102.     Sektorbuffer abgelegt werden.
  103.  
  104.     creates a complete sector.
  105.     Also copies Pack and Sys_Header informations into the
  106.     sector buffer, then reads a packet full of data from
  107.     the input stream into the sector buffer.
  108. *************************************************************************/
  109. static inline void create_sector(Sector_struc* sector,Pack_struc* pack,Sys_header_struc* sys_header,
  110.             unsigned int packet_size,HANDLE inputstream,unsigned char type, 
  111.             unsigned char buffer_scale,unsigned int buffer_size,bool buffers,
  112.             Timecode_struc* PTS,Timecode_struc* DTS,unsigned char timestamps,unsigned int which_streams)
  113. {
  114.     int i,j;
  115.     unsigned char *index;
  116.     unsigned char *size_offset;
  117.     DWORD tmp;
  118.     // FILE* file;
  119.  
  120.     index = sector->buf;
  121.     sector->length_of_sector=0;
  122.  
  123.     /* soll ein Pack Header mit auf dem Sektor gespeichert werden? */
  124.     /* Should we copy Pack Header information ? */
  125.  
  126.     if (pack != NULL)
  127.     {
  128.         i = sizeof(pack->buf);
  129.         //memcpy(index,pack->buf,i);
  130.         bcopy (pack->buf, index, i);
  131.         index += i;
  132.         sector->length_of_sector += i;
  133.     }
  134.  
  135.     /* soll ein System Header mit auf dem Sektor gespeichert werden? */
  136.     /* Should we copy System Header information ? */
  137.  
  138.     if (sys_header != NULL)
  139.     {
  140.         i = sizeof(sys_header->buf);
  141.  
  142.         /* only one stream? 3 bytes less in sys header */
  143.         if (which_streams != STREAMS_BOTH)
  144.             i -= 3;
  145.  
  146.         //memcpy(index,sys_header->buf,i);
  147.         bcopy (sys_header->buf, index, i);
  148.         index += i;
  149.         sector->length_of_sector += i;
  150.     }
  151.  
  152.     /* konstante Packet Headerwerte eintragen */
  153.     /* write constant packet header data */
  154.  
  155.     *(index++) = (unsigned char)(PACKET_START)>>16;
  156.     *(index++) = (unsigned char)(PACKET_START & 0x00ffff)>>8;
  157.     *(index++) = (unsigned char)(PACKET_START & 0x0000ff);
  158.     *(index++) = type;    
  159.  
  160.     /* wir merken uns diese Position, falls sich an der Paketlaenge noch was tut */
  161.     /* we remember this offset in case we will have to shrink this packet */
  162.     
  163.     size_offset = index;
  164.     *(index++) = (unsigned char)((packet_size - PACKET_HEADER_SIZE)>>8);
  165.     *(index++) = (unsigned char)((packet_size - PACKET_HEADER_SIZE)&0xff);
  166.  
  167.     *(index++) = STUFFING_BYTE;
  168.     *(index++) = STUFFING_BYTE;
  169.     *(index++) = STUFFING_BYTE;
  170.  
  171.     i = 0;
  172.  
  173.     if (!buffers)
  174.         i +=2;
  175.  
  176.     if (timestamps == TIMESTAMPS_NO)
  177.         i+=9;
  178.     else if (timestamps == TIMESTAMPS_PTS)
  179.         i+=5;
  180.  
  181.     for (j=0; j<i; j++)
  182.         *(index++) = STUFFING_BYTE;
  183.  
  184.     /* soll Buffer Info angegeben werden ? */
  185.     /* should we write buffer info ? */
  186.  
  187.     if (buffers)
  188.     {
  189.         *(index++) = (unsigned char) (0x40 |
  190.                 (buffer_scale << 5) | (buffer_size >> 8));
  191.         *(index++) = (unsigned char) (buffer_size & 0xff);
  192.     }
  193.  
  194.     /* PTS, PTS & DTS, oder gar nichts? */
  195.     /* should we write PTS, PTS & DTS or nothing at all ? */
  196.  
  197.     switch (timestamps)
  198.     {
  199.     case TIMESTAMPS_NO:
  200.         *(index++) = MARKER_NO_TIMESTAMPS;
  201.         break;
  202.     case TIMESTAMPS_PTS:
  203.         PTS->buffer(MARKER_JUST_PTS, &index);
  204.         sector->TS = *PTS;
  205.         break;
  206.     case TIMESTAMPS_PTS_DTS:
  207.         PTS->buffer(MARKER_PTS, &index);
  208.         DTS->buffer(MARKER_DTS, &index);
  209.         sector->TS = *DTS;
  210.         break;
  211.     }
  212.  
  213.     /* Packet Daten eintragen */
  214.     /* read in packet data */
  215.     
  216.     i = (packet_size - PACKET_HEADER_SIZE - AFTER_PACKET_LENGTH);
  217.  
  218.     if (type == PADDING_STR)
  219.     {
  220.         for (j=0; j<i; j++)
  221.             *(index++)=(unsigned char) STUFFING_BYTE;
  222.         tmp = i;
  223.     } 
  224.     else
  225.     {   
  226.         ReadFile(inputstream,index,sizeof(unsigned char)*i, &tmp, NULL);
  227.         //tmp = fread (index, sizeof (unsigned char), i, inputstream);
  228.         index += tmp;
  229.  
  230.         /* falls nicht genuegend Datenbytes, Paketlaenge verkuerzen */
  231.         /* if we did not get enough data bytes, shorten the Packet length */
  232.  
  233.         if (tmp != (unsigned)i)
  234.         {   
  235.             packet_size -= (i-tmp);
  236.             *(size_offset++) = (unsigned char)((packet_size - PACKET_HEADER_SIZE)>>8);
  237.             *(size_offset++) = (unsigned char)((packet_size - PACKET_HEADER_SIZE)&0xff);
  238.         }
  239.     }
  240.  
  241.  
  242.     /* sonstige Strukturdaten eintragen */
  243.     /* write other struct data */
  244.  
  245.     sector->length_of_sector += packet_size;
  246.     sector->length_of_packet_data = tmp;
  247.     
  248. }
  249.  
  250. /*************************************************************************
  251.     Create_Pack
  252.     erstellt in einem Buffer die spezifischen Pack-Informationen.
  253.     Diese werden dann spaeter von der Sector-Routine nochmals
  254.     in dem Sektor kopiert.
  255.  
  256.     writes specifical pack header information into a buffer
  257.     later this will be copied from the sector routine into
  258.     the sector buffer
  259. *************************************************************************/
  260. static inline void create_pack(Pack_struc* pack,Timecode_struc* SCR,unsigned int mux_rate)
  261. {
  262.     unsigned char *index;
  263.  
  264.     index = pack->buf;
  265.  
  266.     *(index++) = (unsigned char)((PACK_START)>>24);
  267.     *(index++) = (unsigned char)((PACK_START & 0x00ff0000)>>16);
  268.     *(index++) = (unsigned char)((PACK_START & 0x0000ff00)>>8);
  269.     *(index++) = (unsigned char)(PACK_START & 0x000000ff);
  270.     SCR->buffer(MARKER_SCR, &index);
  271.     *(index++) = (unsigned char)(0x80 | (mux_rate >>15));
  272.     *(index++) = (unsigned char)(0xff & (mux_rate >> 7));
  273.     *(index++) = (unsigned char)(0x01 | ((mux_rate & 0x7f)<<1));
  274.     pack->SCR = *SCR;
  275. }
  276.  
  277.  
  278. /*************************************************************************
  279.     Create_Sys_Header
  280.     erstelle in einem Buffer die spezifischen Sys_Header
  281.     Informationen. Diese werden spaeter von der Sector-Routine
  282.     nochmals zum Sectorbuffer kopiert.
  283.  
  284.     writes specifical system header information into a buffer
  285.     later this will be copied from the sector routine into
  286.     the sector buffer
  287. *************************************************************************/
  288. static inline void create_sys_header(Sys_header_struc* sys_header,unsigned int rate_bound,unsigned char audio_bound, 
  289.             unsigned char fixed,unsigned char CSPS,unsigned char audio_lock,unsigned char video_lock,
  290.             unsigned char video_bound,
  291.             unsigned char stream1,unsigned char buffer1_scale,unsigned int buffer1_size,
  292.             unsigned char stream2,unsigned char buffer2_scale,unsigned int buffer2_size,
  293.             unsigned int which_streams)
  294. {
  295.     unsigned char *index;
  296.  
  297.     index = sys_header->buf;
  298.  
  299.     /* if we are not using both streams, we should clear some
  300.        options here */
  301.  
  302.     //if (!(which_streams & STREAMS_AUDIO))
  303.     //audio_bound = 0;
  304.     //if (!(which_streams & STREAMS_VIDEO))
  305.     //video_bound = 0;
  306.  
  307.     *(index++) = (unsigned char)((SYS_HEADER_START)>>24);
  308.     *(index++) = (unsigned char)((SYS_HEADER_START & 0x00ff0000)>>16);
  309.     *(index++) = (unsigned char)((SYS_HEADER_START & 0x0000ff00)>>8);
  310.     *(index++) = (unsigned char)(SYS_HEADER_START & 0x000000ff);
  311.  
  312.     if (which_streams == STREAMS_BOTH)
  313.     {
  314.         *(index++) = (unsigned char)(SYS_HEADER_LENGTH >> 8);
  315.         *(index++) = (unsigned char)(SYS_HEADER_LENGTH & 0xff);
  316.     }
  317.     else
  318.     {
  319.         *(index++) = (unsigned char)((SYS_HEADER_LENGTH-3) >> 8);
  320.         *(index++) = (unsigned char)((SYS_HEADER_LENGTH-3) & 0xff);
  321.     }
  322.  
  323.     *(index++) = (unsigned char)(0x80 | (rate_bound >>15));
  324.     *(index++) = (unsigned char)(0xff & (rate_bound >> 7));
  325.     *(index++) = (unsigned char)(0x01 | ((rate_bound & 0x7f)<<1));
  326.     *(index++) = (unsigned char)((audio_bound << 2)|(fixed << 1)|CSPS);
  327.     *(index++) = (unsigned char)((audio_lock << 7)|(video_lock << 6)|0x20|video_bound);
  328.     *(index++) = (unsigned char)RESERVED_BYTE;
  329.  
  330.     if (which_streams & STREAMS_AUDIO)
  331.     {
  332.         *(index++) = stream1;
  333.         *(index++) = (unsigned char) (0xc0 | (buffer1_scale << 5) | (buffer1_size >> 8));
  334.         *(index++) = (unsigned char) (buffer1_size & 0xff);
  335.     }
  336.  
  337.     if (which_streams & STREAMS_VIDEO)
  338.     {
  339.         *(index++) = stream2;
  340.         *(index++) = (unsigned char) (0xc0 | (buffer2_scale << 5) | (buffer2_size >> 8));
  341.         *(index++) = (unsigned char) (buffer2_size & 0xff);
  342.     }
  343.  
  344. }
  345.  
  346. static inline TOMPGRET get_info_video(const char *video_file,
  347.                                   char *video_units,
  348.                                   Video_struc *video_info,
  349.                                   double &startup_delay,
  350.                                   unsigned int length,
  351.                                   bool(* CallBack)(TOMPEG_PROCESS_PARAM,int))
  352. {
  353.     static const double picture_rates [9] = { 0.0, 24000.0/1001.0, 24.0, 25.0, 
  354.                     30000.0/1001.0, 30.0, 50.0, 60000.0/1001.0, 60.0 };
  355.     TOMPGRET ret = TR_ERR;
  356.     HANDLE info_file = NULL;
  357.     BitStreamStruct video_bs;
  358.     unsigned int offset_bits=0;
  359.     unsigned int stream_length=0; 
  360.     Vaunit_struc access_unit;
  361.     unsigned long syncword;
  362.     unsigned long decoding_order=0;
  363.     unsigned long group_order=0;
  364.     unsigned long temporal_reference=0;
  365.     double secs_per_frame=0;
  366.     unsigned short pict_rate;
  367.     double DTS;
  368.     double PTS;
  369.     int i;
  370.     unsigned int prozent;
  371.     unsigned int old_prozent=0;
  372.    
  373.      if((info_file = CreateFile(video_units, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
  374.         == INVALID_HANDLE_VALUE)
  375.     {
  376.         ret = TR_ERR_OPEN_FILE;
  377.         goto END_OF_GET_INFO_VIDEO;
  378.     }
  379.     switch(video_bs.OpenBitStreamR(video_file, BUFFER_SIZE))
  380.     {
  381.     case BSSR_OK:
  382.         break;
  383.     case BSSR_OPEN_FILE_ERR:
  384.         ret = TR_ERR_OPEN_FILE;
  385.         goto END_OF_GET_INFO_VIDEO;
  386.         break;
  387.     case BSSR_ALLOC_BUFFER_ERR:
  388.         ret = TR_ALLOC_BIT_STREAM_BUFFER_ERR;
  389.         goto END_OF_GET_INFO_VIDEO;
  390.         break;
  391.     default:
  392.         goto END_OF_GET_INFO_VIDEO;
  393.     }
  394.  
  395.     if (video_bs.GetBitStream(32)==SEQUENCE_HEADER)
  396.     {
  397.         video_info->num_sequence++;
  398.         video_info->horizontal_size    = video_bs.GetBitStream(12);
  399.         video_info->vertical_size    = video_bs.GetBitStream(12);
  400.         video_info->aspect_ratio    = video_bs.GetBitStream(4);
  401.         pict_rate             = (unsigned short)video_bs.GetBitStream(4);
  402.         video_info->picture_rate    = pict_rate;
  403.         video_info->bit_rate        = video_bs.GetBitStream(18);
  404.         if(!marker_bit (&video_bs, 1))
  405.             goto END_OF_GET_INFO_VIDEO;
  406.         video_info->vbv_buffer_size    = video_bs.GetBitStream(10);
  407.         video_info->CSPF        = video_bs.GetBit();
  408.     }
  409.     else
  410.     {
  411.         goto END_OF_GET_INFO_VIDEO;
  412.     }
  413.  
  414.     access_unit.empty();
  415.     startup_delay = 2*MAX_FFFFFFFF;
  416.  
  417.     if (pict_rate >0 && pict_rate<9)
  418.         secs_per_frame = 1.0 / picture_rates[pict_rate];
  419.     else
  420.         secs_per_frame = 1.0 / 25.0;    /* invalid pict_rate info */
  421.  
  422.     do
  423.     {
  424.         if (video_bs.SeekSync(SYNCWORD_START, 24))
  425.         {
  426.             syncword = (SYNCWORD_START<<8) + video_bs.GetBitStream(8);
  427.             switch (syncword)
  428.             {
  429.  
  430.             case SEQUENCE_HEADER:
  431.                 video_info->num_sequence++;
  432.                 break;
  433.  
  434.             case GROUP_START:
  435.                 video_info->num_groups++;
  436.                 group_order=0;
  437.                 break;
  438.  
  439.             case PICTURE_START:
  440.                 /* skip access unit number 0 */
  441.                 if (access_unit.type != 0)
  442.                 {
  443.                     stream_length = video_bs.sstell()-32;
  444.                     access_unit.length = (stream_length - offset_bits)>>3;
  445.                     offset_bits = stream_length;
  446.                     access_unit.write_file(info_file);
  447.                     video_info->avg_frames[access_unit.type-1]+=
  448.                         access_unit.length;
  449.                 }
  450.  
  451.                 temporal_reference = video_bs.GetBitStream(10);
  452.                 access_unit.type   = video_bs.GetBitStream(3);
  453.  
  454.                 DTS = decoding_order * secs_per_frame*CLOCKS;
  455.                 PTS = (temporal_reference - group_order + 1 + decoding_order) * secs_per_frame*CLOCKS;
  456.  
  457.                 startup_delay=(PTS<startup_delay ? PTS : startup_delay);
  458.  
  459.                 access_unit.DTS.make(DTS);
  460.                 access_unit.PTS.make(PTS);
  461.                 decoding_order++;
  462.                 group_order++;
  463.  
  464.                 if ((access_unit.type>0) && (access_unit.type<5))
  465.                     video_info->num_frames[access_unit.type-1]++;
  466.  
  467.                 prozent =(int) (((double)video_bs.sstell()/8.0/(double)length)*100.0);
  468.                 video_info->num_pictures++;            
  469.  
  470.                 if (prozent > old_prozent)
  471.                 {
  472.                     if(CallBack!=NULL)
  473.                     {
  474.                         if(!CallBack(TOMPEG_PROCESS_COMBINE,prozent/2))
  475.                         {
  476.                             ret = TR_CANCEL;
  477.                             goto END_OF_GET_INFO_VIDEO;
  478.                         }
  479.                     }
  480.                     old_prozent = prozent;
  481.                 }
  482.  
  483.                 break;            
  484.  
  485.             case SEQUENCE_END:
  486.                 stream_length = video_bs.sstell();
  487.                 access_unit.length = (stream_length - offset_bits)>>3;
  488.                 access_unit.write_file(info_file);
  489.                 video_info->avg_frames[access_unit.type-1]+=access_unit.length;
  490.                 offset_bits = stream_length;
  491.                 video_info->num_seq_end++;
  492.                 break;            
  493.  
  494.             }
  495.         }
  496.         else
  497.             break;
  498.     } while (!video_bs.end_bs());
  499.  
  500.     video_info->stream_length = offset_bits >> 3;
  501.     for (i=0; i<4; i++)
  502.         if (video_info->num_frames[i]!=0)
  503.            video_info->avg_frames[i] /= video_info->num_frames[i];
  504.  
  505.     if (secs_per_frame >0.0)
  506.         video_info->comp_bit_rate = (unsigned int)ceil ((double)(video_info->stream_length)/
  507.                                     (double)(video_info->num_pictures)/secs_per_frame/1250.)*25;
  508.     else
  509.         video_info->comp_bit_rate = 0;
  510.  
  511.     ret = TR_OK;
  512.  
  513. END_OF_GET_INFO_VIDEO:
  514.  
  515.     video_bs.CloseBitStreamR();
  516.     if(info_file!=NULL)
  517.         CloseHandle(info_file);
  518.  
  519.     return ret;
  520. }
  521.  
  522. static inline TOMPGRET get_info_audio(const char* audio_file,
  523.                                   char* audio_units,
  524.                                   Audio_struc* audio_info,
  525.                                   double& startup_delay,
  526.                                   unsigned int length,
  527.                                   bool(* CallBack)(TOMPEG_PROCESS_PARAM,int))
  528. {
  529.     static const double frequency [4] = {44.1, 48, 32, 0};
  530.     static const unsigned int slots [4] = {12, 144, 0, 0};
  531.     static const unsigned int samples [4] = {384, 1152, 0, 0};
  532.  
  533.     HANDLE info_file = NULL;
  534.     TOMPGRET ret = TR_ERR;
  535.  
  536.     BitStreamStruct audio_bs;
  537.     unsigned int offset_bits=0;
  538.     unsigned int stream_length=0; 
  539.     unsigned int framesize;
  540.     unsigned int padding_bit;
  541.     unsigned int skip;
  542.     unsigned int decoding_order=0;
  543.     double PTS;
  544.     double samples_per_second;
  545.     Aaunit_struc access_unit;
  546.     //unsigned long syncword;
  547.     unsigned int i;
  548.     unsigned int prozent;
  549.     unsigned int old_prozent=0;
  550.    
  551.     if((info_file = CreateFile(audio_units, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
  552.         == INVALID_HANDLE_VALUE)
  553.     {
  554.         ret = TR_ERR_OPEN_FILE;
  555.         goto END_OF_GET_INFO_AUDIO;
  556.     }
  557.     switch(audio_bs.OpenBitStreamR(audio_file, BUFFER_SIZE))
  558.     {
  559.     case BSSR_OK:
  560.         break;
  561.     case BSSR_OPEN_FILE_ERR:
  562.         ret = TR_ERR_OPEN_FILE;
  563.         goto END_OF_GET_INFO_AUDIO;
  564.         break;
  565.     case BSSR_ALLOC_BUFFER_ERR:
  566.         ret = TR_ALLOC_BIT_STREAM_BUFFER_ERR;
  567.         goto END_OF_GET_INFO_AUDIO;
  568.     default:
  569.         goto END_OF_GET_INFO_AUDIO;
  570.     }
  571.  
  572.  
  573.     access_unit.empty();
  574.  
  575.     if (audio_bs.GetBitStream(12)==AUDIO_SYNCWORD)
  576.     {
  577.         if(!marker_bit (&audio_bs, 1))
  578.         {
  579.             goto END_OF_GET_INFO_AUDIO;
  580.         }
  581.         audio_info->num_syncword++;
  582.         audio_info->layer         = audio_bs.GetBitStream(2);
  583.         audio_info->protection         = audio_bs.GetBit();
  584.         audio_info->bit_rate         = audio_bs.GetBitStream(4);
  585.         audio_info->frequency         = audio_bs.GetBitStream(2);
  586.         padding_bit = audio_bs.GetBit();
  587.         audio_bs.GetBit();
  588.         audio_info->mode         = audio_bs.GetBitStream(2);
  589.         audio_info->mode_extension     = audio_bs.GetBitStream(2);
  590.         audio_info->copyright         = audio_bs.GetBit();
  591.         audio_info->original_copy     = audio_bs.GetBit();
  592.         audio_info->emphasis        = audio_bs.GetBitStream(2);
  593.  
  594.         framesize =
  595.             (unsigned int)(bitrate_index[3-audio_info->layer][audio_info->bit_rate] /
  596.             frequency[audio_info->frequency] * slots [3-audio_info->layer]);
  597.         audio_info->size_frames[0] = framesize;
  598.         audio_info->size_frames[1] = framesize+1;
  599.         
  600.         access_unit.length = audio_info->size_frames[padding_bit];
  601.  
  602.         samples_per_second = frequency [audio_info->frequency];
  603.  
  604.         PTS = ((double)(decoding_order * samples [3-audio_info->layer])) / samples_per_second * 90. + startup_delay;
  605.  
  606.         access_unit.PTS.make(PTS);
  607.         decoding_order++;
  608.  
  609.         access_unit.write_file(info_file);
  610.         audio_info->num_frames[padding_bit]++;
  611.  
  612.     }
  613.     else
  614.     {
  615.         goto END_OF_GET_INFO_AUDIO;
  616.     }
  617.  
  618.  
  619.     do
  620.     {
  621.         skip=access_unit.length-4;
  622.         if (skip & 0x1)
  623.             audio_bs.GetBitStream(8);
  624.         if (skip & 0x2)
  625.             audio_bs.GetBitStream(16);
  626.         skip=skip>>2;
  627.  
  628.         for (i=0;i<skip;i++)
  629.         {
  630.             audio_bs.GetBitStream(32);
  631.         }
  632.         offset_bits = audio_bs.sstell();
  633.         if (audio_bs.GetBitStream(12)==AUDIO_SYNCWORD)
  634.         {
  635.             if(!marker_bit (&audio_bs, 1))
  636.             {
  637.                 goto END_OF_GET_INFO_AUDIO;
  638.             }
  639.             prozent =(int) ((((double) audio_bs.sstell())/8.0/((double)length))*100.0);
  640.             audio_info->num_syncword++;
  641.             if (prozent > old_prozent)
  642.             {
  643.                 if(CallBack!=NULL)
  644.                 {
  645.                     if(!CallBack(TOMPEG_PROCESS_COMBINE,prozent/2+50))
  646.                     {
  647.                         ret = TR_CANCEL;
  648.                         goto END_OF_GET_INFO_AUDIO;
  649.                     }
  650.                 }
  651.                 old_prozent = prozent;
  652.             }
  653.             audio_bs.GetBitStream(9);
  654.  
  655.             padding_bit=audio_bs.GetBit();
  656.             access_unit.length = audio_info->size_frames[padding_bit];
  657.  
  658.             PTS = ((double)(decoding_order * samples [3-audio_info->layer])) / samples_per_second * 90. + startup_delay;
  659.             access_unit.PTS.make(PTS);
  660.  
  661.             decoding_order++;
  662.  
  663.             access_unit.write_file(info_file);
  664.             audio_info->num_frames[padding_bit]++;
  665.  
  666.             audio_bs.GetBitStream(9);
  667.         }    
  668.         else
  669.             break;
  670.     } while (!audio_bs.end_bs());
  671.  
  672.     //printf ("\nDone, stream bit offset %ld.\n",offset_bits);
  673.  
  674.     audio_info->stream_length = offset_bits >> 3;
  675.  
  676.     ret = TR_OK;
  677.  
  678. END_OF_GET_INFO_AUDIO:
  679.  
  680.     audio_bs.CloseBitStreamR();
  681.     
  682.     if(info_file!=NULL)
  683.         CloseHandle(info_file);
  684.  
  685.     return ret;
  686. }
  687.  
  688.  
  689. static bool open_file(const char* name,unsigned int& bytes)
  690. {
  691.     HANDLE hFile;
  692.     if((hFile = CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
  693.         == INVALID_HANDLE_VALUE)
  694.     {
  695.         return false;
  696.     }
  697.     bytes = (unsigned int)GetFileSize(hFile,NULL);
  698.     CloseHandle(hFile);
  699.  
  700.     return true;
  701. }
  702.  
  703. static inline bool check_files(const char* vfile,
  704.                  const char* afile,
  705.                  const char* mfile,
  706.                  unsigned int& audio_bytes,
  707.                  unsigned int& video_bytes,
  708.                  unsigned int& ptr_which_streams)
  709. {
  710.  
  711.     if (!open_file(vfile, video_bytes) || !open_file(afile, audio_bytes))
  712.         return false; 
  713.  
  714.     ptr_which_streams |= STREAMS_VIDEO;
  715.     ptr_which_streams |= STREAMS_AUDIO;
  716.  
  717.     return true;
  718. }
  719.  
  720. /******************************************************************
  721.     Next_Video_Access_Unit
  722.     holt aus dem TMP File, der die Info's ueber die Access
  723.     Units enthaelt, die jetzt gueltige Info her. Nach
  724.     dem Erstellen des letzten Packs sind naemlich eine
  725.     bestimmte Anzahl Bytes und damit AU's eingelesen worden.
  726.  
  727.     gets information for the next access unit from the tmp
  728.     file
  729. ******************************************************************/
  730.  
  731. static bool next_video_access_unit(Buffer_struc* buffer,Vaunit_struc* video_au,
  732.                                    unsigned int& bytes_left,
  733.                                    HANDLE vunits_info,
  734.                                    bool& picture_start,
  735.                                    Timecode_struc* SCR_delay)
  736. {
  737.  
  738.     if (bytes_left == 0)
  739.         return true;
  740.  
  741.     while (video_au->length < bytes_left)
  742.     {
  743.         if(!buffer->queue(video_au->length, &video_au->DTS))
  744.         {
  745.             return false;
  746.         }
  747.         bytes_left -= video_au->length;
  748.         if (!video_au->read_file(vunits_info))
  749.         {
  750.             video_au->empty();
  751.             return true;
  752.         }
  753.         picture_start = true;
  754.         video_au->DTS = video_au->DTS + *SCR_delay;
  755.         video_au->PTS = video_au->PTS + *SCR_delay;
  756.     }
  757.  
  758.     if (video_au->length > bytes_left)
  759.     {
  760.         if(!buffer->queue(bytes_left, &video_au->DTS))
  761.         {
  762.             return false;
  763.         }
  764.         video_au->length -= bytes_left;
  765.         picture_start = false;
  766.     }
  767.     else if (video_au->length == bytes_left)
  768.     {
  769.         if(!buffer->queue(bytes_left, &video_au->DTS))
  770.         {
  771.             return false;
  772.         }
  773.         if (!video_au->read_file(vunits_info))
  774.         {
  775.             video_au->empty();
  776.             return true;
  777.         }
  778.         picture_start = true;
  779.         video_au->DTS = video_au->DTS + *SCR_delay;
  780.         video_au->PTS = video_au->PTS + *SCR_delay;
  781.     }
  782.     return true;
  783. }
  784.  
  785.  
  786. /******************************************************************
  787.     Output_Video
  788.     generiert Pack/Sys_Header/Packet Informationen aus dem
  789.     Video Stream und speichert den so erhaltenen Sektor ab.
  790.  
  791.     generates Pack/Sys_Header/Packet information from the
  792.     video stream and writes out the new sector
  793. ******************************************************************/
  794.  
  795. static bool output_video (Timecode_struc* SCR,Timecode_struc* SCR_delay,
  796.                    HANDLE vunits_info,HANDLE istream_v,HANDLE ostream,
  797.            Pack_struc* pack,Sys_header_struc* sys_header,Sector_struc* sector,Buffer_struc* buffer,Vaunit_struc* video_au,
  798.            bool& picture_start,unsigned int& bytes_output,unsigned int mux_rate,
  799.            unsigned long audio_buffer_size,unsigned long video_buffer_size,
  800.            unsigned long packet_data_size,unsigned char marker_pack,unsigned int which_streams)
  801. {
  802.  
  803.     unsigned int bytes_left;
  804.     unsigned int temp;
  805.     Pack_struc *pack_ptr;
  806.     Sys_header_struc *sys_header_ptr;
  807.     unsigned char timestamps;
  808.     DWORD dwResult;
  809.  
  810.  
  811.     if (marker_pack)
  812.     {
  813.         create_pack (pack, SCR, mux_rate);
  814.         create_sys_header (sys_header, mux_rate, 1, 1, 1, 1, 1, 1,
  815.             AUDIO_STR_0, 0, audio_buffer_size/128,
  816.             VIDEO_STR_0, 1, video_buffer_size/1024, which_streams );
  817.         pack_ptr = pack;
  818.         sys_header_ptr = sys_header;
  819.     }
  820.     else
  821.     {
  822.         pack_ptr = NULL;
  823.         sys_header_ptr = NULL;
  824.     }
  825.  
  826.     if (picture_start)
  827.     {
  828.         if (video_au->type == BFRAME)
  829.             timestamps=TIMESTAMPS_PTS;
  830.         else
  831.             timestamps=TIMESTAMPS_PTS_DTS;
  832.  
  833.         create_sector (sector, pack_ptr, sys_header_ptr,
  834.                 packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
  835.                 istream_v, VIDEO_STR_0, 1, video_buffer_size/1024,
  836.                 true, &video_au->PTS, &video_au->DTS,
  837.                     timestamps, which_streams );
  838.  
  839.         bytes_left = sector->length_of_packet_data;
  840.  
  841.         if(!next_video_access_unit (buffer, video_au, bytes_left, vunits_info,
  842.                     picture_start, SCR_delay))
  843.         {
  844.             return false;
  845.         }
  846.  
  847.     }
  848.     else if (!(picture_start) && (video_au->length >= packet_data_size))
  849.     {
  850.         create_sector (sector, pack_ptr, sys_header_ptr,
  851.                 packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
  852.                 istream_v, VIDEO_STR_0, 1, video_buffer_size/1024,
  853.                 true, NULL, NULL,
  854.                 TIMESTAMPS_NO, which_streams );
  855.  
  856.         bytes_left = sector->length_of_packet_data;
  857.  
  858.         if(!next_video_access_unit (buffer, video_au, bytes_left, vunits_info,
  859.                     picture_start, SCR_delay))
  860.         {
  861.             return false;
  862.         }
  863.  
  864.     }
  865.     else if (!(picture_start) && (video_au->length < packet_data_size))
  866.     {
  867.         temp = video_au->length;
  868.         if(!buffer->queue(video_au->length, &video_au->DTS))
  869.         {
  870.             return false;
  871.         }
  872.  
  873.         /* gibt es ueberhaupt noch eine Access Unit ? */
  874.         /* is there a new access unit anyway? */
  875.  
  876.         if (video_au->read_file(vunits_info))
  877.         {
  878.             if (video_au->type == BFRAME)
  879.             timestamps=TIMESTAMPS_PTS;
  880.             else
  881.             timestamps=TIMESTAMPS_PTS_DTS;
  882.  
  883.             picture_start = true;
  884.             video_au->DTS = video_au->DTS + *SCR_delay;
  885.             video_au->PTS = video_au->PTS + *SCR_delay;
  886.             create_sector (sector, pack_ptr, sys_header_ptr,
  887.                 packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
  888.                 istream_v, VIDEO_STR_0, 1, video_buffer_size/1024,
  889.                 true, &video_au->PTS, &video_au->DTS,
  890.                 timestamps, which_streams );
  891.             bytes_left = sector->length_of_packet_data - temp;
  892.  
  893.             next_video_access_unit (buffer, video_au, bytes_left, vunits_info,
  894.                         picture_start, SCR_delay);
  895.         }
  896.         else
  897.         {
  898.             video_au->empty();
  899.             create_sector (sector, pack_ptr, sys_header_ptr,
  900.                 packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
  901.                 istream_v, VIDEO_STR_0, 1, video_buffer_size/1024,
  902.                 true, NULL, NULL,
  903.                 TIMESTAMPS_NO, which_streams );
  904.         }
  905.     }
  906.  
  907.  
  908.     /* Sector auf Platte schreiben                */
  909.     /* write out sector                        */
  910.     WriteFile(ostream,sector->buf,sector->length_of_sector, &dwResult, NULL);
  911.     //fwrite (sector->buf, sector->length_of_sector, 1, ostream);
  912.     bytes_output += sector->length_of_sector;
  913.     
  914.     return true;
  915. }
  916.  
  917.  
  918. /******************************************************************
  919.     Next_Audio_Access_Unit
  920.     holt aus dem TMP File, der die Info's ueber die Access
  921.     Units enthaelt, die jetzt gueltige Info her. Nach
  922.     dem Erstellen des letzten Packs sind naemlich eine
  923.     bestimmte Anzahl Bytes und damit AU's eingelesen worden.
  924.  
  925.     gets information on access unit from the tmp file
  926. ******************************************************************/
  927.  
  928. static bool next_audio_access_unit(Buffer_struc* buffer,Aaunit_struc* audio_au,unsigned int& bytes_left,
  929.                             HANDLE aunits_info,bool& audio_frame_start,Timecode_struc* SCR_delay)
  930. {
  931.  
  932.     if (bytes_left == 0)
  933.         return true;
  934.  
  935.     while (audio_au->length < bytes_left)
  936.     {
  937.         if(!buffer->queue(audio_au->length, &audio_au->PTS))
  938.         {
  939.             return false;
  940.         }
  941.         bytes_left -= audio_au->length;
  942.         if (!audio_au->read_file(aunits_info))
  943.         {
  944.             audio_au->empty();
  945.             return true;
  946.         }
  947.         audio_frame_start = true;
  948.         audio_au->PTS = audio_au->PTS + *SCR_delay;
  949.     }
  950.  
  951.     if (audio_au->length > bytes_left)
  952.     {
  953.         if(!buffer->queue(bytes_left, &audio_au->PTS))
  954.         {
  955.             return false;
  956.         }
  957.         audio_au->length -= bytes_left;
  958.         audio_frame_start = false;
  959.     }
  960.     else if (audio_au->length == bytes_left)
  961.     {
  962.         if(!buffer->queue(bytes_left, &audio_au->PTS))
  963.         {
  964.             return false;
  965.         }
  966.         if (!audio_au->read_file(aunits_info))
  967.         {
  968.             audio_au->empty();
  969.             return true;
  970.         }
  971.         audio_frame_start = true;
  972.         audio_au->PTS = audio_au->PTS + *SCR_delay;
  973.     }
  974.     return true;
  975. }
  976.  
  977. /******************************************************************
  978.     Output_Audio
  979.     erstellt Pack/Sys_Header/Packet Informationen aus dem
  980.     Audio Stream und speichert den so erhaltenen Sector ab.
  981.  
  982.     generates Pack/Sys Header/Packet information from the
  983.     audio stream and saves them into the sector
  984. ******************************************************************/
  985. static bool output_audio(Timecode_struc* SCR,Timecode_struc* SCR_delay,
  986.                   HANDLE aunits_info,HANDLE istream_a,HANDLE ostream,
  987.                   Pack_struc* pack,Sys_header_struc* sys_header,Sector_struc* sector,Buffer_struc* buffer,Aaunit_struc* audio_au,
  988.            bool& audio_frame_start,unsigned int& bytes_output,unsigned int mux_rate,
  989.            unsigned long audio_buffer_size,unsigned long video_buffer_size,
  990.            unsigned long packet_data_size,unsigned char marker_pack,unsigned int which_streams)
  991. {
  992.  
  993.     unsigned int bytes_left;
  994.     unsigned int temp;
  995.     Pack_struc *pack_ptr;
  996.     Sys_header_struc *sys_header_ptr;
  997.     DWORD dwResult;
  998.  
  999.     if (marker_pack)
  1000.     {
  1001.         /* Wir generieren den Pack Header                */
  1002.     /* let's generate pack header                    */
  1003.         create_pack (pack, SCR, mux_rate);
  1004.  
  1005.         /* Wir generieren den System Header                */
  1006.     /* let's generate system header                    */
  1007.         create_sys_header (sys_header, mux_rate, 1, 1, 1, 1, 1, 1,
  1008.             AUDIO_STR_0, 0, audio_buffer_size/128,
  1009.             VIDEO_STR_0, 1, video_buffer_size/1024, which_streams );
  1010.         pack_ptr = pack;
  1011.         sys_header_ptr = sys_header;
  1012.     }
  1013.     else
  1014.     {
  1015.         pack_ptr = NULL;
  1016.         sys_header_ptr = NULL;
  1017.     }
  1018.  
  1019.     /* Wir generieren das Packet                */
  1020.     /* Let's generate packet                    */
  1021.  
  1022.     /* faengt im Packet ein Audio Frame an?            */
  1023.     /* does a audio frame start in this packet?            */
  1024.  
  1025.     /* FALL: Packet beginnt mit neuer Access Unit            */
  1026.     /* CASE: packet starts with new access unit            */
  1027.     if (audio_frame_start)
  1028.     {
  1029.         create_sector (sector, pack_ptr, sys_header_ptr,
  1030.                 packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
  1031.                 istream_a, AUDIO_STR_0, 0, audio_buffer_size/128,
  1032.                 true, &audio_au->PTS, NULL,
  1033.                 TIMESTAMPS_PTS, which_streams);
  1034.  
  1035.         bytes_left = sector->length_of_packet_data;
  1036.  
  1037.         if(!next_audio_access_unit (buffer, audio_au, bytes_left, aunits_info,
  1038.                     audio_frame_start, SCR_delay))
  1039.         {
  1040.             return false;
  1041.         }
  1042.     }
  1043.     else if (!(audio_frame_start) && (audio_au->length >= packet_data_size))
  1044.     {
  1045.         create_sector (sector, pack_ptr, sys_header_ptr,
  1046.                 packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
  1047.                 istream_a, AUDIO_STR_0, 0, audio_buffer_size/128,
  1048.                 true, NULL, NULL,
  1049.                 TIMESTAMPS_NO, which_streams );
  1050.  
  1051.         bytes_left = sector->length_of_packet_data;
  1052.  
  1053.         if(!next_audio_access_unit (buffer, audio_au, bytes_left, aunits_info,
  1054.                     audio_frame_start, SCR_delay))
  1055.         {
  1056.             return false;
  1057.         }
  1058.     }
  1059.     else if (!(audio_frame_start) && (audio_au->length < packet_data_size))
  1060.     {
  1061.         temp = audio_au->length;
  1062.         if(!buffer->queue(audio_au->length, &audio_au->PTS))
  1063.         {
  1064.             return false;
  1065.         }
  1066.  
  1067.         /* gibt es ueberhaupt noch eine Access Unit ? */
  1068.         /* is there another access unit anyway ? */
  1069.  
  1070.         if (audio_au->read_file(aunits_info))
  1071.         {
  1072.             audio_frame_start = true;
  1073.             audio_au->PTS = audio_au->PTS + *SCR_delay;
  1074.             create_sector (sector, pack_ptr, sys_header_ptr,
  1075.                 packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
  1076.                 istream_a, AUDIO_STR_0, 0, audio_buffer_size/128,
  1077.                 true, &audio_au->PTS, NULL,
  1078.                 TIMESTAMPS_PTS, which_streams );
  1079.  
  1080.             bytes_left = sector->length_of_packet_data - temp;
  1081.  
  1082.             if(!next_audio_access_unit (buffer, audio_au, bytes_left, aunits_info,
  1083.                         audio_frame_start, SCR_delay))
  1084.             {
  1085.                 return false;
  1086.             }
  1087.         }
  1088.         else 
  1089.         {
  1090.             audio_au->empty();
  1091.             create_sector (sector, pack_ptr, sys_header_ptr,
  1092.                 packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
  1093.                 istream_a, AUDIO_STR_0, 0, audio_buffer_size/128,
  1094.                 true, NULL, NULL,
  1095.                 TIMESTAMPS_NO, which_streams );
  1096.         }
  1097.     }
  1098.  
  1099.     /* Sector auf Platte schreiben                */
  1100.     /* write out sector onto disk                */
  1101.     WriteFile(ostream,sector->buf,sector->length_of_sector, &dwResult, NULL);
  1102. //    fwrite (sector->buf, sector->length_of_sector, 1, ostream);
  1103.     bytes_output += sector->length_of_sector;
  1104.  
  1105.     return true;
  1106.     
  1107. }
  1108.  
  1109. /******************************************************************
  1110.     Output_Padding
  1111.     erstellt Pack/Sys_Header/Packet Informationen zu einem
  1112.     Padding-Stream und speichert den so erhaltenen Sector ab.
  1113.  
  1114.     generates Pack/Sys Header/Packet information for a 
  1115.     padding stream and saves the sector
  1116. ******************************************************************/
  1117. static inline void output_padding (Timecode_struc* SCR,HANDLE ostream,
  1118.            Pack_struc* pack,Sys_header_struc* sys_header,Sector_struc* sector,
  1119.            unsigned int* bytes_output,unsigned int mux_rate,
  1120.            unsigned long audio_buffer_size,unsigned long video_buffer_size,unsigned long packet_data_size,
  1121.            unsigned char marker_pack,unsigned int which_streams)
  1122. {
  1123.     //unsigned int bytes_left;
  1124.     //unsigned int temp;
  1125.     Pack_struc *pack_ptr;
  1126.     Sys_header_struc *sys_header_ptr;
  1127.     DWORD dwResult;
  1128.  
  1129.     if (marker_pack)
  1130.     {
  1131.         /* Wir generieren den Pack Header                */
  1132.     /* let's generate the pack header                */
  1133.         create_pack (pack, SCR, mux_rate);
  1134.  
  1135.         /* Wir generieren den System Header                */
  1136.     /* let's generate the system header                */
  1137.         create_sys_header (sys_header, mux_rate, 1, 1, 1, 1, 1, 1,
  1138.             AUDIO_STR_0, 0, audio_buffer_size/128,
  1139.             VIDEO_STR_0, 1, video_buffer_size/1024, which_streams );
  1140.         pack_ptr = pack;
  1141.         sys_header_ptr = sys_header;
  1142.     }
  1143.     else
  1144.     {
  1145.         pack_ptr = NULL;
  1146.         sys_header_ptr = NULL;
  1147.     }
  1148.  
  1149.     /* Wir generieren das Packet                */
  1150.     /* let's generate the packet                */
  1151.     create_sector (sector, pack_ptr, sys_header_ptr,
  1152.         packet_data_size+PACKET_HEADER_SIZE+AFTER_PACKET_LENGTH,
  1153.         NULL, PADDING_STR, 0, 0,
  1154.         false, NULL, NULL,
  1155.         TIMESTAMPS_NO, which_streams );
  1156.  
  1157.      WriteFile(ostream,sector->buf,sector->length_of_sector, &dwResult, NULL);
  1158. //   fwrite (sector->buf, sector->length_of_sector*sizeof (unsigned char), 1,
  1159. //        ostream);
  1160.     *bytes_output += sector->length_of_sector;
  1161.     
  1162. }
  1163.  
  1164. static inline TOMPGRET outputstream (const char* video_file,char* video_units,Video_struc* video_info,
  1165.            const char* audio_file,char* audio_units,Audio_struc* audio_info,
  1166.            const char* multi_file,unsigned int which_streams)
  1167. {
  1168.     HANDLE istream_v = NULL;            /* Inputstream Video    */
  1169.     HANDLE istream_a = NULL;            /* Inputstream Audio    */
  1170.     HANDLE ostream = NULL;                /* Outputstream MPEG    */
  1171.     HANDLE vunits_info = NULL;            /* Input Video Units    */
  1172.     HANDLE aunits_info = NULL;            /* Input Audio Units    */
  1173.     TOMPGRET ret = TR_ERR;
  1174.  
  1175.     Vaunit_struc video_au;        /* Video Access Unit    */
  1176.     Aaunit_struc audio_au;        /* Audio Access Unit    */
  1177.  
  1178.     unsigned int data_rate=0;        /* AudioVideo Byterate    */
  1179.     unsigned int video_rate=0;
  1180.     unsigned int audio_rate=0;
  1181.     double delay,audio_delay,video_delay;
  1182.     double clock_cycles;
  1183.     double audio_next_clock_cycles;
  1184.     double video_next_clock_cycles;
  1185.     unsigned int bytes_output;
  1186.     double dmux_rate;
  1187.     unsigned long sectors_delay,video_delay_ms,audio_delay_ms;
  1188.     unsigned int mux_rate;
  1189.     bool picture_start;
  1190.     bool audio_frame_start;
  1191.     //unsigned int bytes_left;
  1192.     unsigned int audio_bytes;
  1193.     unsigned int video_bytes;
  1194.     DWORD dwResult;
  1195.  
  1196.     unsigned int nsec_a=0;
  1197.     unsigned int nsec_v=0;
  1198.     unsigned int nsec_p=0;
  1199.  
  1200.     unsigned char* index;
  1201.     
  1202.     Timecode_struc SCR_audio_delay;
  1203.     Timecode_struc SCR_video_delay;
  1204.     Timecode_struc current_SCR;
  1205.     Timecode_struc audio_next_SCR;
  1206.     Timecode_struc video_next_SCR;
  1207.  
  1208.     Buffer_struc video_buffer;
  1209.     Buffer_struc audio_buffer;
  1210.  
  1211.     Pack_struc         pack;
  1212.     Sys_header_struc     sys_header;
  1213.     Sector_struc     sector;
  1214.  
  1215.     unsigned long sector_size;
  1216.     unsigned long min_packet_data;
  1217.     unsigned long max_packet_data;
  1218.     unsigned long packets_per_pack;
  1219.     unsigned long audio_buffer_size;
  1220.     unsigned long video_buffer_size;
  1221.  
  1222.     unsigned long write_pack;
  1223.     bool marker_pack;
  1224.     unsigned long packet_data_size;
  1225.     int total_length;
  1226.  
  1227.     /* Oeffne alle Ein- und Ausgabefiles            */
  1228.     /* Open in- and outputstream                */
  1229.  
  1230.     if (which_streams & STREAMS_VIDEO)
  1231.     {
  1232.         if((istream_v = CreateFile(video_file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
  1233.             == INVALID_HANDLE_VALUE)
  1234.         {
  1235.             ret = TR_ERR_OPEN_FILE;
  1236.             goto END_OUTPUT_STREAM;
  1237.         }
  1238.         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))
  1239.             == INVALID_HANDLE_VALUE)
  1240.         {
  1241.             ret = TR_ERR_OPEN_FILE;
  1242.             goto END_OUTPUT_STREAM;
  1243.         }
  1244.     }
  1245.     if (which_streams & STREAMS_AUDIO)
  1246.     {
  1247.         if((istream_a = CreateFile(audio_file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
  1248.             == INVALID_HANDLE_VALUE)
  1249.         {
  1250.             ret = TR_ERR_OPEN_FILE;
  1251.             goto END_OUTPUT_STREAM;
  1252.         }
  1253.         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))
  1254.             == INVALID_HANDLE_VALUE)
  1255.         {
  1256.             ret = TR_ERR_OPEN_FILE;
  1257.             goto END_OUTPUT_STREAM;
  1258.         }
  1259.     }
  1260.     if((ostream = CreateFile(multi_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))
  1261.         == INVALID_HANDLE_VALUE)
  1262.     {
  1263.         ret = TR_ERR_OPEN_FILE;
  1264.         goto END_OUTPUT_STREAM;
  1265.     }
  1266.  
  1267.     /* Einlesen erster Access Unit Informationen        */
  1268.     /* read in first access unit information            */
  1269.  
  1270.     picture_start     = false;
  1271.     audio_frame_start = false;
  1272.     video_au.empty();
  1273.     audio_au.empty();
  1274.  
  1275.     if (which_streams & STREAMS_AUDIO)
  1276.     {
  1277.         audio_au.read_file(aunits_info);
  1278.         audio_frame_start = true;
  1279.     }
  1280.     if (which_streams & STREAMS_VIDEO)
  1281.     {
  1282.         video_au.read_file(vunits_info);
  1283.         picture_start = true;
  1284.     }
  1285.  
  1286.     sector_size = 2048;
  1287.  
  1288.      packets_per_pack = 1;
  1289.  
  1290.     video_buffer_size = 40;
  1291.  
  1292.     audio_buffer_size = 4;
  1293.  
  1294.     write_pack = packets_per_pack;
  1295.     video_buffer_size *= 1024;
  1296.     audio_buffer_size *= 1024;
  1297.     min_packet_data = sector_size - PACK_HEADER_SIZE - SYS_HEADER_SIZE -
  1298.     PACKET_HEADER_SIZE - AFTER_PACKET_LENGTH;
  1299.     max_packet_data = sector_size - PACKET_HEADER_SIZE - AFTER_PACKET_LENGTH;
  1300.  
  1301.      if (which_streams != STREAMS_BOTH)
  1302.      { 
  1303.         min_packet_data += 3; 
  1304.      }     
  1305.  
  1306.  
  1307.     init_buffer_struc (&video_buffer,video_buffer_size);
  1308.     init_buffer_struc (&audio_buffer,audio_buffer_size);
  1309.  
  1310.     if (which_streams & STREAMS_VIDEO)
  1311.     {
  1312.         if (video_info->bit_rate > video_info->comp_bit_rate)
  1313.             video_rate = video_info->bit_rate * 50;
  1314.         else
  1315.             video_rate = video_info->comp_bit_rate * 50;
  1316.     }
  1317.     if (which_streams & STREAMS_AUDIO)
  1318.         audio_rate = bitrate_index[3-audio_info->layer][audio_info->bit_rate]*128;
  1319.  
  1320.     data_rate = video_rate + audio_rate;
  1321.  
  1322.     dmux_rate =  ceil((double)(data_rate) *
  1323.          ((double)(sector_size)/(double)(min_packet_data) +
  1324.          ((double)(sector_size)/(double)(max_packet_data) *
  1325.          (double)(packets_per_pack-1.))) / (double)(packets_per_pack) );
  1326.     data_rate = (unsigned int)ceil(dmux_rate/50.)*50;
  1327.  
  1328.     sectors_delay = 8;
  1329.  
  1330.     video_delay_ms = 0;
  1331.  
  1332.     audio_delay_ms = 0;
  1333.  
  1334.     video_delay = (double)video_delay_ms*(double)(CLOCKS/1000);
  1335.     audio_delay = (double)audio_delay_ms*(double)(CLOCKS/1000);
  1336.  
  1337.     mux_rate = (unsigned int)ceil(dmux_rate/50.);
  1338.  
  1339.     dmux_rate= mux_rate * 50.;
  1340.  
  1341.     delay = ((double)sectors_delay +
  1342.             ceil((double)video_au.length/(double)min_packet_data)  +
  1343.             ceil((double)audio_au.length/(double)min_packet_data )) *
  1344.             (double)sector_size/dmux_rate*(double)CLOCKS;
  1345.  
  1346.     audio_delay += delay;
  1347.     video_delay += delay;
  1348.  
  1349.     SCR_audio_delay.make(audio_delay);
  1350.     SCR_video_delay.make(video_delay);
  1351.  
  1352.     video_au.DTS = video_au.DTS + SCR_video_delay;
  1353.     video_au.PTS = video_au.PTS + SCR_video_delay;
  1354.     audio_au.PTS = audio_au.PTS + SCR_audio_delay;
  1355.  
  1356.     bytes_output = 0;
  1357.  
  1358.     total_length = video_au.length + audio_au.length;
  1359.  
  1360.     while ((video_au.length + audio_au.length) > 0)
  1361.     {
  1362.         if (write_pack-- == packets_per_pack) 
  1363.         {
  1364.             marker_pack = true;
  1365.             packet_data_size = min_packet_data;
  1366.         }
  1367.         else 
  1368.         {
  1369.             marker_pack = false;
  1370.             packet_data_size = max_packet_data;
  1371.         }
  1372.  
  1373.         if(write_pack == 0)
  1374.             write_pack = packets_per_pack;
  1375.  
  1376.         audio_bytes = (audio_au.length/min_packet_data)*sector_size + (audio_au.length%min_packet_data)+(sector_size-min_packet_data);
  1377.         video_bytes = (video_au.length/min_packet_data)*sector_size + (video_au.length%min_packet_data)+(sector_size-min_packet_data);
  1378.  
  1379.         clock_cycles = (double)(bytes_output+LAST_SCR_BYTE_IN_PACK)*CLOCKS/dmux_rate;
  1380.  
  1381.         audio_next_clock_cycles = (double)(bytes_output+sector_size+audio_bytes)/dmux_rate*CLOCKS;
  1382.         video_next_clock_cycles = (double)(bytes_output+sector_size+video_bytes)/dmux_rate*CLOCKS;
  1383.  
  1384.         current_SCR.make(clock_cycles);
  1385.         audio_next_SCR.make(audio_next_clock_cycles);
  1386.         video_next_SCR.make(video_next_clock_cycles);
  1387.  
  1388.         if (which_streams & STREAMS_AUDIO)
  1389.             audio_buffer.clean(¤t_SCR);
  1390.         if (which_streams & STREAMS_VIDEO)
  1391.             video_buffer.clean(¤t_SCR);
  1392.  
  1393.         if ( (video_buffer.space() >= packet_data_size)
  1394.              && (video_au.length>0)
  1395.              && ((comp_timecode(&audio_next_SCR, &audio_au.PTS)) ||
  1396.              (audio_au.length==0) ))
  1397.         {
  1398.             if(!output_video(¤t_SCR, &SCR_video_delay, vunits_info,
  1399.                         istream_v, ostream, &pack, &sys_header, §or,
  1400.                         &video_buffer, &video_au, picture_start,
  1401.                         bytes_output, mux_rate, audio_buffer_size, video_buffer_size,
  1402.                         packet_data_size, marker_pack, which_streams))
  1403.             {
  1404.                 ret = TR_OUTPUT_VIDRO_ERR;
  1405.                 goto END_OUTPUT_STREAM;
  1406.             }
  1407.         }
  1408.         else if ( (audio_buffer.space() >= packet_data_size)
  1409.               && (audio_au.length>0)
  1410.               && ((comp_timecode (&video_next_SCR, &video_au.DTS)) ||
  1411.                   (video_au.length==0) ))
  1412.         {
  1413.             output_audio (¤t_SCR, &SCR_audio_delay, aunits_info,
  1414.                         istream_a, ostream, &pack, &sys_header, §or,
  1415.                         &audio_buffer, &audio_au, audio_frame_start,
  1416.                         bytes_output, mux_rate, audio_buffer_size, video_buffer_size,
  1417.                         packet_data_size, marker_pack, which_streams);
  1418.         }
  1419.         else if ( (audio_buffer.space() >= packet_data_size)
  1420.               && (audio_au.length>0)
  1421.               &! comp_timecode (&audio_next_SCR, &audio_au.PTS))
  1422.         {
  1423.             output_audio(¤t_SCR, &SCR_audio_delay, aunits_info,
  1424.                         istream_a, ostream, &pack, &sys_header, §or,
  1425.                         &audio_buffer, &audio_au, audio_frame_start,
  1426.                         bytes_output, mux_rate, audio_buffer_size, video_buffer_size,
  1427.                         packet_data_size, marker_pack, which_streams);
  1428.         }
  1429.         else if ( (video_buffer.space() >= packet_data_size)
  1430.                && (video_au.length>0)
  1431.                &! comp_timecode (&video_next_SCR, &video_au.DTS))
  1432.         {
  1433.             if(!output_video(¤t_SCR, &SCR_video_delay, vunits_info,
  1434.                         istream_v, ostream, &pack, &sys_header, §or,
  1435.                         &video_buffer, &video_au, picture_start,
  1436.                         bytes_output, mux_rate, audio_buffer_size, video_buffer_size,
  1437.                         packet_data_size, marker_pack, which_streams))
  1438.             {
  1439.                 ret = TR_OUTPUT_VIDRO_ERR;
  1440.                 goto END_OUTPUT_STREAM;
  1441.             }
  1442.         }
  1443.         else
  1444.         {
  1445.             output_padding(¤t_SCR, ostream, &pack, &sys_header,
  1446.                             §or, &bytes_output, mux_rate, audio_buffer_size, 
  1447.                             video_buffer_size,packet_data_size, marker_pack, which_streams);
  1448.  
  1449.         }
  1450.     }
  1451.  
  1452.  
  1453.     /* ISO 11172 END CODE schreiben                */
  1454.     /* write out ISO 11172 END CODE                */
  1455.     index = sector.buf;
  1456.  
  1457.     *(index++) = (unsigned char)((ISO11172_END)>>24);
  1458.     *(index++) = (unsigned char)((ISO11172_END & 0x00ff0000)>>16);
  1459.     *(index++) = (unsigned char)((ISO11172_END & 0x0000ff00)>>8);
  1460.     *(index++) = (unsigned char)(ISO11172_END & 0x000000ff);
  1461.  
  1462.     WriteFile(ostream,sector.buf,4, &dwResult, NULL);
  1463.     //fwrite (sector.buf, sizeof (unsigned char), 4, ostream);
  1464.     bytes_output += 4;
  1465.  
  1466.     ret = TR_OK;
  1467. END_OUTPUT_STREAM:
  1468.  
  1469.     if(ostream!=NULL)
  1470.         CloseHandle(ostream);
  1471.     if(aunits_info!=NULL)
  1472.         CloseHandle(aunits_info);
  1473.     if(vunits_info!=NULL)
  1474.         CloseHandle(vunits_info);
  1475.     if(istream_a!=NULL)
  1476.         CloseHandle(istream_a);
  1477.     if(istream_v!=NULL)
  1478.         CloseHandle(istream_v);
  1479.  
  1480.  
  1481.     //if (which_streams & STREAMS_VIDEO) unlink (video_units);
  1482.     //if (which_streams & STREAMS_AUDIO) unlink (audio_units); 
  1483.     
  1484.     return ret;
  1485. }
  1486.  
  1487. EXPORT TOMPGRET CALLBACK TOMPEG_ConvAudioAndVideo(const char *vfile,
  1488.                                                    const char *afile,
  1489.                                                    const char *mfile,
  1490.                                                    bool(* CallBack)(TOMPEG_PROCESS_PARAM,int))
  1491. {
  1492.     char    video_units[260];
  1493.     char    audio_units[260];
  1494.     char    tmp_file_path[260];
  1495.  
  1496.     Video_struc video_info;
  1497.     Audio_struc audio_info;
  1498.     unsigned int audio_bytes, video_bytes;
  1499.     unsigned int which_streams = STREAMS_BOTH;
  1500.     double    startup_delay = 0;
  1501.     TOMPGRET ret;
  1502.  
  1503.     if(!check_files(vfile, afile, mfile,
  1504.          audio_bytes, video_bytes, which_streams))
  1505.     {
  1506.         return TR_CHECK_FILE_ERR;
  1507.     }
  1508.  
  1509.     empty_video_struc (&video_info);
  1510.     empty_audio_struc (&audio_info);
  1511.  
  1512.     // êΩÄ₧âtâ@âCâïé≡ì∞ɼé╖éΘâpâXé≡ĵô╛é╖éΘ
  1513.     GetTempPath(sizeof(tmp_file_path),tmp_file_path);
  1514.     
  1515.     if (which_streams & STREAMS_VIDEO)
  1516.     {
  1517.         GetTempFileName(tmp_file_path,"tpv",0,video_units);
  1518.         //video_units=tempnam ("./","tmp_v");
  1519.         // ê╚æOé╠êΩÄ₧âtâ@âCâïé═ìφÅ£é╡é─é¿é¡
  1520.         DeleteFile(video_units);
  1521.         if((ret = get_info_video (vfile, video_units, &video_info, startup_delay,
  1522.                 video_bytes,CallBack))!=TR_OK)
  1523.         {
  1524.             return ret;
  1525.         }
  1526.     }
  1527.  
  1528.     if (which_streams & STREAMS_AUDIO)
  1529.     {
  1530.         GetTempFileName(tmp_file_path,"tpa",0,audio_units);
  1531.         //audio_units=tempnam ("./","tmp_a");
  1532.         // ê╚æOé╠êΩÄ₧âtâ@âCâïé═ìφÅ£é╡é─é¿é¡
  1533.         DeleteFile(audio_units);
  1534.         if((ret = get_info_audio (afile, audio_units, &audio_info, startup_delay,
  1535.                 audio_bytes,CallBack))!=TR_OK)
  1536.         {
  1537.             return ret;
  1538.         }
  1539.     }
  1540.  
  1541.     if((ret = outputstream(vfile, video_units, &video_info, afile, audio_units, &audio_info, mfile, which_streams))!=TR_OK)
  1542.     {
  1543.         return ret;
  1544.     }
  1545.  
  1546.     if(which_streams & STREAMS_VIDEO)
  1547.         DeleteFile(video_units);
  1548.  
  1549.     if(which_streams & STREAMS_AUDIO)
  1550.          DeleteFile(audio_units); 
  1551.  
  1552.     return TR_OK;    
  1553. }
  1554.  
  1555.             
  1556.