Skip to content

Commit

Permalink
fixes for updated mp4v2 custom file provider
Browse files Browse the repository at this point in the history
  • Loading branch information
nu774 committed Dec 28, 2014
1 parent 740f1ad commit ed4252d
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 89 deletions.
71 changes: 0 additions & 71 deletions mp4v2wrapper.cpp
Expand Up @@ -83,77 +83,6 @@ class MP4SgpdAtom: public MP4Atom {
}
};

namespace myprovider {

static
void *open(const char *name, MP4FileMode mode)
{
return win32::tmpfile(strutil::us2w(name).c_str());
}

static
int seek(void *fh, int64_t pos)
{
FILE *fp = reinterpret_cast<FILE*>(fh);
#if defined(_MSC_VER) || defined(__MINGW32__)
return std::fsetpos(fp, static_cast<fpos_t*>(&pos));
#else
return fseeko(fp, pos, SEEK_SET);
#endif
}

static
int read(void *fh, void *data, int64_t size, int64_t *nc, int64_t)
{
FILE *fp = reinterpret_cast<FILE*>(fh);
size_t n = std::fread(data, 1, size, fp);
*nc = n;
return std::ferror(fp);
}

static
int write(void *fh, const void *data, int64_t size, int64_t *nc, int64_t)
{
FILE *fp = reinterpret_cast<FILE*>(fh);
size_t n = std::fwrite(data, 1, size, fp);
*nc = n;
return std::ferror(fp);
}

static
int close(void *fh)
{
FILE *fp = reinterpret_cast<FILE*>(fh);
return std::fclose(fp);
}

} // namespace myprovider


void MP4FileX::CreateTemp(const char *prefix,
uint32_t flags, int add_ftyp, int add_iods,
char *majorBrand, uint32_t minorVersion,
char **supportedBrands, uint32_t supportedBrandsCount)
{
MP4FileProvider provider = {
myprovider::open, myprovider::seek, myprovider::read,
myprovider::write, myprovider::close
};
m_createFlags = flags;
Open(prefix, File::MODE_CREATE, &provider);

m_pRootAtom = MP4Atom::CreateAtom(*this, NULL, NULL);
m_pRootAtom->Generate();

if (add_ftyp)
MakeFtypAtom(majorBrand, minorVersion,
supportedBrands, supportedBrandsCount);
CacheProperties();
InsertChildAtom(m_pRootAtom, "mdat", add_ftyp ? 1 : 0);
m_pRootAtom->BeginWrite();
if (add_iods != 0) (void)AddChildAtom("moov", "iods");
}

MP4TrackId
MP4FileX::AddAlacAudioTrack(const uint8_t *alac, const uint8_t *chan)
{
Expand Down
13 changes: 7 additions & 6 deletions mp4v2wrapper.h
Expand Up @@ -27,11 +27,6 @@ class MP4FileX: public mp4v2::impl::MP4File {

void ResetFile() { m_file = 0; }

void CreateTemp(const char *prefix,
uint32_t flags, int add_ftyp, int add_iods,
char *majorBrand, uint32_t minorVersion,
char **supportedBrands, uint32_t supportedBrandsCount);

void FinishWriteX()
{
for (size_t i = 0; i < m_pTracks.Size(); ++i)
Expand Down Expand Up @@ -106,7 +101,7 @@ struct MP4FDReadProvider: public MP4FileProvider
MP4FDReadProvider()
{
static MP4FileProvider t = {
open, seek, read, 0, close
open, seek, read, 0, close, get_size
};
std::memset(this, 0, sizeof t);
std::memcpy(this, &t, sizeof t);
Expand Down Expand Up @@ -140,6 +135,12 @@ struct MP4FDReadProvider: public MP4FileProvider
{
return 0;
}
static int get_size(void *handle, int64_t *size)
{
int fd = reinterpret_cast<int>(handle) - 1;
*size = _filelengthi64(fd);
return *size == -1 ? -1 : 0;
}
};

#endif
95 changes: 83 additions & 12 deletions sink.cpp
Expand Up @@ -57,6 +57,77 @@ void parseMagicCookieALAC(const std::vector<uint8_t> &cookie,
}
}


namespace t {
void *open(const char *name, MP4FileMode mode)
{
const wchar_t *m = L"";
switch (mode) {
case FILEMODE_READ: m = L"rb"; break;
case FILEMODE_MODIFY: m = L"rb+"; break;
case FILEMODE_CREATE: m = L"wb"; break;
}
return win32::wfopenx(strutil::us2w(name).c_str(), m);
}
void *open_temp(const char *name, MP4FileMode mode)
{
return win32::tmpfile(strutil::us2w(name).c_str());
}
int seek(void *fh, int64_t pos)
{
FILE *fp = static_cast<FILE*>(fh);
return std::fsetpos(fp, static_cast<fpos_t*>(&pos));
}
int read(void *fh, void *data, int64_t size, int64_t *nc, int64_t)
{
FILE *fp = static_cast<FILE*>(fh);
size_t n = std::fread(data, 1, size, fp);
*nc = n;
return std::ferror(fp);
}
int write(void *fh, const void *data, int64_t size,
int64_t *nc, int64_t)
{
FILE *fp = static_cast<FILE*>(fh);
size_t n = std::fwrite(data, 1, size, fp);
*nc = n;
return std::ferror(fp);
}
int close(void *fh)
{
FILE *fp = static_cast<FILE*>(fh);
return std::fclose(fp);
}
int get_size(void *fh, int64_t *size)
{
FILE *fp = static_cast<FILE*>(fh);
*size = _filelengthi64(fileno(fp));
return *size == -1 ? -1 : 0;
}
}

struct MP4CustomFileProvider: public MP4FileProvider
{
MP4CustomFileProvider()
{
static MP4FileProvider t = {
t::open, t::seek, t::read, t::write, t::close, t::get_size
};
std::memcpy(this, &t, sizeof t);
}
};

struct MP4TempFileProvider: public MP4FileProvider
{
MP4TempFileProvider()
{
static MP4FileProvider t = {
t::open_temp, t::seek, t::read, t::write, t::close, t::get_size
};
std::memcpy(this, &t, sizeof t);
}
};

using mp4v2::impl::MP4Atom;

MP4SinkBase::MP4SinkBase(const std::wstring &path, bool temp)
Expand All @@ -65,20 +136,20 @@ MP4SinkBase::MP4SinkBase(const std::wstring &path, bool temp)
{
static const char * const compatibleBrands[] =
{ "M4A ", "mp42", "isom", "" };
void (MP4FileX::*create)(const char *, uint32_t, int, int,
char*, uint32_t, char **, uint32_t);
if (temp) m_filename = L"qaac.int";
try {
create = temp ? &MP4FileX::CreateTemp : &MP4FileX::Create;
(m_mp4file.*create)(
strutil::w2us(m_filename).c_str(),
0, // flags
1, // add_ftypes
0, // add_iods
"M4A ", // majorBrand
0, // minorVersion
const_cast<char**>(compatibleBrands),
util::sizeof_array(compatibleBrands));
static MP4CustomFileProvider cprovider;
static MP4TempFileProvider tprovider;
m_mp4file.Create(strutil::w2us(m_filename).c_str(),
0, // flags
temp ? static_cast<MP4FileProvider*>(&tprovider)
: static_cast<MP4FileProvider*>(&cprovider),
1, // add_ftypes
0, // add_iods
"M4A ", // majorBrand
0, // minorVersion
const_cast<char**>(compatibleBrands),
util::sizeof_array(compatibleBrands));
} catch (mp4v2::impl::Exception *e) {
m_mp4file.ResetFile();
handle_mp4error(e);
Expand Down

0 comments on commit ed4252d

Please sign in to comment.