⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp4v.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	  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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -