static unsigned FrameLength(FrameHeader fh) { unsigned bitrate = BitRate(fh); if (!bitrate) return 0; unsigned samplerate = SampleRate(fh); if (!samplerate) return 0; if (fh.s.layer == 3) return (((12*bitrate) / samplerate) + fh.s.padding) * 4; unsigned samples = 1152; if ((fh.s.version == 0 || fh.s.version == 2) && fh.s.layer == 1) samples = 576; return (samples*bitrate)/(8*samplerate) + fh.s.padding; }
bool CHolly_Theora_Video::Start() { m_bFrameWaiting = false; th_info thInfo; th_info_init( &thInfo ); thInfo.frame_width = Width(); thInfo.frame_height = Height(); thInfo.pic_width = Width(); thInfo.pic_height = Height(); thInfo.pic_x = 0; thInfo.pic_y = 0; thInfo.colorspace = TH_CS_ITU_REC_470BG; thInfo.pixel_fmt = TH_PF_420; // TH_PF_444 thInfo.target_bitrate = BitRate() * 1024; thInfo.quality = 42; thInfo.keyframe_granule_shift = 6; // default value thInfo.fps_numerator = FPS(); thInfo.fps_denominator = 1; thInfo.aspect_numerator = 1; thInfo.aspect_denominator = 1; m_Encoder = th_encode_alloc( &thInfo ); if ( !m_Encoder ) { return false; } th_info_clear( &thInfo ); SetupFrame(); WriteHeader(); return true; }
static unsigned WalkFrames(util::Stream *st, uint64_t pos, bool *ok) { uint64_t end = st->GetLength(); unsigned int nframes = 0; unsigned int nsilent = 0; bool started = false; unsigned int bitrate = 0; bool vbr = false; uint64_t streamlen = end-pos; while (pos < (end-4)) { unsigned char header[4]; st->Seek(pos); unsigned rc = st->ReadAll(header, 4); if (rc) return rc; FrameHeader fh; fh.x = read_be32(header); if (fh.s.sync != 0x7FF) { printf(" Sync lost at %llu (%08x %08x)\n", (long long unsigned)pos, fh.x, fh.s.sync); *ok = false; return 0; } unsigned int len = FrameLength(fh); if (!len) { printf(" Bogus header %08x at %llu\n", fh.x, (long long unsigned)pos); *ok = false; return 0; } if (s_frames) { printf(" 0x%08llx: frame %u\n", (unsigned long long)pos, nframes); } unsigned char frame[8192]; rc = st->ReadAll(frame, len-4); if (rc) return rc; unsigned int zeroes; if (fh.s.version == 3) { if (fh.s.channelmode == 3) zeroes = 17; else zeroes = 32; } else { if (fh.s.channelmode == 3) zeroes = 9; else zeroes = 17; } bool silent = true; for (unsigned int i=0; i<zeroes && silent; ++i) { if (frame[i]) silent = false; } if (silent && !started) { ++nsilent; if (!memcmp(frame + zeroes, "Xing", 4) || !memcmp(frame + zeroes, "Info", 4)) { if (s_all) { printf(" Info header in frame %u\n", nframes); printf(" Frame count %u\n", read_be32(frame+zeroes+8)); printf(" Stream length %u\n", read_be32(frame+zeroes+12)); } } else if (!memcmp(frame+32, "VBRI", 4)) { if (s_all) printf(" VBRI header in frame %u\n", nframes); } else { started = true; if (s_all) printf(" Audio begins in frame %u\n", nframes); } } else { if (!started) { started = true; if (s_all) printf(" Audio begins in frame %u\n", nframes); } nsilent = 0; } if (started) { unsigned frame_bitrate = BitRate(fh); if (!bitrate) bitrate = frame_bitrate; else if (bitrate != frame_bitrate) vbr = true; } ++nframes; pos += len; } if (s_all) { if (nsilent) printf(" Final %u frames silent\n", nsilent); printf(" %u frames\n", nframes); if (vbr) printf(" Variable bitrate\n"); else printf(" Bitrate=%u CBR\n", bitrate); printf(" MP3 stream length %llu\n", (unsigned long long)streamlen); } return 0; }