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
|
diff --git a/include/libmkv.h b/include/libmkv.h
index 4bd6f8c..146a91f 100644
--- a/include/libmkv.h
+++ b/include/libmkv.h
@@ -216,6 +216,7 @@ struct mk_TrackConfig_s {
mk_Writer *mk_createWriter(const char *filename, int64_t timescale,
uint8_t vlc_compat);
mk_Track *mk_createTrack(mk_Writer *w, mk_TrackConfig *tc);
+int mk_updateTrackPrivateData(mk_Writer *w, mk_Track *track, uint8_t * data, int size );
int mk_writeHeader(mk_Writer *w, const char *writingApp);
int mk_startFrame(mk_Writer *w, mk_Track *track);
int mk_flushFrame(mk_Writer *w, mk_Track *track);
diff --git a/src/matroska.c b/src/matroska.c
index f61b6f2..b14fd4c 100644
--- a/src/matroska.c
+++ b/src/matroska.c
@@ -171,8 +171,17 @@ int mk_writeHeader(mk_Writer *w, const char *writingApp)
w->seek_data.tracks = w->root->d_cur - w->segment_ptr;
- if (w->tracks)
- CHECK(mk_closeContext(w->tracks, 0));
+ if (w->tracks) {
+ mk_Track * tk;
+ int i;
+
+ CHECK(mk_closeContext(w->tracks, &offset));
+ for (i = 0; i < w->num_tracks; i++) {
+ tk = w->tracks_arr[i];
+ if (tk->private_data_size)
+ tk->private_data_ptr += offset;
+ }
+ }
CHECK(mk_flushContextData(w->root));
@@ -487,12 +496,8 @@ int mk_close(mk_Writer *w)
for (i = w->num_tracks - 1; i >= 0; i--) {
tk = w->tracks_arr[i];
- w->tracks_arr[i] = NULL;
- --w->num_tracks;
if (mk_flushFrame(w, tk) < 0)
ret = -1;
- free(tk);
- tk = NULL;
}
if (mk_closeCluster(w) < 0)
@@ -611,6 +616,24 @@ int mk_close(mk_Writer *w)
ret = -1;
}
+ /* update any track private data that may have changed */
+ for (i = w->num_tracks - 1; i >= 0; i--) {
+ tk = w->tracks_arr[i];
+ if (tk->private_data_size && tk->private_data)
+ {
+ if (mk_seekFile(w, tk->private_data_ptr) < 0)
+ ret = -1;
+ if (mk_writeBin(w->root, MATROSKA_ID_CODECPRIVATE,
+ tk->private_data, tk->private_data_size) < 0 ||
+ mk_flushContextData(w->root) < 0)
+ ret = -1;
+ free(tk->private_data);
+ }
+ w->tracks_arr[i] = NULL;
+ --w->num_tracks;
+ free(tk);
+ }
+
if (mk_closeContext(w->root, 0) < 0)
ret = -1;
mk_destroyContexts(w);
diff --git a/src/matroska.h b/src/matroska.h
index 515c5ab..2e1eb2f 100644
--- a/src/matroska.h
+++ b/src/matroska.h
@@ -269,6 +269,9 @@ struct mk_Track_s {
uint64_t default_duration;
mk_TrackType track_type;
int64_t prev_cue_pos;
+ uint8_t *private_data;
+ unsigned private_data_size;
+ int64_t private_data_ptr;
struct {
mk_Context *data;
diff --git a/src/tracks.c b/src/tracks.c
index d9fc38b..0e224e4 100644
--- a/src/tracks.c
+++ b/src/tracks.c
@@ -81,6 +81,8 @@ mk_Track *mk_createTrack(mk_Writer *w, mk_TrackConfig *tc)
return NULL;
if (tc->codecPrivateSize && (tc->codecPrivate != NULL)) {
/* CodecPrivate */
+ track->private_data_size = tc->codecPrivateSize;
+ track->private_data_ptr = ti->d_cur;
if (mk_writeBin(ti, MATROSKA_ID_CODECPRIVATE, tc->codecPrivate, tc->codecPrivateSize) < 0)
return NULL;
}
@@ -191,17 +193,40 @@ mk_Track *mk_createTrack(mk_Writer *w, mk_TrackConfig *tc)
return NULL;
}
- if (mk_closeContext(ti, 0) < 0)
+ int64_t offset = 0;
+ if (mk_closeContext(ti, &offset) < 0)
return NULL;
+ track->private_data_ptr += offset;
return track;
}
+int mk_updateTrackPrivateData(mk_Writer *w, mk_Track *track, uint8_t * data, int size )
+{
+ /* can not write data larger than was previously reserved */
+ if (size > track->private_data_size)
+ return -1;
+
+ if (track->private_data == NULL)
+ track->private_data = calloc(1, track->private_data_size);
+ memcpy(track->private_data, data, size);
+}
+
int mk_writeTracks(mk_Writer *w, mk_Context *tracks)
{
+ int i;
+ mk_Track * tk;
+ int64_t offset = 0;
+
w->seek_data.tracks = w->root->d_cur;
- CHECK(mk_closeContext(w->tracks, 0));
+ CHECK(mk_closeContext(w->tracks, &offset));
+
+ for (i = 0; i < w->num_tracks; i++) {
+ tk = w->tracks_arr[i];
+ if (tk->private_data_size)
+ tk->private_data_ptr += offset;
+ }
return 0;
}
|