r1053: Add Russian translation.
[cinelerra_cv.git] / libmpeg3 / mpeg3split.c
blob96f24311fe2a50bbaa3005e15ad4af291b87d378
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
5 #include "mpeg3private.inc"
7 void copy_data(FILE *out, FILE *in, long bytes)
9 long fragment_size = 0x100000;
10 char *buffer = malloc(fragment_size);
11 long i;
13 for(i = 0; i < bytes; i += fragment_size)
15 if(i + fragment_size > bytes) fragment_size = bytes - i;
16 if(!fread(buffer, 1, fragment_size, in))
18 perror("copy_data");
20 if(!fwrite(buffer, 1, fragment_size, out))
22 perror("copy_data");
26 free(buffer);
29 void split_video(char *path, long default_fragment_size)
31 long current_byte = 0;
32 int result = 0;
33 int i = 0;
34 long total_bytes;
35 FILE *in = fopen(path, "r");
36 char *sequence_hdr;
37 long sequence_hdr_size;
38 unsigned long header = 0;
39 long header_start;
40 long header_end;
42 if(!in)
44 perror("split_file");
45 return;
47 fseek(in, 0, SEEK_END);
48 total_bytes = ftell(in);
49 fseek(in, 0, SEEK_SET);
51 // Copy sequence header
52 do{
53 header <<= 8;
54 header = (header & 0xffffffff) | getc(in);
55 }while(header != MPEG3_SEQUENCE_START_CODE && !feof(in));
57 header_start = ftell(in) - 4;
58 do{
59 header <<= 8;
60 header = (header & 0xffffffff) | getc(in);
61 }while(header != MPEG3_GOP_START_CODE && !feof(in));
62 header_end = ftell(in) - 4;
64 sequence_hdr_size = header_end - header_start;
65 sequence_hdr = malloc(sequence_hdr_size);
66 fseek(in, header_start, SEEK_SET);
67 fread(sequence_hdr, 1, sequence_hdr_size, in);
68 fseek(in, 0, SEEK_SET);
70 while(current_byte < total_bytes && !result)
72 FILE *out;
73 char outpath[1024];
74 long fragment_size;
76 sprintf(outpath, "%s%02d", path, i);
77 out = fopen(outpath, "w");
78 if(!out)
80 perror("split_file");
81 break;
84 // Default fragment size
85 fragment_size = default_fragment_size;
86 // Corrected fragment size
87 if(current_byte + fragment_size >= total_bytes)
89 fragment_size = total_bytes - current_byte;
91 else
93 header = 0;
95 // Get GOP header
96 fseek(in, current_byte + fragment_size, SEEK_SET);
99 fseek(in, -1, SEEK_CUR);
100 header >>= 8;
101 header |= ((unsigned long)fgetc(in)) << 24;
102 fseek(in, -1, SEEK_CUR);
103 }while(ftell(in) > 0 && header != MPEG3_GOP_START_CODE);
104 fragment_size = ftell(in) - current_byte;
105 fseek(in, current_byte, SEEK_SET);
108 // Put sequence header
109 if(current_byte > 0)
111 fwrite(sequence_hdr, 1, sequence_hdr_size, out);
114 // Put data
115 copy_data(out, in, fragment_size);
117 fclose(out);
118 i++;
119 current_byte += fragment_size;
121 free(sequence_hdr);
124 int main(int argc, char *argv[])
126 long bytes = 0;
127 int i;
129 if(argc < 2)
131 fprintf(stderr, "Split elementary streams into chunks of bytes.\n"
132 "Usage: mpeg3split -b bytes <infile>\n");
133 exit(1);
136 for(i = 1; i < argc; i++)
138 if(!strcmp(argv[i], "-b"))
140 if(i < argc - 1)
142 i++;
143 bytes = atol(argv[i]);
145 else
147 fprintf(stderr, "-b must be paired with a value\n");
148 exit(1);
151 else
152 if(bytes > 0)
154 // Split a file
155 split_video(argv[i], bytes);
157 else
159 fprintf(stderr, "No value for bytes specified,\n");
160 exit(1);