ivfrate.cpp
1 2 #include "compat.h" 3 #ifndef USE_OPENGL 4 # define USE_OPENGL 5 #endif 6 #define ANIMVPX_STANDALONE 7 #include "animvpx.h" 8 9 10 static void print_info(const char *prefix, const animvpx_ivf_header_t *hdr) 11 { 12 printf("%s%d x %d, %d frames @ %d frames / %d seconds (%.3f fps%s)\n", prefix, 13 hdr->width, hdr->height, hdr->numframes, hdr->fpsnumer, hdr->fpsdenom, 14 (hdr->fpsdenom==0 ? 0 : (double)hdr->fpsnumer/hdr->fpsdenom), 15 hdr->fpsnumer>=1000 ? " --> 30 fps" : ""); 16 } 17 18 19 int main(int argc, char **argv) 20 { 21 int fd, dowrite, err; 22 animvpx_ivf_header_t hdr; 23 24 union { uint16_t i; char c[2]; } u; 25 u.c[0] = 1; 26 u.c[1] = 0; 27 if (u.i != 1) 28 { 29 fprintf(stderr, "This program is only for little-endian machines.\n"); 30 return 255; 31 } 32 33 if (argc == 2 && argv[1][0]=='-') 34 goto usage; 35 36 if (argc != 2 && argc != 4 && argc != 5) 37 { 38 usage: 39 fprintf(stderr, "Usage: %s <file.ivf> [<fpsnumerator> <fpsdenominator> [-force]]\n" 40 " Without -force, <fpsnumerator> must be < 1000.\n" 41 " If <fpsnumerator> is >= 1000, the actual frame rate\n" 42 " is set to 30 fps on playback.\n", 43 argv[0]); 44 return 1; 45 } 46 47 dowrite = (argc >= 4); 48 49 fd = open(argv[1], dowrite ? O_RDWR : O_RDONLY); 50 if (fd < 0) 51 { 52 fprintf(stderr, "Could't open \"%s\" for %s: %s\n", argv[1], 53 dowrite ? "reading/writing":"reading", strerror(errno)); 54 return 2; 55 } 56 57 if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) 58 { 59 fprintf(stderr, "Couldn't read IVF header: %s\n", strerror(errno)); 60 return 3; 61 } 62 63 err = animvpx_check_header(&hdr); 64 if (err) 65 { 66 fprintf(stderr, "Header check failed with code %d (not an IVF file?)\n", err); 67 return 4; 68 } 69 70 if (!dowrite) 71 { 72 print_info("", &hdr); 73 } 74 else 75 { 76 unsigned long numer = strtoul(argv[2], NULL, 10); 77 unsigned long denom = strtoul(argv[3], NULL, 10); 78 uint32_t numer32=numer, denom32=denom; 79 const int NUMER_OFS = 16; //offsetof(animvpx_ivf_header_t, fpsnumer); 80 81 if (denom == 0) 82 { 83 fprintf(stderr, "FPS denominator must not be zero!\n"); 84 return 4; 85 } 86 87 if (numer >= 1000 && (argc!=5 || strcmp(argv[4], "-force"))) 88 { 89 fprintf(stderr, "FPS numerator must be < 1000, or -force must be passed as 5th arg.\n"); 90 return 5; 91 } 92 93 if (numer32 != numer || denom32 != denom) 94 { 95 fprintf(stderr, "Out of range number passed.\n"); 96 return 6; 97 } 98 99 print_info("Old: ", &hdr); 100 hdr.fpsnumer = numer32; 101 hdr.fpsdenom = denom32; 102 print_info("New: ", &hdr); 103 104 if (lseek(fd, NUMER_OFS, SEEK_SET) != NUMER_OFS) 105 { 106 fprintf(stderr, "lseek failed: %s\n", strerror(errno)); 107 return 7; 108 } 109 110 err = 0; 111 err |= (write(fd, &numer32, 4) != 4); 112 err |= (write(fd, &denom32, 4) != 4); 113 114 if (err) 115 { 116 fprintf(stderr, "Warning: data not fully written.\n"); 117 return 8; 118 } 119 } 120 121 return 0; 122 }