uint32_t ismacrypEncryptSampleAddHeader2 (uint32_t session, uint32_t length, uint8_t *data, uint32_t *new_length, uint8_t **new_data) { ismacryp_rc_t rc = ismacrypEncryptSampleAddHeader ( (ismacryp_session_id_t) session, length, data, new_length, new_data ); return (uint32_t) rc; }
MP4TrackId Mp4vCreator(MP4FileHandle mp4File, FILE* inFile, bool doEncrypt, bool allowVariableFrameRate) { bool rc; u_int8_t sampleBuffer[256 * 1024 * 2]; u_int8_t* pCurrentSample = sampleBuffer; u_int32_t maxSampleSize = sizeof(sampleBuffer) / 2; u_int32_t prevSampleSize = 0; // the current syntactical object // typically 1:1 with a sample // but not always, i.e. non-VOP's u_int8_t* pObj = pCurrentSample; u_int32_t objSize; u_int8_t objType; // the current sample MP4SampleId sampleId = 1; MP4Timestamp currentSampleTime = 0; // the last reference VOP MP4SampleId refVopId = 1; MP4Timestamp refVopTime = 0; // track configuration info u_int8_t videoProfileLevel = MPEG4_SP_L3; u_int8_t timeBits = 15; u_int16_t timeTicks = 30000; u_int16_t frameDuration = 3000; u_int16_t frameWidth = 320; u_int16_t frameHeight = 240; u_int32_t esConfigSize = 0; int vopType = 0; int prevVopType = 0; bool foundVOSH = false, foundVO = false, foundVOL = false; u_int32_t lastVopTimeIncrement = 0; bool variableFrameRate = false; bool lastFrame = false; bool haveBframes = false; mpeg4_frame_t *head = NULL, *tail = NULL; // start reading objects until we get the first VOP while (LoadNextObject(inFile, pObj, &objSize, &objType)) { // guard against buffer overflow if (pObj + objSize >= pCurrentSample + maxSampleSize) { fprintf(stderr, "%s: buffer overflow, invalid video stream?\n", ProgName); return MP4_INVALID_TRACK_ID; } #ifdef DEBUG_MP4V if (Verbosity & MP4_DETAILS_SAMPLE) { printf("MP4V type %x size %u\n", objType, objSize); } #endif if (objType == MP4AV_MPEG4_VOSH_START) { MP4AV_Mpeg4ParseVosh(pObj, objSize, &videoProfileLevel); foundVOSH = true; } else if (objType == MP4AV_MPEG4_VO_START) { foundVO = true; } else if (objType == MP4AV_MPEG4_VOL_START) { MP4AV_Mpeg4ParseVol(pObj, objSize, &timeBits, &timeTicks, &frameDuration, &frameWidth, &frameHeight); foundVOL = true; #ifdef DEBUG_MP4V printf("ParseVol: timeBits %u timeTicks %u frameDuration %u\n", timeBits, timeTicks, frameDuration); #endif } else if (foundVOL == true || objType == MP4AV_MPEG4_VOP_START) { esConfigSize = pObj - pCurrentSample; // ready to set up mp4 track break; } /* XXX why do we need this if ? * It looks like it will remove this object ... XXX */ // It does. On Purpose. wmay 6/2004 if (objType != MP4AV_MPEG4_USER_DATA_START) { pObj += objSize; } } if (foundVOSH == false) { fprintf(stderr, "%s: no VOSH header found in MPEG-4 video.\n" "This can cause problems with players other than mp4player. \n", ProgName); } else { if (VideoProfileLevelSpecified && videoProfileLevel != VideoProfileLevel) { fprintf(stderr, "%s: You have specified a different video profile level than was detected in the VOSH header\n" "The level you specified was %d and %d was read from the VOSH\n", ProgName, VideoProfileLevel, videoProfileLevel); } } if (foundVO == false) { fprintf(stderr, "%s: No VO header found in mpeg-4 video.\n" "This can cause problems with players other than mp4player\n", ProgName); } if (foundVOL == false) { fprintf(stderr, "%s: fatal: No VOL header found in mpeg-4 video stream\n", ProgName); return MP4_INVALID_TRACK_ID; } // convert frame duration to canonical time scale // note zero value for frame duration signals variable rate video if (timeTicks == 0) { timeTicks = 1; } u_int32_t mp4FrameDuration = 0; if (VideoFrameRate) { mp4FrameDuration = (u_int32_t)(((double)Mp4TimeScale) / VideoFrameRate); } else if (frameDuration) { VideoFrameRate = frameDuration; VideoFrameRate /= timeTicks; mp4FrameDuration = (Mp4TimeScale * frameDuration) / timeTicks; } else { if (allowVariableFrameRate == false ) { fprintf(stderr, "%s: variable rate video stream signalled," " please specify average frame rate with -r option\n" " or --variable-frame-rate argument\n", ProgName); return MP4_INVALID_TRACK_ID; } variableFrameRate = true; } ismacryp_session_id_t ismaCrypSId; mp4v2_ismacrypParams *icPp = (mp4v2_ismacrypParams *) malloc(sizeof(mp4v2_ismacrypParams)); memset(icPp, 0, sizeof(mp4v2_ismacrypParams)); // initialize ismacryp session if encrypting if (doEncrypt) { if (ismacrypInitSession(&ismaCrypSId,KeyTypeVideo) != 0) { fprintf(stderr, "%s: could not initialize the ISMAcryp session\n", ProgName); return MP4_INVALID_TRACK_ID; } if (ismacrypGetScheme(ismaCrypSId, &(icPp->scheme_type)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp scheme type. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetSchemeVersion(ismaCrypSId, &(icPp->scheme_version)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp scheme ver. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetKMSUri(ismaCrypSId, &(icPp->kms_uri)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp kms uri. sid %d\n", ProgName, ismaCrypSId); CHECK_AND_FREE(icPp->kms_uri); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if ( ismacrypGetSelectiveEncryption(ismaCrypSId, &(icPp->selective_enc)) != ismacryp_rc_ok ) { fprintf(stderr, "%s: could not get ismacryp selec enc. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetKeyIndicatorLength(ismaCrypSId, &(icPp->key_ind_len)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp key ind len. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetIVLength(ismaCrypSId, &(icPp->iv_len)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp iv len. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } } // create the new video track MP4TrackId trackId; if (doEncrypt) { trackId = MP4AddEncVideoTrack( mp4File, Mp4TimeScale, mp4FrameDuration, frameWidth, frameHeight, icPp, MP4_MPEG4_VIDEO_TYPE); } else { trackId = MP4AddVideoTrack( mp4File, Mp4TimeScale, mp4FrameDuration, frameWidth, frameHeight, MP4_MPEG4_VIDEO_TYPE); } if (trackId == MP4_INVALID_TRACK_ID) { fprintf(stderr, "%s: can't create video track\n", ProgName); return MP4_INVALID_TRACK_ID; } if (VideoProfileLevelSpecified) { videoProfileLevel = VideoProfileLevel; } if (MP4GetNumberOfTracks(mp4File, MP4_VIDEO_TRACK_TYPE) == 1) { MP4SetVideoProfileLevel(mp4File, videoProfileLevel); } printf("es config size is %d\n", esConfigSize); if (esConfigSize) { MP4SetTrackESConfiguration(mp4File, trackId, pCurrentSample, esConfigSize); // move past ES config, so it doesn't go into first sample pCurrentSample += esConfigSize; } // Move the current frame to the beginning of the // buffer memmove(sampleBuffer, pCurrentSample, pObj - pCurrentSample + objSize); pObj = sampleBuffer + (pObj - pCurrentSample); pCurrentSample = sampleBuffer; MP4Timestamp prevFrameTimestamp = 0; // now process the rest of the video stream while ( true ) { if ( objType != MP4AV_MPEG4_VOP_START ) { // keep it in the buffer until a VOP comes along // Actually, do nothings, since we only want VOP // headers in the stream - wmay 6/2004 //pObj += objSize; } else { // we have VOP u_int32_t sampleSize = (pObj + objSize) - pCurrentSample; vopType = MP4AV_Mpeg4GetVopType(pObj, objSize); mpeg4_frame_t *fr = MALLOC_STRUCTURE(mpeg4_frame_t); if (head == NULL) { head = tail = fr; } else { tail->next = fr; tail = fr; } fr->vopType = vopType; fr->frameTimestamp = currentSampleTime; fr->next = NULL; if ( variableFrameRate ) { // variable frame rate: recalculate "mp4FrameDuration" if ( lastFrame ) { // last frame mp4FrameDuration = Mp4TimeScale / timeTicks; } else { // not the last frame u_int32_t vopTimeIncrement; MP4AV_Mpeg4ParseVop(pObj, objSize, &vopType, timeBits, timeTicks, &vopTimeIncrement); u_int32_t vopTime = vopTimeIncrement - lastVopTimeIncrement; mp4FrameDuration = (Mp4TimeScale * vopTime) / timeTicks; lastVopTimeIncrement = vopTimeIncrement % timeTicks; } } if ( prevSampleSize > 0 ) { // not the first time // fill sample data & length to write u_int8_t* sampleData2Write = NULL; u_int32_t sampleLen2Write = 0; if ( doEncrypt ) { if ( ismacrypEncryptSampleAddHeader(ismaCrypSId, sampleSize, sampleBuffer, &sampleLen2Write, &sampleData2Write) != 0 ) { fprintf(stderr, "%s: can't encrypt video sample and add header %u\n", ProgName, sampleId); } } else { sampleData2Write = sampleBuffer; sampleLen2Write = prevSampleSize; } if (variableFrameRate == false) { double now_calc; now_calc = sampleId; now_calc *= Mp4TimeScale; now_calc /= VideoFrameRate; MP4Timestamp now_ts = (MP4Timestamp)now_calc; mp4FrameDuration = now_ts - prevFrameTimestamp; prevFrameTimestamp = now_ts; currentSampleTime = now_ts; } // Write the previous sample rc = MP4WriteSample(mp4File, trackId, sampleData2Write, sampleLen2Write, mp4FrameDuration, 0, prevVopType == VOP_TYPE_I); if ( doEncrypt && sampleData2Write ) { // buffer allocated by encrypt function. // must free it! free(sampleData2Write); } if ( !rc ) { fprintf(stderr, "%s: can't write video frame %u\n", ProgName, sampleId); MP4DeleteTrack(mp4File, trackId); return MP4_INVALID_TRACK_ID; } // deal with rendering time offsets // that can occur when B frames are being used // which is the case for all profiles except Simple Profile haveBframes |= (prevVopType == VOP_TYPE_B); if ( lastFrame ) { // finish read frames break; } sampleId++; } // not the first time currentSampleTime += mp4FrameDuration; // Move the current frame to the beginning of the // buffer memmove(sampleBuffer, pCurrentSample, sampleSize); prevSampleSize = sampleSize; prevVopType = vopType; // reset pointers pObj = pCurrentSample = sampleBuffer + sampleSize; } // we have VOP // load next object from bitstream if (!LoadNextObject(inFile, pObj, &objSize, &objType)) { if (objType != MP4AV_MPEG4_VOP_START) break; lastFrame = true; objSize = 0; continue; } // guard against buffer overflow if (pObj + objSize >= pCurrentSample + maxSampleSize) { fprintf(stderr, "%s: buffer overflow, invalid video stream?\n", ProgName); MP4DeleteTrack(mp4File, trackId); return MP4_INVALID_TRACK_ID; } #ifdef DEBUG_MP4V if (Verbosity & MP4_DETAILS_SAMPLE) { printf("MP4V type %x size %u\n", objType, objSize); } #endif } bool doRenderingOffset = false; switch (videoProfileLevel) { case MPEG4_SP_L0: case MPEG4_SP_L1: case MPEG4_SP_L2: case MPEG4_SP_L3: break; default: doRenderingOffset = true; break; } if (doRenderingOffset && haveBframes) { // only generate ctts (with rendering offset for I, P frames) when // we need one. We saved all the frames types and timestamps above - // we can't use MP4ReadSample, because the end frames might not have // been written refVopId = 1; refVopTime = 0; MP4SampleId maxSamples = MP4GetTrackNumberOfSamples(mp4File, trackId); // start with sample 2 - we know the first one is a I frame mpeg4_frame_t *fr = head->next; // skip the first one for (MP4SampleId ix = 2; ix <= maxSamples; ix++) { if (fr->vopType != VOP_TYPE_B) { #ifdef DEBUG_MP4V_TS printf("sample %u %u renderingOffset "U64"\n", refVopId, fr->vopType, fr->frameTimestamp - refVopTime); #endif MP4SetSampleRenderingOffset(mp4File, trackId, refVopId, fr->frameTimestamp - refVopTime); refVopId = ix; refVopTime = fr->frameTimestamp; } fr = fr->next; } #ifdef DEBUG_MP4V_TS printf("sample %u %u renderingOffset "U64"\n", refVopId, fr->vopType, fr->frameTimestamp - refVopTime); #endif MP4SetSampleRenderingOffset(mp4File, trackId, refVopId, fr->frameTimestamp - refVopTime); } while (head != NULL) { tail = head->next; free(head); head = tail; } // terminate session if encrypting if (doEncrypt) { if (ismacrypEndSession(ismaCrypSId) != 0) { fprintf(stderr, "%s: could not end the ISMAcryp session\n", ProgName); } } return trackId; }
static MP4TrackId VideoCreate (MP4FileHandle mp4file, mpeg2ps_t *file, int vstream, bool doEncrypt) { double frame_rate = mpeg2ps_get_video_stream_framerate(file, vstream); uint8_t video_type; uint16_t w, h; MP4TrackId id; ismacryp_session_id_t ismaCrypSId; mp4v2_ismacrypParams *icPp = (mp4v2_ismacrypParams *) malloc(sizeof(mp4v2_ismacrypParams)); memset(icPp, 0, sizeof(mp4v2_ismacrypParams)); #ifdef _WIN32 MP4Duration mp4FrameDuration; mp4FrameDuration = (MP4Duration)((double)Mp4TimeScale / frame_rate); #else MP4Duration mp4FrameDuration = (MP4Duration)(Mp4TimeScale / frame_rate); #endif h = mpeg2ps_get_video_stream_height(file, vstream); w = mpeg2ps_get_video_stream_width(file, vstream); video_type = mpeg2ps_get_video_stream_type(file, vstream) == MPEG_VIDEO_MPEG2 ? MP4_MPEG2_MAIN_VIDEO_TYPE : MP4_MPEG1_VIDEO_TYPE; if (doEncrypt) { // initialize session if (ismacrypInitSession(&ismaCrypSId,KeyTypeVideo) != 0) { fprintf(stderr, "%s: could not initialize the ISMAcryp session\n", ProgName); return MP4_INVALID_TRACK_ID; } if (ismacrypGetScheme(ismaCrypSId, &(icPp->scheme_type)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp scheme type. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetSchemeVersion(ismaCrypSId, &(icPp->scheme_version)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp scheme ver. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetKMSUri(ismaCrypSId, &(icPp->kms_uri)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp kms uri. sid %d\n", ProgName, ismaCrypSId); if (icPp->kms_uri != NULL) free(icPp->kms_uri); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if ( ismacrypGetSelectiveEncryption(ismaCrypSId, &(icPp->selective_enc)) != ismacryp_rc_ok ) { fprintf(stderr, "%s: could not get ismacryp selec enc. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetKeyIndicatorLength(ismaCrypSId, &(icPp->key_ind_len)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp key ind len. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetIVLength(ismaCrypSId, &(icPp->iv_len)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp iv len. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } id = MP4AddEncVideoTrack(mp4file, Mp4TimeScale, mp4FrameDuration, w, h, icPp, video_type); } else { id = MP4AddVideoTrack(mp4file, Mp4TimeScale, mp4FrameDuration, w, h, video_type); } //printf("duration "U64" w %d h %d type %x\n", mp4FrameDuration, w, h, video_type); if (MP4GetNumberOfTracks(mp4file, MP4_VIDEO_TRACK_TYPE) == 1) { MP4SetVideoProfileLevel(mp4file, 0xfe); // undefined profile } if (id == MP4_INVALID_TRACK_ID) { fprintf(stderr, "%s:Couldn't add video track %d", ProgName, vstream); return MP4_INVALID_TRACK_ID; } uint8_t *buf; uint32_t blen; uint32_t frames = 1; #if 0 printf("Processing %lu video frames\n", frames_max); #endif uint32_t refFrame = 1; uint8_t frame_type; while (mpeg2ps_get_video_frame(file, vstream, &buf, &blen, &frame_type, TS_90000, NULL)) { if (buf[blen - 4] == 0 && buf[blen - 3] == 0 && buf[blen - 2] == 1) blen -= 4; // encrypt the sample if neeed if (doEncrypt) { u_int8_t* encSampleData = NULL; u_int32_t encSampleLen = 0; if (ismacrypEncryptSampleAddHeader(ismaCrypSId, blen, buf, &encSampleLen, &encSampleData) != 0) { fprintf(stderr, "%s: can't encrypt video sample and add header %u\n", ProgName, id); } MP4WriteSample(mp4file, id, encSampleData, encSampleLen, mp4FrameDuration, 0, frame_type == 1 ? true : false); if (encSampleData != NULL) { free(encSampleData); } } else { MP4WriteSample(mp4file, id, buf, blen, mp4FrameDuration, 0, frame_type == 1 ? true : false); #if 0 printf("frame %d len %d duration "U64" ftype %d\n", frames, blen, mp4FrameDuration, frame_type); #endif } if (frame_type != 3) { // I or P frame MP4SetSampleRenderingOffset(mp4file, id, refFrame, (frames - refFrame) * mp4FrameDuration); refFrame = frames; } frames++; #if 0 if ((frames % 100) == 0) printf("%d frames\n", frames); #endif } // if encrypting, terminate the ismacryp session if (doEncrypt) { if (ismacrypEndSession(ismaCrypSId) != 0) { fprintf(stderr, "%s: could not end the ISMAcryp session\n", ProgName); return MP4_INVALID_TRACK_ID; } } return id; }
static MP4TrackId AudioCreate (MP4FileHandle mp4file, mpeg2ps_t *file, int astream, bool doEncrypt) { uint16_t freq; int type; MP4TrackId id; uint16_t samples_per_frame; uint8_t *buf = NULL; uint32_t blen = 0; uint32_t frame_num = 1; ismacryp_session_id_t ismaCrypSId; mp4v2_ismacrypParams *icPp = (mp4v2_ismacrypParams *) malloc(sizeof(mp4v2_ismacrypParams)); MP4AV_Mp3Header hdr; u_int8_t mpegVersion; memset(icPp, 0, sizeof(mp4v2_ismacrypParams)); type = mpeg2ps_get_audio_stream_type(file, astream); if (type != MPEG_AUDIO_MPEG) { fprintf(stderr, "Unsupported audio format %d in audio stream %d\n", type, astream); return MP4_INVALID_TRACK_ID; } freq = mpeg2ps_get_audio_stream_sample_freq(file, astream); if (mpeg2ps_get_audio_frame(file, astream, &buf, &blen, TS_90000, NULL, NULL) == false) { fprintf(stderr, "No audio tracks in audio stream %d\n", astream); return MP4_INVALID_TRACK_ID; } hdr = MP4AV_Mp3HeaderFromBytes(buf); mpegVersion = MP4AV_Mp3GetHdrVersion(hdr); samples_per_frame = MP4AV_Mp3GetHdrSamplingWindow(hdr); u_int8_t audioType = MP4AV_Mp3ToMp4AudioType(mpegVersion); if (audioType == MP4_INVALID_AUDIO_TYPE || samples_per_frame == 0) { fprintf(stderr, "%s: data in file doesn't appear to be valid audio\n", ProgName); return MP4_INVALID_TRACK_ID; } MP4Duration duration = (90000 * samples_per_frame) / freq; if (doEncrypt) { // initialize the ismacryp session if (ismacrypInitSession(&ismaCrypSId,KeyTypeAudio) != 0) { fprintf(stderr, "%s: could not initialize the ISMAcryp session\n", ProgName); return MP4_INVALID_TRACK_ID; } if (ismacrypGetScheme(ismaCrypSId, &(icPp->scheme_type)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp scheme type. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetSchemeVersion(ismaCrypSId, &(icPp->scheme_version)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp scheme ver. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetKMSUri(ismaCrypSId, &(icPp->kms_uri)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp kms uri. sid %d\n", ProgName, ismaCrypSId); if (icPp->kms_uri != NULL) free(icPp->kms_uri); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if ( ismacrypGetSelectiveEncryption(ismaCrypSId, &(icPp->selective_enc)) != ismacryp_rc_ok ) { fprintf(stderr, "%s: could not get ismacryp selec enc. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetKeyIndicatorLength(ismaCrypSId, &(icPp->key_ind_len)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp key ind len. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } if (ismacrypGetIVLength(ismaCrypSId, &(icPp->iv_len)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp iv len. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); return MP4_INVALID_TRACK_ID; } id = MP4AddEncAudioTrack(mp4file, 90000, duration, icPp, audioType); } else { id = MP4AddAudioTrack(mp4file, 90000, duration, audioType); } if (id == MP4_INVALID_TRACK_ID) { fprintf(stderr, "%s: can't create audio track from stream %d\n", ProgName, astream); return MP4_INVALID_TRACK_ID; } if (MP4GetNumberOfTracks(mp4file, MP4_AUDIO_TRACK_TYPE) == 1) { MP4SetAudioProfileLevel(mp4file, 0xFE); } do { // encrypt if needed if (doEncrypt) { u_int8_t* encSampleData = NULL; u_int32_t encSampleLen = 0; if (ismacrypEncryptSampleAddHeader(ismaCrypSId, blen, buf, &encSampleLen, &encSampleData) != 0) { fprintf(stderr, "%s: can't encrypt audio sample and add header %u\n", ProgName, id); } // now write the sample if (!MP4WriteSample(mp4file, id, encSampleData, encSampleLen)) { fprintf(stderr, "%s: can't write audio track %u, stream %d", ProgName, frame_num, astream); MP4DeleteTrack(mp4file, id); return MP4_INVALID_TRACK_ID; } if (encSampleData != NULL) { free(encSampleData); } } // now write the sample if (!MP4WriteSample(mp4file, id, buf, blen)) { fprintf(stderr, "%s: can't write audio track %u, stream %d", ProgName, frame_num, astream); MP4DeleteTrack(mp4file, id); return MP4_INVALID_TRACK_ID; } frame_num++; #if 0 if ((frame_num % 100) == 0) printf("Audio frame %d\n", frame_num); #endif } while (mpeg2ps_get_audio_frame(file, astream, &buf, &blen, TS_90000, NULL, NULL)); // if encrypting, terminate the ismacryp session if (doEncrypt) { if (ismacrypEndSession(ismaCrypSId) != 0) { fprintf(stderr, "%s: could not end the ISMAcryp session\n", ProgName); return MP4_INVALID_TRACK_ID; } } return id; }