-
Notifications
You must be signed in to change notification settings - Fork 4
/
hdlr.cc
90 lines (81 loc) · 2.71 KB
/
hdlr.cc
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
//
// Created by wlanjie on 2018/3/9.
//
#include "hdlr.h"
#include "utils.h"
#include "log.h"
namespace mp4 {
Hdlr *Hdlr::create(Size size, ByteStream &stream) {
UI08 version;
UI32 flags;
if (size < FULL_ATOM_HEADER_SIZE) {
return nullptr;
}
if (FAILED(Atom::readFullHeader(stream, version, flags))) {
return nullptr;
}
if (version != 0) {
return nullptr;
}
return new Hdlr(size, version, flags, stream);
}
Hdlr::Hdlr(Atom::Type hdlrType, const char *hdlrName) :
Atom(ATOM_TYPE_HDLR, FULL_ATOM_HEADER_SIZE, 0, 0),
handlerType(hdlrType),
handlerName(hdlrName) {
LOGV("hdlrType = %d hdlrName = %s\n", hdlrType, hdlrName);
size32 += 20 + handlerName.getLength() + 1;
reserved[0] = reserved[1] = reserved[2] = 0;
}
Hdlr::Hdlr(UI32 size, UI08 version, UI32 flags, ByteStream &stream) :
Atom(ATOM_TYPE_HDLR, size, version, flags) {
UI32 predefined;
stream.readUI32(predefined);
stream.readUI32(handlerType);
stream.readUI32(reserved[0]);
stream.readUI32(reserved[1]);
stream.readUI32(reserved[2]);
// read the name unless it is empty
if (size < FULL_ATOM_HEADER_SIZE + 20) return;
UI32 name_size = size - (FULL_ATOM_HEADER_SIZE + 20);
auto *name = new char[name_size + 1];
stream.read(name, name_size);
name[name_size] = '\0'; // force a null termination
// handle a special case: the Quicktime files have a pascal
// string here, but ISO MP4 files have a C string.
// we try to detect a pascal encoding and correct it.
if ((UI08) name[0] == (UI08) (name_size - 1)) {
handlerName = name + 1;
} else {
handlerName = name;
}
delete[] name;
}
Result Hdlr::writeFields(ByteStream &stream) {
LOGV("write hldr fields\n");
Result result;
result = stream.writeUI32(0);
if (FAILED(result)) return result;
result = stream.writeUI32(handlerType);
if (FAILED(result)) return result;
result = stream.writeUI32(reserved[0]);
if (FAILED(result)) return result;
result = stream.writeUI32(reserved[1]);
if (FAILED(result)) return result;
result = stream.writeUI32(reserved[2]);
if (FAILED(result)) return result;
UI08 name_size = (UI08) handlerName.getLength();
if (FULL_ATOM_HEADER_SIZE + 20 + name_size > size32) {
name_size = (UI08) (size32 - FULL_ATOM_HEADER_SIZE + 20);
}
if (name_size) {
result = stream.write(handlerName.getChars(), name_size);
if (FAILED(result)) return result;
}
// pad with zeros if necessary
Size padding = size32 - (FULL_ATOM_HEADER_SIZE + 20 + name_size);
while (padding--) stream.writeUI08(0);
LOGV("write hldr fields done\n");
return SUCCESS;
}
}