00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004
00005 #include "mpeg3private.inc"
00006
00007 void copy_data(FILE *out, FILE *in, long bytes)
00008 {
00009 long fragment_size = 0x100000;
00010 char *buffer = malloc(fragment_size);
00011 long i;
00012
00013 for(i = 0; i < bytes; i += fragment_size)
00014 {
00015 if(i + fragment_size > bytes) fragment_size = bytes - i;
00016 if(!fread(buffer, 1, fragment_size, in))
00017 {
00018 perror("copy_data");
00019 }
00020 if(!fwrite(buffer, 1, fragment_size, out))
00021 {
00022 perror("copy_data");
00023 }
00024 }
00025
00026 free(buffer);
00027 }
00028
00029 void split_video(char *path, long default_fragment_size)
00030 {
00031 long current_byte = 0;
00032 int result = 0;
00033 int i = 0;
00034 long total_bytes;
00035 FILE *in = fopen(path, "r");
00036 char *sequence_hdr;
00037 long sequence_hdr_size;
00038 unsigned long header = 0;
00039 long header_start;
00040 long header_end;
00041
00042 if(!in)
00043 {
00044 perror("split_file");
00045 return;
00046 }
00047 fseek(in, 0, SEEK_END);
00048 total_bytes = ftell(in);
00049 fseek(in, 0, SEEK_SET);
00050
00051
00052 do{
00053 header <<= 8;
00054 header = (header & 0xffffffff) | getc(in);
00055 }while(header != MPEG3_SEQUENCE_START_CODE && !feof(in));
00056
00057 header_start = ftell(in) - 4;
00058 do{
00059 header <<= 8;
00060 header = (header & 0xffffffff) | getc(in);
00061 }while(header != MPEG3_GOP_START_CODE && !feof(in));
00062 header_end = ftell(in) - 4;
00063
00064 sequence_hdr_size = header_end - header_start;
00065 sequence_hdr = malloc(sequence_hdr_size);
00066 fseek(in, header_start, SEEK_SET);
00067 fread(sequence_hdr, 1, sequence_hdr_size, in);
00068 fseek(in, 0, SEEK_SET);
00069
00070 while(current_byte < total_bytes && !result)
00071 {
00072 FILE *out;
00073 char outpath[1024];
00074 long fragment_size;
00075
00076 sprintf(outpath, "%s%02d", path, i);
00077 out = fopen(outpath, "w");
00078 if(!out)
00079 {
00080 perror("split_file");
00081 break;
00082 }
00083
00084
00085 fragment_size = default_fragment_size;
00086
00087 if(current_byte + fragment_size >= total_bytes)
00088 {
00089 fragment_size = total_bytes - current_byte;
00090 }
00091 else
00092 {
00093 header = 0;
00094
00095
00096 fseek(in, current_byte + fragment_size, SEEK_SET);
00097 do
00098 {
00099 fseek(in, -1, SEEK_CUR);
00100 header >>= 8;
00101 header |= ((unsigned long)fgetc(in)) << 24;
00102 fseek(in, -1, SEEK_CUR);
00103 }while(ftell(in) > 0 && header != MPEG3_GOP_START_CODE);
00104 fragment_size = ftell(in) - current_byte;
00105 fseek(in, current_byte, SEEK_SET);
00106 }
00107
00108
00109 if(current_byte > 0)
00110 {
00111 fwrite(sequence_hdr, 1, sequence_hdr_size, out);
00112 }
00113
00114
00115 copy_data(out, in, fragment_size);
00116
00117 fclose(out);
00118 i++;
00119 current_byte += fragment_size;
00120 }
00121 free(sequence_hdr);
00122 }
00123
00124 int main(int argc, char *argv[])
00125 {
00126 long bytes = 0;
00127 int i;
00128
00129 if(argc < 2)
00130 {
00131 fprintf(stderr, "Split elementary streams into chunks of bytes.\n"
00132 "Usage: mpeg3split -b bytes <infile>\n");
00133 exit(1);
00134 }
00135
00136 for(i = 1; i < argc; i++)
00137 {
00138 if(!strcmp(argv[i], "-b"))
00139 {
00140 if(i < argc - 1)
00141 {
00142 i++;
00143 bytes = atol(argv[i]);
00144 }
00145 else
00146 {
00147 fprintf(stderr, "-b must be paired with a value\n");
00148 exit(1);
00149 }
00150 }
00151 else
00152 if(bytes > 0)
00153 {
00154
00155 split_video(argv[i], bytes);
00156 }
00157 else
00158 {
00159 fprintf(stderr, "No value for bytes specified,\n");
00160 exit(1);
00161 }
00162 }
00163 }
00164
00165