#include "common.h" #include #include // setprecision #include #include extern "C" { #include "libavcodec/avcodec.h" } #include "libavutil/ffversion.h" #ifndef UNTR_VERSION #define UNTR_VERSION "?" #endif // http://git.ffmpeg.org/gitweb/ffmpeg.git/commit/061a0c14bb57 #if (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 107, 100)) const bool is_new_ffmpeg_api = false; #else const bool is_new_ffmpeg_api = true; #endif using namespace std; LogMode g_log_mode = LogMode::I; size_t g_max_partsize = 1600000; bool g_interactive = true; bool g_muted = false; bool g_ignore_unknown = false; bool g_stretch_video = false; std::string g_version_str = "version '" UNTR_VERSION "' using ffmpeg '" FFMPEG_VERSION "'"; uint16_t swap16(uint16_t us) { return (us >> 8) | (us << 8); } uint32_t swap32(uint32_t ui) { return (ui >> 24) | ((ui<<8) & 0x00FF0000) | ((ui>>8) & 0x0000FF00) | (ui << 24); } uint64_t swap64(uint64_t ull) { return (ull >> 56) | ((ull<<40) & 0x00FF000000000000) | ((ull<<24) & 0x0000FF0000000000) | ((ull<<8) & 0x000000FF00000000) | ((ull>>8) & 0x00000000FF000000) | ((ull>>24) & 0x0000000000FF0000) | ((ull>>40) & 0x000000000000FF00) | (ull << 56); } int readGolomb(const uchar *&buffer, int &offset) { //count the zeroes; int count = 0; //count the leading zeroes while((*buffer & (0x1<<(7 - offset))) == 0) { count++; offset++; if(offset == 8) { buffer++; offset = 0; } if(count > 20) { cout << "Failed reading golomb: too large!\n"; return -1; } } //skip the single 1 delimiter offset++; if(offset == 8) { buffer++; offset = 0; } uint32_t res = 1; //read count bits while(count-- > 0) { res <<= 1; res |= (*buffer & (0x1<<(7 - offset))) >> (7 - offset); offset++; if(offset == 8) { buffer++; offset = 0; } } return res-1; } void printBuffer(const uchar* pos, int n){ cout << mkHexStr(pos, n, true) << '\n'; } string mkHexStr(const uchar* pos, int n, bool bytes_seperated){ stringstream out; out << hex; for (int i=0; i != n; ++i) { int x = (int) *(pos+i); if (x < 16) out << '0'; out << x << (bytes_seperated?" ":""); } return out.str(); } uint readBits(int n, const uchar *&buffer, int &offset) { uint res = 0; int d = 8 - offset; uint mask = ((1 << d)-1); int to_rshift = d - n; if (to_rshift > 0){ res = (*buffer & mask) >> to_rshift; offset += n; } else if (to_rshift == 0){ res = (*buffer & mask); buffer++; offset = 0; } else { res = (*buffer & mask); n -= d; buffer++; offset = 0; while (n >= 8){ res <<= 8; res |= *buffer; n -= 8; buffer++; } if(n > 0){ offset = n; res <<= n; res |= *buffer >> (8-n); } } return res; } // not working correctly //uint readBits(int n, uchar *&buffer, int &offset) { // int res = 0; // while(n + offset > 8) { //can't read in a single reading // int d = 8 - offset; // res <<= d; // res |= *buffer & ((1<> d) & ((1 << n) - 1); // return res; //} void hitEnterToContinue() { if (g_interactive) { cout << " Hit enter to continue." << endl; getchar(); } // else cout << '\n'; } void outProgress(double now, double all) { double x = round(1000*(now/all)); cout << x/10 << "% \r" << flush; } void mute() { g_muted = true; av_log_set_level(AV_LOG_QUIET); } void unmute() { g_muted = false; if(g_log_mode < V) av_log_set_level(AV_LOG_WARNING); else if(g_log_mode > V) av_log_set_level(AV_LOG_DEBUG); } string pretty_bytes(uint num) { uint idx = 0; vector units = {"","Ki","Mi","Gi","Ti","Pi","Ei","Zi"}; while (idx+1 < units.size()) { if (num < 1024) break; num /= 1024; idx++; } stringstream s; s << setprecision(3) << num << units[idx] << "B"; return s.str(); }