Esempio n. 1
0
void printTimeCodes(const Option &opt, TrackEditor &track)
{
#ifdef _WIN32
    utf8_codecvt_facet u8codec;
    std::wstring wname = m2w(opt.timecodeFile, utf8_codecvt_facet());
    FILE *fp = std::strcmp(opt.timecodeFile, "-")
               ? _wfopen(wname.c_str(), L"w")
               : stdout;
#else
    FILE *fp = std::strcmp(opt.timecodeFile, "-")
               ? std::fopen(opt.timecodeFile, "w")
               : stdout;
#endif
    if (!fp)
        throw std::runtime_error("Can't open timecode file");
    uint32_t timeScale = track.GetTimeScale();
    std::fputs("# timecode format v2\n", fp);
    if (track.GetFrameCount()) {
        uint64_t off = track.CTS(0);
        for (size_t i = 0; i < track.GetFrameCount(); ++i) {
            uint64_t cts = track.CTS(i) - off;
            std::fprintf(fp, "%.15g\n",
                static_cast<double>(cts) / timeScale * 1000.0);
        }
    }
    std::fclose(fp);
}
Esempio n. 2
0
ALACSink::ALACSink(const std::wstring &path, EncoderBase &encoder)
	: m_mp4file(0),
	  m_filename(path),
	  m_closed(false)
{
    static const char * const compatibleBrands[] = { "M4A ", "mp42" };

    const AudioStreamBasicDescription &format
	= encoder.getOutputBasicDescription();
    uint32_t sample_rate = static_cast<uint32_t>(format.mSampleRate);
    try {
	m_mp4file.Create(
		w2m(path, utf8_codecvt_facet()).c_str(),
		0, // flags
		1, // add_ftypes
		0, // add_iods
		"M4A ", // majorBrand
		0, // minorVersion
		const_cast<char**>(compatibleBrands), 
		array_size(compatibleBrands));

	m_mp4file.SetTimeScale(sample_rate);
	std::vector<char> cookie;
	encoder.getMagicCookie(&cookie);
	m_track_id = m_mp4file.AddAlacAudioTrack(sample_rate,
		reinterpret_cast<uint8_t*>(&cookie[20]),
		cookie.size() - 28);
    } catch (mp4v2::impl::MP4Error *e) {
	handle_mp4error(e);
    }
}
Esempio n. 3
0
void loadTimecodeV2(Option &option, size_t count)
{
    std::wstring wfname = m2w(option.timecodeFile, utf8_codecvt_facet());

    HANDLE fh = CreateFileW(wfname.c_str(), GENERIC_READ,
        FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
    if (fh == INVALID_HANDLE_VALUE)
        throw std::runtime_error("Can't open timecode file");

    DWORD nread;
    char buffer[8192];
    std::stringstream ss;
    while (ReadFile(fh, buffer, sizeof buffer, &nread, 0) && nread > 0)
        ss.write(buffer, nread);
    CloseHandle(fh);

    ss.seekg(0);
    parseTimecodeV2(option, ss, count);
}
Esempio n. 4
0
ALACSource::ALACSource(const std::wstring &path)
    : m_position(0)
{
    try {
	m_file.Read(w2m(path, utf8_codecvt_facet()).c_str(), 0);
	m_track_id = m_file.FindTrackId(0, MP4_AUDIO_TRACK_TYPE);
	const char *type = m_file.GetTrackMediaDataName(m_track_id);
	if (std::strcmp(type, "alac"))
	    throw std::runtime_error("Not an ALAC file");

	const char *alacprop, *chanprop;
	const char *brand = m_file.GetStringProperty("ftyp.majorBrand");
	if (!std::strcmp(brand, "qt  ")) {
	    // throw std::runtime_error("Not supported format");
	    alacprop = "mdia.minf.stbl.stsd.alac.wave.alac.decoderConfig";
	    chanprop = "mdia.minf.stbl.stsd.alac.wave.chan.data";
	} else {
	    alacprop = "mdia.minf.stbl.stsd.alac.alac.decoderConfig";
	    chanprop = "mdia.minf.stbl.stsd.alac.chan.data";
	}

	std::vector<uint8_t> alac, chan;
	uint8_t *value;
	uint32_t size;
	m_file.GetTrackBytesProperty(m_track_id, alacprop, &value, &size);
	std::copy(value + 4, value + size, std::back_inserter(alac));
	MP4Free(value);
	value = 0;
	try {
	    m_file.GetTrackBytesProperty(m_track_id, chanprop, &value, &size);
	    std::copy(value + 4, value + size, std::back_inserter(chan));
	    MP4Free(value);
	} catch (...) {}
	if (alac.size() != 24 || (chan.size() && chan.size() < 12))
	    throw std::runtime_error("ALACSource: invalid magic cookie");

	std::memset(&m_format, 0, sizeof m_format);
	m_format.m_type = SampleFormat::kIsSignedInteger;
	m_format.m_endian = SampleFormat::kIsLittleEndian;
	m_format.m_nchannels = alac[9];
	m_format.m_bitsPerSample = alac[5];
	if (m_format.m_bitsPerSample == 20)
	    m_format.m_bitsPerSample = 24;
	uint32_t timeScale;
	std::memcpy(&timeScale, &alac[20], 4);
	timeScale = b2host32(timeScale);
	m_format.m_rate = timeScale;

	AudioChannelLayout acl = { 0 };
	if (chan.size()) {
	    fourcc tag(reinterpret_cast<const char*>(&chan[0]));
	    fourcc bitmap(reinterpret_cast<const char*>(&chan[4]));
	    acl.mChannelLayoutTag = tag;
	    acl.mChannelBitmap = bitmap;
	    chanmap::GetChannels(&acl, &m_chanmap);
	}
	m_decoder = x::shared_ptr<ALACDecoder>(new ALACDecoder());
	CHECKCA(m_decoder->Init(&alac[0], alac.size()));
	setRange(0, m_file.GetTrackDuration(m_track_id));

	mp4a::fetchTags(m_file, &m_tags);
    } catch (mp4v2::impl::Exception *e) {
	handle_mp4error(e);
    }
}