summaryrefslogtreecommitdiff
path: root/tools/qt-faststart.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/qt-faststart.c')
-rw-r--r--tools/qt-faststart.c57
1 files changed, 42 insertions, 15 deletions
diff --git a/tools/qt-faststart.c b/tools/qt-faststart.c
index f33d6fa80c..c9aa6e8287 100644
--- a/tools/qt-faststart.c
+++ b/tools/qt-faststart.c
@@ -8,7 +8,7 @@
* is in front of the data, thus facilitating network streaming.
*
* To compile this program, start from the base directory from which you
- * are building Libav and type:
+ * are building FFmpeg and type:
* make tools/qt-faststart
* The qt-faststart program will be built in the tools/ directory. If you
* do not build the program in this manner, correct results are not
@@ -37,6 +37,8 @@
#define ftello(x) _ftelli64(x)
#endif
+#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
+
#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
#define BE_32(x) ((((uint8_t*)(x))[0] << 24) | \
@@ -77,7 +79,7 @@
#define CO64_ATOM QT_ATOM('c', 'o', '6', '4')
#define ATOM_PREAMBLE_SIZE 8
-#define COPY_BUFFER_SIZE 1024
+#define COPY_BUFFER_SIZE 33554432
int main(int argc, char *argv[])
{
@@ -95,8 +97,8 @@ int main(int argc, char *argv[])
uint64_t i, j;
uint32_t offset_count;
uint64_t current_offset;
- uint64_t start_offset = 0;
- unsigned char copy_buffer[COPY_BUFFER_SIZE];
+ int64_t start_offset = 0;
+ unsigned char *copy_buffer = NULL;
int bytes_to_copy;
if (argc != 3) {
@@ -134,22 +136,27 @@ int main(int argc, char *argv[])
atom_size);
goto error_out;
}
- fseeko(infile, -ATOM_PREAMBLE_SIZE, SEEK_CUR);
- if (fread(ftyp_atom, atom_size, 1, infile) != 1) {
+ if ( fseeko(infile, -ATOM_PREAMBLE_SIZE, SEEK_CUR)
+ || fread(ftyp_atom, atom_size, 1, infile) != 1
+ || (start_offset = ftello(infile))<0) {
perror(argv[1]);
goto error_out;
}
- start_offset = ftello(infile);
} else {
+ int ret;
/* 64-bit special case */
if (atom_size == 1) {
if (fread(atom_bytes, ATOM_PREAMBLE_SIZE, 1, infile) != 1) {
break;
}
atom_size = BE_64(&atom_bytes[0]);
- fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE * 2, SEEK_CUR);
+ ret = fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE * 2, SEEK_CUR);
} else {
- fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE, SEEK_CUR);
+ ret = fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE, SEEK_CUR);
+ }
+ if(ret) {
+ perror(argv[1]);
+ goto error_out;
}
}
printf("%c%c%c%c %10"PRIu64" %"PRIu64"\n",
@@ -190,7 +197,10 @@ int main(int argc, char *argv[])
/* moov atom was, in fact, the last atom in the chunk; load the whole
* moov atom */
- fseeko(infile, -atom_size, SEEK_END);
+ if (fseeko(infile, -atom_size, SEEK_END)) {
+ perror(argv[1]);
+ goto error_out;
+ }
last_offset = ftello(infile);
moov_atom_size = atom_size;
moov_atom = malloc(moov_atom_size);
@@ -225,6 +235,10 @@ int main(int argc, char *argv[])
goto error_out;
}
offset_count = BE_32(&moov_atom[i + 8]);
+ if (i + 12LL + offset_count * 4LL > moov_atom_size) {
+ printf(" bad atom size\n");
+ goto error_out;
+ }
for (j = 0; j < offset_count; j++) {
current_offset = BE_32(&moov_atom[i + 12 + j * 4]);
current_offset += moov_atom_size;
@@ -242,6 +256,10 @@ int main(int argc, char *argv[])
goto error_out;
}
offset_count = BE_32(&moov_atom[i + 8]);
+ if (i + 12LL + offset_count * 8LL > moov_atom_size) {
+ printf(" bad atom size\n");
+ goto error_out;
+ }
for (j = 0; j < offset_count; j++) {
current_offset = BE_64(&moov_atom[i + 12 + j * 8]);
current_offset += moov_atom_size;
@@ -266,7 +284,11 @@ int main(int argc, char *argv[])
}
if (start_offset > 0) { /* seek after ftyp atom */
- fseeko(infile, start_offset, SEEK_SET);
+ if (fseeko(infile, start_offset, SEEK_SET)) {
+ perror(argv[1]);
+ goto error_out;
+ }
+
last_offset -= start_offset;
}
@@ -293,12 +315,15 @@ int main(int argc, char *argv[])
}
/* copy the remainder of the infile, from offset 0 -> last_offset - 1 */
+ bytes_to_copy = FFMIN(COPY_BUFFER_SIZE, last_offset);
+ copy_buffer = malloc(bytes_to_copy);
+ if (!copy_buffer) {
+ printf("could not allocate %d bytes for copy_buffer\n", bytes_to_copy);
+ goto error_out;
+ }
printf(" copying rest of file...\n");
while (last_offset) {
- if (last_offset > COPY_BUFFER_SIZE)
- bytes_to_copy = COPY_BUFFER_SIZE;
- else
- bytes_to_copy = last_offset;
+ bytes_to_copy = FFMIN(bytes_to_copy, last_offset);
if (fread(copy_buffer, bytes_to_copy, 1, infile) != 1) {
perror(argv[1]);
@@ -315,6 +340,7 @@ int main(int argc, char *argv[])
fclose(outfile);
free(moov_atom);
free(ftyp_atom);
+ free(copy_buffer);
return 0;
@@ -325,5 +351,6 @@ error_out:
fclose(outfile);
free(moov_atom);
free(ftyp_atom);
+ free(copy_buffer);
return 1;
}