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

📄 mpeg.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 4 页
字号:
        bbP = Bitio_New(NULL);    else {        const char * fileName;        asprintfN(&fileName, "%s.frame.%d", outputFileName, frameNumber);        bbP = Bitio_New_Filename(fileName);        strfree(fileName);    }    return bbP;}static voidgetBFrame(int                  const frameNum,          struct inputSource * const inputSourceP,          MpegFrame *          const pastRefFrameP,          boolean              const childProcess,          boolean              const remoteIO,          MpegFrame **         const bFramePP,          int *                const IOtimeP,          unsigned int *       const framesReadP) {/*----------------------------------------------------------------------------   Get Frame 'frameNum', which is a B frame related to previous reference   frame 'pastRefFrameP'.  Return it as *bFramePP.   We have various ways of getting the frame, corresponding to the   multitude of modes in which Ppmtompeg works.-----------------------------------------------------------------------------*/    if (!inputSourceP->stdinUsed) {        time_t tempTimeStart, tempTimeEnd;        MpegFrame * bFrameP;        bFrameP = Frame_New(frameNum, 'b');        time(&tempTimeStart);        ReadNthFrame(inputSourceP, frameNum, remoteIO, childProcess,                     separateConversion, slaveConversion, inputConversion,                     bFrameP);        time(&tempTimeEnd);        *IOtimeP += (tempTimeEnd-tempTimeStart);        ++(*framesReadP);        *bFramePP = bFrameP;    } else {        /* As the frame input is serial, we can't read the B frame now.           Rather, Caller has already read it and chained it to            the previous reference frame.  So we get that copy now.        */        *bFramePP = pastRefFrameP->next;        pastRefFrameP->next = (*bFramePP)->next;  /* unlink from list */    }}static voidprocessBFrames(MpegFrame *          const pastRefFrameP,               MpegFrame *          const futureRefFrameP,               int                  const realStart,               int                  const realEnd,               struct inputSource * const inputSourceP,               boolean              const remoteIo,               boolean              const childProcess,               int *                const IOtimeP,               BitBucket *          const wholeStreamBbP,               const char *         const outputFileName,               unsigned int *       const framesReadP,               unsigned int *       const framesOutputP,               int *                const currentGopP) {/*----------------------------------------------------------------------------   Process the B frames that go between 'pastRefFrameP' and   'futureRefFrame' in the movie (but go after 'futureRefFrameP' in the   MPEG stream, so reader doesn't have to read ahead).   Remember that a B frame is one which is described by data in the   MPEG stream that describes the frame with respect to a frame somewhere   before it, and a frame somewhere after it (i.e. reference frames).   But do only those B frames whose frame numbers are within the range   'realStart' through 'realEnd'.-----------------------------------------------------------------------------*/    boolean const separateFiles = (wholeStreamBbP == NULL);    unsigned int const firstBFrameNum = pastRefFrameP->id + 1;    int frameNum;    assert(pastRefFrameP != NULL);    assert(futureRefFrameP != NULL);        for (frameNum = MAX(realStart, firstBFrameNum);          frameNum < MIN(realEnd, futureRefFrameP->id);          ++frameNum) {        MpegFrame * bFrame;        BitBucket * bbP;        getBFrame(frameNum, inputSourceP, pastRefFrameP, childProcess,                   remoteIO,                  &bFrame, IOtimeP, framesReadP);        if (separateFiles)            bbP = bitioNew(outputFileName, bFrame->id, remoteIO);        else            bbP = wholeStreamBbP;        GenBFrame(bbP, bFrame, pastRefFrameP, futureRefFrameP);        ++(*framesOutputP);        if (separateFiles) {            if (remoteIO)                SendRemoteFrame(bFrame->id, bbP);            else {                Bitio_Flush(bbP);                Bitio_Close(bbP);            }        }        /* free this B frame right away */        Frame_Free(bFrame);        numB--;        timeMask &= 0x3;        ShowRemainingTime(childProcess);        ++(*currentGopP);        IncrementTCTime();    }}static voidprocessRefFrame(MpegFrame *    const frameP,                 BitBucket *    const bb_arg,                int            const lastFrame,                int            const realStart,                int            const realEnd,                MpegFrame *    const pastRefFrameP,                boolean        const childProcess,                const char *   const outputFileName,                unsigned int * const framesReadP,                unsigned int * const framesOutputP) {/*----------------------------------------------------------------------------   Process an I or P frame.  Encode and output it.   But only if its frame number is within the range 'realStart'   through 'realEnd'.-----------------------------------------------------------------------------*/    if (frameP->id >= realStart && frameP->id <= realEnd) {        boolean separateFiles;        BitBucket * bb;          separateFiles = (bb_arg == NULL);          if ( separateFiles )            bb = bitioNew(outputFileName, frameP->id, remoteIO);        else            bb = bb_arg;          /* first, output this reference frame */        switch (frameP->type) {        case TYPE_IFRAME:            outputIFrame(frameP, bb, realStart, realEnd, pastRefFrameP,                          separateFiles);            break;        case TYPE_PFRAME:            outputPFrame(frameP, bb, realStart, realEnd, pastRefFrameP);            ShowRemainingTime(childProcess);            break;        default:            pm_error("INTERNAL ERROR: non-reference frame passed to "                     "ProcessRefFrame()");        }                  ++(*framesOutputP);                finishFrameOutput(frameP, bb, separateFiles, referenceFrame,                          childProcess, remoteIO);    }}static voidcountFrames(unsigned int const firstFrame,            unsigned int const lastFrame,            boolean      const stdinUsed,            int *        const numIP,            int *        const numPP,            int *        const numBP,            int *        const timeMaskP,            boolean *    const frameCountsUnknownP) {/*----------------------------------------------------------------------------  Count number of I, P, and B frames-----------------------------------------------------------------------------*/    unsigned int numI, numP, numB;    unsigned int timeMask;                numI = 0; numP = 0; numB = 0;    timeMask = 0;    if (stdinUsed) {        numI = numP = numB = MAXINT/4;        *frameCountsUnknownP = TRUE;    } else {        unsigned int i;        for (i = firstFrame; i <= lastFrame; ++i) {            char const frameType = FType_Type(i);            switch(frameType) {            case 'i':        numI++;            timeMask |= 0x1;    break;            case 'p':        numP++;            timeMask |= 0x2;    break;            case 'b':        numB++;            timeMask |= 0x4;    break;            }        }        *frameCountsUnknownP = FALSE;    }    *numIP     = numI;    *numPP     = numP;    *numBP     = numB;    *timeMaskP = timeMask;    *frameCountsUnknownP = frameCountsUnknown;}static voidreadAndSaveFrame(struct inputSource * const inputSourceP,                 unsigned int         const frameNumber,                 char                 const frameType,                 const char *         const inputConversion,                 MpegFrame *          const pastRefFrameP,                 unsigned int *       const framesReadP,                 int *                const ioTimeP) {/*----------------------------------------------------------------------------   Read the next frame from Standard Input and add it to the linked list   at *pastRefFrameP.  Assume it is Frame Number 'frameNumber' and is of   type 'frameType'.      Add the time it took to read it, in seconds, to *iotimeP.-----------------------------------------------------------------------------*/    /* This really should be part of ReadNthFrame.  The frame should be chained       to the input object, not the past reference frame.    */           MpegFrame * p;    MpegFrame * frameP;    time_t ioTimeStart, ioTimeEnd;        time(&ioTimeStart);    frameP = Frame_New(frameNumber, frameType);    ReadFrame(frameP, inputSourceP, frameNumber, inputConversion);        ++(*framesReadP);        time(&ioTimeEnd);    *ioTimeP += (ioTimeEnd - ioTimeStart);    /* Add the B frame to the end of the queue of B-frames        for later encoding.    */    assert(pastRefFrameP != NULL);        p = pastRefFrameP;    while (p->next != NULL)        p = p->next;    p->next = frameP;}static voiddoFirstFrameStuff(enum frameContext const context,                  const char *      const userDataFileName,                  BitBucket *       const bb,                  int               const fsize_x,                  int               const fsize_y,                  int               const aspectRatio,                  int               const frameRate,                  int32             const qtable[],                  int32             const niqtable[],                  unsigned int *    const inputFrameBitsP) {/*----------------------------------------------------------------------------   Do stuff we have to do after reading the first frame in a sequence   of frames requested of GenMPEGStream().-----------------------------------------------------------------------------*/    *inputFrameBitsP = 24*Fsize_x*Fsize_y;    SetBlocksPerSlice();              if (context == CONTEXT_WHOLESTREAM) {        int32 const bitstreamMode = getRateMode();        char * userData;        unsigned int userDataSize;        assert(bb != NULL);        DBG_PRINT(("Generating sequence header\n"));        if (bitstreamMode == FIXED_RATE) {            bit_rate = getBitRate();            buf_size = getBufferSize();        } else {            bit_rate = -1;            buf_size = -1;        }                if (strlen(userDataFileName) != 0) {            struct stat statbuf;            FILE *fp;                      stat(userDataFileName,&statbuf);            userDataSize = statbuf.st_size;            userData = malloc(userDataSize);            fp = fopen(userDataFileName,"rb");            if (fp == NULL) {                pm_message("Could not open userdata file '%s'.",                           userDataFileName);                userData = NULL;                userDataSize = 0;            } else {                size_t bytesRead;                bytesRead = fread(userData,1,userDataSize,fp);                if (bytesRead != userDataSize) {                    pm_message("Could not read %d bytes from "                               "userdata file '%s'.",                               userDataSize,userDataFileName);                    userData = NULL;                    userDataSize = 0;                }            }        } else { /* Put in our UserData Header */            const char * userDataString;            time_t now;                                time(&now);            asprintfN(&userDataString,"MPEG stream encoded by UCB Encoder "                      "(mpeg_encode) v%s on %s.",                      VERSION, ctime(&now));            userData = strdup(userDataString);            userDataSize = strlen(userData);            strfree(userDataString);        }        Mhead_GenSequenceHeader(bb, Fsize_x, Fsize_y,                                /* pratio */ aspectRatio,                                /* pict_rate */ frameRate,                                 /* bit_rate */ bit_rate,                                /* buf_size */ buf_size,                                /*c_param_flag */ 1,                                /* iq_matrix */ qtable,                                 /* niq_matrix */ niqtable,                                /* ext_data */ NULL,                                /* ext_data_size */ 0,                                /* user_data */ (uint8*) userData,                                /* user_data_size */ userDataSize);    }}static voidgetPreviousFrame(unsigned int         const frameStart,                 int                  const referenceFrame,                 struct inputSource * const inputSourceP,                 boolean              const childProcess,                 const char *         const slaveConversion,                 const char *         const inputConversion,                 MpegFrame **         const framePP,                 unsigned int *       const framesReadP,                 int *                const ioTimeP) {    MpegFrame * frameP;    time_t ioTimeStart, ioTimeEnd;    /* can't find the previous frame interactively */    if (inputSourceP->stdinUsed)        pm_error("Cannot encode GOP from stdin when "                 "first frame is a B-frame.");    if (frameStart < 1)        pm_error("Cannot encode GOP when first frame is a B-frame "                 "and is not preceded by anything.");    /* need to load in previous frame; call it an I frame */    frameP = Frame_New(frameStart-1, 'i');    time(&ioTimeStart);    if ((referenceFrame == DECODED_FRAME) && childProcess) {        WaitForDecodedFrame(frameStart);        if (remoteIO)            GetRemoteDecodedRefFrame(frameP, frameStart - 1);        else            ReadDecodedRefFrame(frameP, frameStart - 1);    } else        ReadNthFrame(inputSourceP, frameStart - 1, remoteIO, childProcess,                     separateConversion, slaveConversion, inputConversion,                     frameP);                ++(*framesReadP);        time(&ioTimeEnd);    *ioTimeP += (ioTimeEnd-ioTimeStart);

⌨️ 快捷键说明

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