2
* The contents of this file are subject to the Mozilla Public
3
* License Version 1.1 (the "License"); you may not use this file
4
* except in compliance with the License. You may obtain a copy of
5
* the License at http://www.mozilla.org/MPL/
7
* Software distributed under the License is distributed on an "AS
8
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9
* implied. See the License for the specific language governing
10
* rights and limitations under the License.
12
* The Original Code is MPEG4IP.
14
* The Initial Developer of the Original Code is Cisco Systems Inc.
15
* Portions created by Cisco Systems Inc. are
16
* Copyright (C) Cisco Systems Inc. 2002. All Rights Reserved.
19
* Bill May wmay@cisco.com
20
* Alix Marchandise-Franquet alix@cisco.com
22
#include "mp4creator.h"
25
static MP4TrackId VideoCreate (MP4FileHandle mp4file,
30
double frame_rate = mpeg2ps_get_video_stream_framerate(file, vstream);
34
ismacryp_session_id_t ismaCrypSId;
35
mp4v2_ismacrypParams *icPp = (mp4v2_ismacrypParams *) malloc(sizeof(mp4v2_ismacrypParams));
36
memset(icPp, 0, sizeof(mp4v2_ismacrypParams));
40
MP4Duration mp4FrameDuration;
42
(MP4Duration)((double)Mp4TimeScale / frame_rate);
44
MP4Duration mp4FrameDuration =
45
(MP4Duration)(Mp4TimeScale / frame_rate);
48
h = mpeg2ps_get_video_stream_height(file, vstream);
49
w = mpeg2ps_get_video_stream_width(file, vstream);
51
video_type = mpeg2ps_get_video_stream_mp4_type(file, vstream);
55
if (ismacrypInitSession(&ismaCrypSId,KeyTypeVideo) != 0) {
56
fprintf(stderr, "%s: could not initialize the ISMAcryp session\n",
58
return MP4_INVALID_TRACK_ID;
60
if (ismacrypGetScheme(ismaCrypSId, &(icPp->scheme_type)) != ismacryp_rc_ok) {
61
fprintf(stderr, "%s: could not get ismacryp scheme type. sid %d\n",
62
ProgName, ismaCrypSId);
63
ismacrypEndSession(ismaCrypSId);
64
return MP4_INVALID_TRACK_ID;
66
if (ismacrypGetSchemeVersion(ismaCrypSId, &(icPp->scheme_version)) != ismacryp_rc_ok) {
67
fprintf(stderr, "%s: could not get ismacryp scheme ver. sid %d\n",
68
ProgName, ismaCrypSId);
69
ismacrypEndSession(ismaCrypSId);
70
return MP4_INVALID_TRACK_ID;
72
if (ismacrypGetKMSUri(ismaCrypSId, &(icPp->kms_uri)) != ismacryp_rc_ok) {
73
fprintf(stderr, "%s: could not get ismacryp kms uri. sid %d\n",
74
ProgName, ismaCrypSId);
75
CHECK_AND_FREE(icPp->kms_uri);
76
ismacrypEndSession(ismaCrypSId);
77
return MP4_INVALID_TRACK_ID;
79
if ( ismacrypGetSelectiveEncryption(ismaCrypSId, &(icPp->selective_enc)) != ismacryp_rc_ok ) {
80
fprintf(stderr, "%s: could not get ismacryp selec enc. sid %d\n",
81
ProgName, ismaCrypSId);
82
ismacrypEndSession(ismaCrypSId);
83
return MP4_INVALID_TRACK_ID;
85
if (ismacrypGetKeyIndicatorLength(ismaCrypSId, &(icPp->key_ind_len)) != ismacryp_rc_ok) {
86
fprintf(stderr, "%s: could not get ismacryp key ind len. sid %d\n",
87
ProgName, ismaCrypSId);
88
ismacrypEndSession(ismaCrypSId);
89
return MP4_INVALID_TRACK_ID;
91
if (ismacrypGetIVLength(ismaCrypSId, &(icPp->iv_len)) != ismacryp_rc_ok) {
92
fprintf(stderr, "%s: could not get ismacryp iv len. sid %d\n",
93
ProgName, ismaCrypSId);
94
ismacrypEndSession(ismaCrypSId);
95
return MP4_INVALID_TRACK_ID;
97
id = MP4AddEncVideoTrack(mp4file,
105
id = MP4AddVideoTrack(mp4file,
113
//printf("duration "U64" w %d h %d type %x\n", mp4FrameDuration, w, h, video_type);
114
if (MP4GetNumberOfTracks(mp4file, MP4_VIDEO_TRACK_TYPE) == 1) {
115
MP4SetVideoProfileLevel(mp4file, 0xfe); // undefined profile
118
if (id == MP4_INVALID_TRACK_ID) {
119
fprintf(stderr, "%s:Couldn't add video track %d", ProgName, vstream);
120
return MP4_INVALID_TRACK_ID;
126
printf("Processing %lu video frames\n", frames_max);
128
uint32_t refFrame = 1;
130
while (mpeg2ps_get_video_frame(file,
137
if (buf[blen - 4] == 0 &&
138
buf[blen - 3] == 0 &&
139
buf[blen - 2] == 1) blen -= 4;
141
// encrypt the sample if neeed
143
u_int8_t* encSampleData = NULL;
144
u_int32_t encSampleLen = 0;
145
if (ismacrypEncryptSampleAddHeader(ismaCrypSId, blen, buf,
146
&encSampleLen, &encSampleData) != 0) {
148
"%s: can't encrypt video sample and add header %u\n", ProgName, id);
150
MP4WriteSample(mp4file, id, encSampleData, encSampleLen,
152
frame_type == 1 ? true : false);
153
if (encSampleData != NULL) {
157
MP4WriteSample(mp4file, id, buf, blen, mp4FrameDuration, 0,
158
frame_type == 1 ? true : false);
160
printf("frame %d len %d duration "U64" ftype %d\n",
161
frames, blen, mp4FrameDuration, frame_type);
164
if (frame_type != 3) {
166
MP4SetSampleRenderingOffset(mp4file, id, refFrame,
167
(frames - refFrame) * mp4FrameDuration);
172
if ((frames % 100) == 0) printf("%d frames\n", frames);
176
// if encrypting, terminate the ismacryp session
178
if (ismacrypEndSession(ismaCrypSId) != 0) {
180
"%s: could not end the ISMAcryp session\n",
182
return MP4_INVALID_TRACK_ID;
188
static MP4TrackId AudioCreate (MP4FileHandle mp4file,
196
uint16_t samples_per_frame;
199
uint32_t frame_num = 1;
200
ismacryp_session_id_t ismaCrypSId;
201
mp4v2_ismacrypParams *icPp = (mp4v2_ismacrypParams *) malloc(sizeof(mp4v2_ismacrypParams));
203
u_int8_t mpegVersion;
204
memset(icPp, 0, sizeof(mp4v2_ismacrypParams));
206
type = mpeg2ps_get_audio_stream_type(file, astream);
208
if (type != MPEG_AUDIO_MPEG) {
209
fprintf(stderr, "Unsupported audio format %d in audio stream %d\n",
211
return MP4_INVALID_TRACK_ID;
214
freq = mpeg2ps_get_audio_stream_sample_freq(file, astream);
216
if (mpeg2ps_get_audio_frame(file,
223
fprintf(stderr, "No audio tracks in audio stream %d\n", astream);
224
return MP4_INVALID_TRACK_ID;
227
hdr = MP4AV_Mp3HeaderFromBytes(buf);
228
mpegVersion = MP4AV_Mp3GetHdrVersion(hdr);
229
samples_per_frame = MP4AV_Mp3GetHdrSamplingWindow(hdr);
231
u_int8_t audioType = MP4AV_Mp3ToMp4AudioType(mpegVersion);
233
if (audioType == MP4_INVALID_AUDIO_TYPE
234
|| samples_per_frame == 0) {
236
"%s: data in file doesn't appear to be valid audio\n",
238
return MP4_INVALID_TRACK_ID;
241
MP4Duration duration = (90000 * samples_per_frame) / freq;
244
// initialize the ismacryp session
245
if (ismacrypInitSession(&ismaCrypSId,KeyTypeAudio) != 0) {
247
"%s: could not initialize the ISMAcryp session\n",
249
return MP4_INVALID_TRACK_ID;
251
if (ismacrypGetScheme(ismaCrypSId, &(icPp->scheme_type)) != ismacryp_rc_ok) {
252
fprintf(stderr, "%s: could not get ismacryp scheme type. sid %d\n",
253
ProgName, ismaCrypSId);
254
ismacrypEndSession(ismaCrypSId);
255
return MP4_INVALID_TRACK_ID;
257
if (ismacrypGetSchemeVersion(ismaCrypSId, &(icPp->scheme_version)) != ismacryp_rc_ok) {
258
fprintf(stderr, "%s: could not get ismacryp scheme ver. sid %d\n",
259
ProgName, ismaCrypSId);
260
ismacrypEndSession(ismaCrypSId);
261
return MP4_INVALID_TRACK_ID;
263
if (ismacrypGetKMSUri(ismaCrypSId, &(icPp->kms_uri)) != ismacryp_rc_ok) {
264
fprintf(stderr, "%s: could not get ismacryp kms uri. sid %d\n",
265
ProgName, ismaCrypSId);
266
CHECK_AND_FREE(icPp->kms_uri);
267
ismacrypEndSession(ismaCrypSId);
268
return MP4_INVALID_TRACK_ID;
270
if ( ismacrypGetSelectiveEncryption(ismaCrypSId, &(icPp->selective_enc)) != ismacryp_rc_ok ) {
271
fprintf(stderr, "%s: could not get ismacryp selec enc. sid %d\n",
272
ProgName, ismaCrypSId);
273
ismacrypEndSession(ismaCrypSId);
274
return MP4_INVALID_TRACK_ID;
276
if (ismacrypGetKeyIndicatorLength(ismaCrypSId, &(icPp->key_ind_len)) != ismacryp_rc_ok) {
277
fprintf(stderr, "%s: could not get ismacryp key ind len. sid %d\n",
278
ProgName, ismaCrypSId);
279
ismacrypEndSession(ismaCrypSId);
280
return MP4_INVALID_TRACK_ID;
282
if (ismacrypGetIVLength(ismaCrypSId, &(icPp->iv_len)) != ismacryp_rc_ok) {
283
fprintf(stderr, "%s: could not get ismacryp iv len. sid %d\n",
284
ProgName, ismaCrypSId);
285
ismacrypEndSession(ismaCrypSId);
286
return MP4_INVALID_TRACK_ID;
288
id = MP4AddEncAudioTrack(mp4file,
294
id = MP4AddAudioTrack(mp4file,
300
if (id == MP4_INVALID_TRACK_ID) {
302
"%s: can't create audio track from stream %d\n",
304
return MP4_INVALID_TRACK_ID;
307
if (MP4GetNumberOfTracks(mp4file, MP4_AUDIO_TRACK_TYPE) == 1) {
308
MP4SetAudioProfileLevel(mp4file, 0xFE);
314
u_int8_t* encSampleData = NULL;
315
u_int32_t encSampleLen = 0;
316
if (ismacrypEncryptSampleAddHeader(ismaCrypSId, blen, buf,
317
&encSampleLen, &encSampleData) != 0) {
319
"%s: can't encrypt audio sample and add header %u\n", ProgName, id);
321
// now write the sample
322
if (!MP4WriteSample(mp4file, id, encSampleData, encSampleLen)) {
323
fprintf(stderr, "%s: can't write audio track %u, stream %d",
324
ProgName, frame_num, astream);
325
MP4DeleteTrack(mp4file, id);
326
return MP4_INVALID_TRACK_ID;
328
if (encSampleData != NULL) {
332
// now write the sample
333
if (!MP4WriteSample(mp4file, id, buf, blen)) {
334
fprintf(stderr, "%s: can't write audio track %u, stream %d",
335
ProgName, frame_num, astream);
336
MP4DeleteTrack(mp4file, id);
337
return MP4_INVALID_TRACK_ID;
341
if ((frame_num % 100) == 0) printf("Audio frame %d\n", frame_num);
343
} while (mpeg2ps_get_audio_frame(file,
350
// if encrypting, terminate the ismacryp session
352
if (ismacrypEndSession(ismaCrypSId) != 0) {
354
"%s: could not end the ISMAcryp session\n",
356
return MP4_INVALID_TRACK_ID;
363
MP4TrackId *MpegCreator (MP4FileHandle mp4file, const char *fname, bool doEncrypt)
367
int video_streams, audio_streams;
369
MP4TrackId *pTrackId;
371
file = mpeg2ps_init(fname);
372
video_streams = mpeg2ps_get_video_stream_count(file);
373
audio_streams = mpeg2ps_get_audio_stream_count(file);
376
(MP4TrackId *)malloc(sizeof(MP4TrackId) * (audio_streams + video_streams + 1));
378
for (ix = 0; ix < video_streams + audio_streams + 1; ix++) {
379
pTrackId[ix] = MP4_INVALID_TRACK_ID;
382
for (ix = 0; ix < video_streams; ix++) {
383
pTrackId[ix] = VideoCreate(mp4file, file, ix, doEncrypt);
385
for (ix = 0; ix < audio_streams; ix++) {
386
pTrackId[ix + video_streams] = AudioCreate(mp4file, file, ix, doEncrypt);