Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.0 / mplexlo / mplex.c
diff --git a/cinelerra-5.0/mplexlo/mplex.c b/cinelerra-5.0/mplexlo/mplex.c
deleted file mode 100644 (file)
index be372d1..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-
-
-#include "libzmpeg3.h"
-
-#define PACKET_SIZE 2048
-
-class multiplexer_t {
-public:
-       int derivative;
-       unsigned char packet_buffer[PACKET_SIZE];
-       FILE *out_file;
-};
-
-class track_t {
-public:
-       void *operator new(size_t n) {
-               void *t = (void*) new char[n];
-               memset(t,0,n);
-               return t;
-       }
-       void operator delete(void *t,size_t n) {
-               delete[](char*)t;
-       }
-       long bytes_decoded;
-       long frames_decoded;
-       long samples_decoded;
-       mpeg3_t *file;
-       FILE *raw_file;
-       int stream_number;
-       int end_of_data;
-};
-
-int write_pack_header(unsigned char *ptr, 
-               multiplexer_t *mplex, 
-               float seconds,
-               int stream_id,
-               int ac3)
-{
-       int packet_length;
-// PACK START CODE
-       *ptr++ = 0x00;
-       *ptr++ = 0x00;
-       *ptr++ = 0x01;
-       *ptr++ = 0xba;
-
-       if(mplex->derivative == 1)
-       {
-               unsigned long timestamp = (unsigned long)(seconds * 90000);
-               *ptr = 0x20;
-               *ptr++ |= ((timestamp & 0xc0000000) >> 29) | 1;
-               *ptr++ =  (timestamp & 0x3fc00000) >> 22;
-               *ptr++ =  ((timestamp & 0x003f8000) >> 14) | 1;
-               *ptr++ =  (timestamp & 0x00007f80) >> 7;
-               *ptr++ =  ((timestamp & 0x0000007f) << 1) | 1;
-
-               *ptr++ = 0;
-               *ptr++ = 0;
-               *ptr++ = 0;
-       }
-       else
-       if(mplex->derivative == 2)
-       {
-               *ptr = 0x40;
-       }
-
-       *ptr++ = 0x00;
-       *ptr++ = 0x00;
-       *ptr++ = 0x01;
-       if(ac3) 
-               *ptr++ = 0xbd;
-       else
-               *ptr++ = stream_id;
-
-// Packet length
-       packet_length = PACKET_SIZE - (ptr - mplex->packet_buffer) - 2;
-       *ptr++ = (packet_length & 0xff00) >> 8;
-       *ptr++ = packet_length & 0xff;
-
-// Pts/dts flags
-       *ptr++ = 0x0f;
-
-// AC3 stream_id
-       if(ac3)
-       {
-               *ptr++ = stream_id;
-               *ptr++ = 0x00;
-               *ptr++ = 0x00;
-               *ptr++ = 0x00;
-       }
-
-       return PACKET_SIZE - (ptr - mplex->packet_buffer);
-}
-
-int write_packet(track_t *track, 
-               float start_time, 
-               float end_time, 
-               multiplexer_t *mplex,
-               int stream_id,
-               int ac3)
-{
-       int result = 0;
-       
-       long bytes_needed = track->bytes_decoded - ftell(track->raw_file);
-       long current_byte = 0;
-
-       while(current_byte < bytes_needed)
-       {
-// Write packet header
-               float current_time = start_time + (float)current_byte / bytes_needed * (end_time - start_time);
-               int packet_bytes = write_pack_header(mplex->packet_buffer, 
-                       mplex, 
-                       current_time,
-                       stream_id,
-                       ac3);
-               unsigned char *ptr = mplex->packet_buffer + PACKET_SIZE - packet_bytes;
-               /*int bytes_read =*/ fread(ptr, 1, packet_bytes, track->raw_file);
-
-               result = !fwrite(mplex->packet_buffer, PACKET_SIZE, 1, mplex->out_file);
-               current_byte += packet_bytes;
-       }
-       return result;
-}
-
-int main(int argc, char *argv[])
-{
-       int streams = 0;
-       int stream = 0;
-       int result = 0;
-       track_t *atracks[streams + 1];
-       track_t *vtracks[streams + 1];
-       int total_atracks = 0;
-       int total_vtracks = 0;
-       float frame_rate = 30000.0 / 1001.0;
-       float sample_rate = 48000;
-       long frames_decoded = 0;
-       float *audio_temp = new float[1];
-       long audio_temp_allocated = 0;
-       float current_time = 0, previous_time = 0;
-       int video_completed = 0;
-       int audio_completed = 0;
-       int i;
-       int ac3 = 0;
-       multiplexer_t mplex;
-       char **path;
-       char *output_path = 0;
-       int old_percentage = 0;
-       
-       path = new char*[argc];
-       mplex.derivative = 1;
-       mplex.out_file = 0;
-
-       if(argc < 4)
-       {
-               printf("Tiny MPLEX by Heroine Virtual Ltd.\n");
-               printf("Usage: mplex [-a] <stream 1> <stream2> ... <output>\n");
-               printf("        -a use ac3 packet headers\n");
-               exit(1);
-       }
-
-       for(i = 1; i < argc; i++)
-       {
-               if(!strcmp(argv[i], "-a"))
-               {
-                       ac3 = 1;
-               }
-               else
-               if(i == argc - 1)
-               {
-                       output_path = argv[i];
-               }
-               else
-               {
-                       path[stream] = new char[strlen(argv[i])+1];
-                       strcpy(path[stream], argv[i]);
-                       streams++;
-                       stream++;
-               }
-       }
-
-// Open files
-       for(stream = 0; stream < streams; stream++)
-       {
-               int is_audio, is_video;
-               int error_return;
-               mpeg3_t *file = mpeg3_open(path[stream], &error_return);
-
-               if(!file)
-               {
-                       printf("Couldn't open %s\n", path[stream]);
-                       result = 1;
-               }
-               else
-               {
-                       is_audio = mpeg3_has_audio(file);
-                       is_video = mpeg3_has_video(file);
-                       mpeg3_set_cpus(file, 2);
-
-                       if(is_audio && is_video)
-                       {
-                               printf("%s: Can't multiplex a system stream.\n", path[stream]);
-                               result = 1;
-                       }
-                       else
-                       if(is_audio)
-                       {
-                               atracks[total_atracks] = new track_t();
-                               atracks[total_atracks]->file = file;
-                               sample_rate = mpeg3_sample_rate(file, 0);
-                               atracks[total_atracks]->raw_file = fopen(path[stream], "rb");
-                               atracks[total_atracks]->stream_number = total_atracks;
-                               total_atracks++;
-                       }
-                       else
-                       if(is_video)
-                       {
-                               vtracks[total_vtracks] = new track_t();
-                               vtracks[total_vtracks]->file = file;
-                               frame_rate = mpeg3_frame_rate(file, 0);
-                               vtracks[total_vtracks]->raw_file = fopen(path[stream], "rb");
-                               vtracks[total_vtracks]->stream_number = total_vtracks;
-// Get the first frame
-                               mpeg3_skip_video_frame(vtracks[total_vtracks]->file,0);
-                               total_vtracks++;
-                       }
-                       else
-                       {
-                               printf("%s: Has neither audio or video.\n", path[stream]);
-                               result = 1;
-                       }
-               }
-       }
-
-       if(!result)
-       {
-               if(!total_vtracks)
-               {
-                       printf("You must supply at least 1 video track.\n");
-                       result = 1;
-               }
-       }
-
-// Open output
-       if(!result)
-               if(!(mplex.out_file = fopen(output_path, "wb")))
-               {
-                       printf("Couldn't open output file\n");
-                       result = 1;
-               }
-
-// Write multiplexed stream
-       if(!result)
-       {
-               while(!result && !(video_completed && audio_completed))
-               {
-                       previous_time = current_time;
-// Want the frame to come before the audio that goes with it.
-                       for(stream = 0; stream < total_vtracks && !result; stream++)
-                       {
-// Decode a frame and write it
-                               track_t *track = vtracks[stream];
-
-                               if(!track->end_of_data)
-                               {
-                                       int percentage;
-                                       mpeg3_skip_video_frame(track->file,0);
-                                       track->frames_decoded++;
-                                       track->bytes_decoded = mpeg3_video_tell_byte(track->file,0);
-                                       if(track->frames_decoded > frames_decoded)
-                                       {
-                                               frames_decoded = track->frames_decoded;
-                                               current_time = (float)frames_decoded / frame_rate;
-                                       }
-
-                                       result = write_packet(track, 
-                                                                       previous_time, 
-                                                                       current_time, 
-                                                                       &mplex,
-                                                                       0xe0 | track->stream_number,
-                                                                       0);
-                                   track->end_of_data = mpeg3_end_of_video(track->file, 0);
-                                       percentage = (int)(mpeg3_video_tell_byte(track->file,0) * 100 / 
-                                               mpeg3_get_bytes(track->file));
-                                       if(percentage - old_percentage >= 1)
-                                       {
-                                               printf("\t%d%% completed\r", percentage);
-                                               old_percentage = percentage;
-                                       }
-                                       fflush(stdout);
-                               }
-                       }
-
-// Decode audio until the last frame is covered
-                       for(stream = 0; stream < total_atracks && !result; stream++)
-                       {
-                               track_t *track = atracks[stream];
-//printf("mplex decode audio 1\n");
-                               if(!track->end_of_data &&
-                                       (track->samples_decoded < current_time * sample_rate ||
-                                               video_completed))
-                               {
-                                       if(!video_completed)
-                                       {
-                                               long samples_needed = (long)(current_time * sample_rate) - track->samples_decoded;
-                                               if(audio_temp_allocated < samples_needed)
-                                               {
-                                                       delete [] audio_temp;
-                                                       audio_temp = new float[samples_needed];
-                                                       audio_temp_allocated = samples_needed;
-                                               }
-
-                                               mpeg3_read_audio(track->file,
-                                                       audio_temp,
-                                                       0,
-                                                       0,
-                                                       samples_needed,
-                                                       0);
-                                               track->bytes_decoded = mpeg3_audio_tell_byte(track->file,0);
-                                               if(!track->end_of_data) track->bytes_decoded -= 2048;
-                                               track->samples_decoded += samples_needed;
-                                               track->end_of_data = mpeg3_end_of_audio(track->file, 0);
-                                       }
-                                       else
-                                       {
-                                               track->bytes_decoded = mpeg3_get_bytes(track->file);
-                                               track->end_of_data = 1;
-                                       }
-
-//printf("mplex decode audio 2\n");
-                                       result = write_packet(track, 
-                                               previous_time, 
-                                               current_time, 
-                                               &mplex,
-                                               ac3 ? track->stream_number : (0xc0 | track->stream_number),
-                                               ac3);
-                               }
-                       }
-
-                       for(stream = 0; stream < total_vtracks; stream++)
-                       {
-                               if(vtracks[stream]->end_of_data) video_completed++;
-                       }
-                       if(video_completed < total_vtracks) video_completed = 0;
-
-                       for(stream = 0; stream < total_atracks; stream++)
-                       {
-                               if(atracks[stream]->end_of_data) audio_completed++;
-                       }
-                       if(audio_completed < total_atracks) audio_completed = 0;
-               }
-       }
-
-// Close streams
-       for(stream = 0; stream < total_atracks; stream++)
-       {
-               mpeg3_close(atracks[stream]->file);
-               fclose(atracks[stream]->raw_file);
-               delete atracks[stream];
-       }
-
-       for(stream = 0; stream < total_vtracks; stream++)
-       {
-               mpeg3_close(vtracks[stream]->file);
-               fclose(vtracks[stream]->raw_file);
-               delete vtracks[stream];
-       }
-       
-       if(mplex.out_file) fclose(mplex.out_file);
-
-       return result;
-}
-
-