forked from nu774/qaac
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mp4v2wrapper.h
149 lines (133 loc) · 4.53 KB
/
mp4v2wrapper.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#ifndef MP4V2WRAPPER_H
#define MP4V2WRAPPER_H
#include <string>
#include <stdexcept>
#include <stdint.h>
#include <cstdio> // FILE
#include <unistd.h> // ftruncate
#undef FindAtom
#include "src/impl.h"
#include "util.h"
#include "misc.h"
std::string format_mp4error(const mp4v2::impl::Exception &e);
inline void handle_mp4error(mp4v2::impl::Exception *e)
{
std::runtime_error re(format_mp4error(*e));
delete e;
throw re;
}
class MP4FileCopy;
class MP4FileX: public mp4v2::impl::MP4File {
friend class MP4FileCopy;
public:
MP4FileX() {}
void ResetFile() { m_file = 0; }
void FinishWriteX()
{
for (size_t i = 0; i < m_pTracks.Size(); ++i)
m_pTracks[i]->FinishWrite(MP4_CLOSE_DO_NOT_COMPUTE_BITRATE);
}
util::AutoDynaCast<mp4v2::impl::MP4Atom>
FindAtomT(const char *name)
{
return FindAtom(name);
}
util::AutoDynaCast<mp4v2::impl::MP4Atom>
FindChildAtomT(mp4v2::impl::MP4Atom *parent, const char *name)
{
return parent->FindChildAtom(name);
}
util::AutoDynaCast<mp4v2::impl::MP4Atom>
AddChildAtomT(mp4v2::impl::MP4Atom *parent, const char *name)
{
return AddChildAtom(parent, name);
}
MP4TrackId AddAlacAudioTrack(const uint8_t *alac, const uint8_t *chan);
void CreateAudioSampleGroupDescription(MP4TrackId trackId,
uint32_t sampleCount);
bool SetMetadataString(const char *atom, const char *value);
bool SetMetadataTrack(uint16_t track, uint16_t totalTracks);
bool SetMetadataDisk(uint16_t disk, uint16_t totalDisks);
bool SetMetadataUint8(const char *atom, uint8_t value);
bool SetMetadataUint16(const char *atom, uint16_t value);
bool SetMetadataUint32(const char *atom, uint32_t value);
bool SetMetadataUint64(const char *atom, uint64_t value);
bool SetMetadataGenre(const char *atom, uint16_t value);
bool SetMetadataArtwork(const char *atom,
const char *data, size_t size,
mp4v2::impl::itmf::BasicType typeCode
= mp4v2::impl::itmf::BT_UNDEFINED);
bool SetMetadataFreeForm(const char *name, const char *mean,
const uint8_t* pValue, uint32_t valueSize,
mp4v2::impl::itmf::BasicType typeCode
=mp4v2::impl::itmf::BT_UTF8);
bool GetQTChapters(std::vector<misc::chapter_t> *chapters);
bool GetNeroChapters(std::vector<misc::chapter_t> *chapters,
double *first_off);
protected:
mp4v2::impl::MP4DataAtom *CreateMetadataAtom(const char *name,
mp4v2::impl::itmf::BasicType typeCode);
mp4v2::impl::MP4DataAtom *FindOrCreateMetadataAtom(const char *atom,
mp4v2::impl::itmf::BasicType typeCode);
};
class MP4FileCopy {
struct ChunkInfo {
mp4v2::impl::MP4ChunkId current, final;
MP4Timestamp time;
};
MP4FileX *m_mp4file;
std::shared_ptr<FILE> m_fp;
uint64_t m_nchunks;
std::vector<ChunkInfo> m_state;
mp4v2::platform::io::File *m_src;
mp4v2::platform::io::File *m_dst;
public:
MP4FileCopy(mp4v2::impl::MP4File *file);
~MP4FileCopy() { if (m_dst) finish(); }
void start(const char *path);
void finish();
bool copyNextChunk();
uint64_t getTotalChunks() { return m_nchunks; }
};
struct MP4StdIOCallbacks: public MP4IOCallbacks
{
MP4StdIOCallbacks()
{
static MP4IOCallbacks t = {
get_size, seek, read, write, truncate
};
std::memset(this, 0, sizeof t);
std::memcpy(this, &t, sizeof t);
}
static int64_t get_size(void *handle) {
FILE *fp = static_cast<FILE*>(handle);
fflush(fp);
long originalPosition = ftell(fp);
fseek(fp, 0, SEEK_END);
long fileSize = ftell(fp);
fseek(fp, originalPosition, SEEK_SET);
return fileSize;
}
static int seek(void *handle, int64_t pos) {
FILE *fp = static_cast<FILE*>(handle);
return fseeko(fp, pos, SEEK_SET) < 0;
}
static int read(void *handle, void *buffer, int64_t size, int64_t *nin)
{
FILE *fp = static_cast<FILE*>(handle);
*nin = fread(buffer, 1, size, fp);
return ferror(fp);
}
static int write(void *handle, const void *buffer, int64_t size, int64_t *nout)
{
FILE *fp = static_cast<FILE*>(handle);
*nout = fwrite(buffer, 1, size, fp);
return ferror(fp);
}
static int truncate(void *handle, int64_t size) {
FILE *fp = static_cast<FILE*>(handle);
fflush(fp);
return ftruncate(fileno(fp), size) < 0;
}
};
#endif