1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2007 libmkv
7 * Authors: Mike Matsnev
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
28 /* TODO: Figure out what can actually fail without damaging the track. */
30 mk_Track
*mk_createTrack(mk_Writer
*w
, mk_TrackConfig
*tc
)
34 mk_Track
*track
= calloc(1, sizeof(*track
));
38 if ((w
->tracks_arr
= realloc(w
->tracks_arr
, (w
->num_tracks
+ 1) * sizeof(mk_Track
*))) == NULL
)
40 w
->tracks_arr
[w
->num_tracks
] = track
;
41 track
->track_id
= ++w
->num_tracks
;
43 if (w
->tracks
== NULL
)
45 if ((w
->tracks
= mk_createContext(w
, w
->root
, 0x1654ae6b)) == NULL
) // tracks
49 if ((ti
= mk_createContext(w
, w
->tracks
, 0xae)) == NULL
) // TrackEntry
51 if (mk_writeUInt(ti
, 0xd7, track
->track_id
) < 0) // TrackNumber
54 if (mk_writeUInt(ti
, 0x73c5, tc
->trackUID
) < 0) /* TrackUID */
58 * If we aren't given a UID, randomly generate one.
59 * NOTE: It would probably be better to CRC32 some unique track information
60 * in place of something completely random.
62 unsigned long track_uid
;
65 if (mk_writeUInt(ti
, 0x73c5, track_uid
) < 0) /* TrackUID */
68 if (mk_writeUInt(ti
, 0x83, tc
->trackType
) < 0) // TrackType
70 track
->track_type
= tc
->trackType
;
71 if (mk_writeUInt(ti
, 0x9c, tc
->flagLacing
) < 0) // FlagLacing
73 if (mk_writeStr(ti
, 0x86, tc
->codecID
) < 0) // CodecID
75 if (tc
->codecPrivateSize
&& (tc
->codecPrivate
!= NULL
))
76 if (mk_writeBin(ti
, 0x63a2, tc
->codecPrivate
, tc
->codecPrivateSize
) < 0) // CodecPrivate
78 if (tc
->defaultDuration
) {
79 if (mk_writeUInt(ti
, 0x23e383, tc
->defaultDuration
) < 0)
81 track
->default_duration
= tc
->defaultDuration
;
84 if (mk_writeStr(ti
, 0x22b59c, tc
->language
) < 0) // Language
86 if (tc
->flagEnabled
!= 1)
87 if (mk_writeUInt(ti
, 0xb9, tc
->flagEnabled
) < 0) // FlagEnabled
89 if (mk_writeUInt(ti
, 0x88, tc
->flagDefault
) < 0) // FlagDefault
92 if (mk_writeUInt(ti
, 0x55aa, tc
->flagForced
) < 0) // FlagForced
95 if (mk_writeUInt(ti
, 0x6de7, tc
->minCache
) < 0) // MinCache
97 /* FIXME: this won't handle NULL values, which signals that the cache is disabled. */
99 if (mk_writeUInt(ti
, 0x6df8, tc
->maxCache
) < 0) // MaxCache
102 switch (tc
->trackType
)
104 case MK_TRACK_VIDEO
: // Video
105 if ((v
= mk_createContext(w
, ti
, 0xe0)) == NULL
)
107 if (tc
->extra
.video
.pixelCrop
[0] != 0 || tc
->extra
.video
.pixelCrop
[1] != 0 || tc
->extra
.video
.pixelCrop
[2] != 0 || tc
->extra
.video
.pixelCrop
[3] != 0) {
108 for (i
= 0; i
< 4; i
++) {
109 if (mk_writeUInt(v
, 0x54aa + (i
* 0x11), tc
->extra
.video
.pixelCrop
[i
]) < 0) // PixelCrop
113 if (mk_writeUInt(v
, 0xb0, tc
->extra
.video
.pixelWidth
) < 0) // PixelWidth
115 if (mk_writeUInt(v
, 0xba, tc
->extra
.video
.pixelHeight
) < 0 ) // PixelHeight
117 if (mk_writeUInt(v
, 0x54b0, tc
->extra
.video
.displayWidth
) < 0) // DisplayWidth
119 if (mk_writeUInt(v
, 0x54ba, tc
->extra
.video
.displayHeight
) < 0) // DisplayHeight
121 if (tc
->extra
.video
.displayUnit
)
122 if (mk_writeUInt(v
, 0x54b2, tc
->extra
.video
.displayUnit
) < 0) // DisplayUnit
125 case MK_TRACK_AUDIO
: // Audio
126 if ((v
= mk_createContext(w
, ti
, 0xe1)) == NULL
)
128 if (mk_writeFloat(v
, 0xb5, tc
->extra
.audio
.samplingFreq
) < 0) // SamplingFrequency
130 if (mk_writeUInt(v
, 0x9f, tc
->extra
.audio
.channels
) < 0) // Channels
132 if (tc
->extra
.audio
.bitDepth
)
133 if (mk_writeUInt(v
, 0x6264, tc
->extra
.audio
.bitDepth
) < 0) // BitDepth
136 default: // Other TODO: Implement other track types.
140 if (mk_closeContext(v
, 0) < 0)
142 if (mk_closeContext(ti
, 0) < 0)
148 int mk_writeTracks(mk_Writer
*w
, mk_Context
*tracks
)
150 w
->seek_data
.tracks
= w
->root
->d_cur
;
152 CHECK(mk_closeContext(w
->tracks
, 0));