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

📄 mp4v.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is MPEG4IP. * * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved. * * Portions created by Ximpo Group Ltd. are * Copyright (C) Ximpo Group Ltd. 2003, 2004.  All Rights Reserved. * * Contributor(s): *		Dave Mackie                dmackie@cisco.com *              Alix Marchandise-Franquet  alix@cisco.com *		Ximpo Group Ltd.           mp4v2@ximpo.com *///#define DEBUG_MP4V 1//#define DEBUG_MP4V_TS 1/* * Notes: *  - file formatted with tabstops == 4 spaces */#include <mp4creator.h>typedef struct mpeg4_frame_t {  mpeg4_frame_t *next;  MP4Timestamp frameTimestamp;  int vopType;} mpeg4_frame_t;/* * Load the next syntatic object from the file * into the supplied buffer, which better be large enough! * * Objects are delineated by 4 byte start codes (0x00 0x00 0x01 0x??) * Objects are padded to byte boundaries, and the encoder assures that * the start code pattern is never generated for encoded data */static int LoadNextObject(FILE* inFile,        u_int8_t* pBuf, u_int32_t* pBufSize, u_int8_t* pObjCode){    static u_int8_t state = 0;    static u_int8_t nextObjCode = 0;    *pBufSize = 0;    /* initial state, never read from file before */    if (state == 0) {        /*         * go looking for first sync word         * we discard anything before this         */        state = 1;        while (state < 5) {            /* read a byte */            u_char b;            if (fread(&b, 1, 1, inFile) == 0) {                // EOF or IO error                return 0;            }            switch (state) {                case 1:                    if (b == 0) {                        state = 2;                    }                    break;                case 2:                    if (b == 0) {                        state = 3;                    }                    break;                case 3:                    if (b == 1) {                        state = 4;                    }                    break;                case 4:                    pBuf[0] = 0;                    pBuf[1] = 0;                    pBuf[2] = 1;                    pBuf[3] = b;                    (*pObjCode) = (u_int)b;                    *pBufSize = 4;                    state = 5;                    break;            }        }        /* we're primed now */        state = 1;    } else if (state == 5) {        state = 0;        return 0;    } else {        /*         * We have next object code from prevous call         * insert start code into buffer         */        (*pObjCode) = nextObjCode;        pBuf[(*pBufSize)++] = 0;        pBuf[(*pBufSize)++] = 0;        pBuf[(*pBufSize)++] = 1;        pBuf[(*pBufSize)++] = (u_char)(*pObjCode);    }    /* read bytes, execute state machine */    while (1) {        /* read a byte */        u_char b;        if (fread(&b, 1, 1, inFile) == 0) {            /* handle EOF */            if (feof(inFile)) {                switch (state) {                    case 3:                        pBuf[(*pBufSize)++] = 0;                        /* fall thru */                    case 2:                        pBuf[(*pBufSize)++] = 0;                        break;                }                state = 5;                return 1;            }            /* else error */            *pBufSize = 0;            return 0;        }        switch (state) {            case 1:                if (b == 0) {                    state = 2;                } else {                    pBuf[(*pBufSize)++] = b;                }                break;            case 2:                if (b == 0) {                    state = 3;                } else {                    pBuf[(*pBufSize)++] = 0;                    pBuf[(*pBufSize)++] = b;                    state = 1;                }                break;            case 3:                if (b == 1) {                    state = 4;                } else if (b == 0) {                    pBuf[(*pBufSize)++] = 0;                    // state remains 3                } else {                    pBuf[(*pBufSize)++] = 0;                    pBuf[(*pBufSize)++] = 0;                    pBuf[(*pBufSize)++] = b;                    state = 1;                }                break;            case 4:                nextObjCode = b;                state = 1;                return 1;            default:                ASSERT(false);        }    }}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;

⌨️ 快捷键说明

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