Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * $ gcc -Wall -O3 -o unrotate unrotate.c
- * $ ./unrotate input.mp4 output.mp4
- */
- #include <stdio.h>
- #include <inttypes.h>
- #include <sys/mman.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <string.h>
- static int fd_in = -1;
- static int fd_out = -1;
- static struct stat st;
- static const uint8_t *buf_in = NULL;
- static uint8_t *buf_out = NULL;
- static void mmap_close(void)
- {
- if (buf_out ) munmap(buf_out, st.st_size);
- if (buf_in ) munmap((void*)buf_in, st.st_size);
- if (fd_out != -1) close(fd_out);
- if (fd_in != -1) close(fd_in);
- }
- static int mmap_open(char *fname_in, char *fname_out)
- {
- int offset;
- /* Open and mmap input file */
- fd_in = open(fname_in, O_RDONLY);
- if (fd_in == -1) {
- fprintf(stderr, "could not open input file '%s'\n", fname_in);
- goto end;
- }
- if (fstat(fd_in, &st) == -1) {
- fprintf(stderr, "could not stat input file '%s'\n", fname_in);
- goto end;
- }
- buf_in = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd_in, 0);
- if (buf_in == MAP_FAILED) {
- fprintf(stderr, "could not map input file '%s'\n", fname_in);
- goto end;
- }
- /* Open and mmap output file, with same size as input file */
- fd_out = open(fname_out, O_RDWR | O_CREAT | O_TRUNC, 0666);
- if (fd_out == -1) {
- fprintf(stderr, "could not open output file '%s'\n", fname_out);
- goto end;
- }
- lseek(fd_out, st.st_size-1, SEEK_SET);
- offset = write(fd_out, "", 1);
- lseek(fd_out, 0, SEEK_SET);
- buf_out = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_out, 0);
- if (buf_out == MAP_FAILED) {
- fprintf(stderr, "could not map output file '%s'\n", fname_out);
- goto end;
- }
- return st.st_size;
- end:
- mmap_close();
- return 0;
- }
- static uint32_t read_be32(const uint8_t *p)
- {
- return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]);
- }
- static void write_be16(uint8_t *p, uint32_t val)
- {
- p[0] = (val >> 8) & 0xff;
- p[1] = (val >> 0) & 0xff;
- }
- int main(int argc, char *argv[])
- {
- unsigned int file_size;
- unsigned int i;
- int ok = 0;
- if (argc < 3) {
- fprintf(stderr, "usage: %s <input> <output>\n", argv[0]);
- return -1;
- }
- file_size = mmap_open(argv[1], argv[2]);
- if (!file_size)
- return -1;
- for (i = 0; i < 4; i++)
- buf_out[i] = buf_in[i];
- for ( ; !ok && i < file_size-(4+104); i++) {
- if ((*(uint32_t *)&buf_in[i]) == 0x64686b74) {
- uint32_t tkhd_size = read_be32(&buf_in[i-4]);
- uint8_t version = buf_in[i+4];
- uint8_t offset = (version ? 14 : 11) << 2;
- memcpy(&buf_out[i], &buf_in[i], tkhd_size);
- if (read_be32(&buf_in[i+offset+36]) && read_be32(&buf_in[i+offset+40])) {
- write_be16(&buf_out[i+offset ], 1);
- write_be16(&buf_out[i+offset+ 4], 0);
- write_be16(&buf_out[i+offset+ 8], 0);
- write_be16(&buf_out[i+offset+12], 0);
- write_be16(&buf_out[i+offset+16], 1);
- write_be16(&buf_out[i+offset+20], 0);
- fprintf(stderr, "video tkhd found and matrix changed\n");
- ok = 1;
- }
- i += tkhd_size-1;
- } else {
- buf_out[i] = buf_in[i];
- }
- }
- memcpy(&buf_out[i], &buf_in[i], file_size - i);
- mmap_close();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement