FFMPEG 視頻編碼流程

來源:互聯網
上載者:User

代碼截取自FFMPEG官方example,添加註釋以FFMPEG的編碼流程就變得很清楚了

static void video_encode_example(const char *filename, int codec_id){                                                                    //1.定義如下資料結構    AVCodec *codec;    AVCodecContext *c= NULL;    int i, ret, x, y, got_output;    FILE *f;    AVFrame *frame;    AVPacket pkt;    uint8_t endcode[] = { 0, 0, 1, 0xb7 };//MPEG檔案尾      printf("Encode video file %s\n", filename);        /* find the mpeg1 video encoder */    codec = avcodec_find_encoder(codec_id);                         //2.尋找編碼器    if (!codec) {        fprintf(stderr, "Codec not found\n");        exit(1);    }        c = avcodec_alloc_context3(codec);                              //3.分配編碼器結構體    if (!c) {        fprintf(stderr, "Could not allocate video codec context\n");        exit(1);    }        /* put sample parameters */                                     //4.設定編碼器參數    c->bit_rate = 400000;    /* resolution must be a multiple of two */    c->width = 352;    c->height = 288;    /* frames per second */    c->time_base= (AVRational){1,25};    c->gop_size = 10; /* emit one intra frame every ten frames */    c->max_b_frames=1;    c->pix_fmt = AV_PIX_FMT_YUV420P;    if(codec_id == AV_CODEC_ID_H264)        av_opt_set(c->priv_data, "preset", "slow", 0);        /* open it */    if (avcodec_open2(c, codec, NULL) < 0) {                        //5.開啟編碼器        fprintf(stderr, "Could not open codec\n");        exit(1);    }        f = fopen(filename, "wb");                                      //6.開啟檔案    if (!f) {        fprintf(stderr, "Could not open %s\n", filename);        exit(1);    }        frame = avcodec_alloc_frame();                                  //7.分配幀結構體    if (!frame) {        fprintf(stderr, "Could not allocate video frame\n");        exit(1);    }    frame->format = c->pix_fmt;    frame->width  = c->width;    frame->height = c->height;    /* the image can be allocated by any means and av_image_alloc() is     * just the most convenient way if av_malloc() is to be used */                                                                    //8.分配幀資料空間frame->data,     ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,                         c->pix_fmt, 32);    if (ret < 0) {        fprintf(stderr, "Could not allocate raw picture buffer\n");        exit(1);    }    /* encode 1 second of video */    for(i=0;i<25;i++) {               av_init_packet(&pkt);                                        //9.初始化 packet 結構體,packet資料由編碼器分配        pkt.data = NULL;    // packet data will be allocated by the encoder        pkt.size = 0;        fflush(stdout);        /* prepare a dummy image */        /* Y */                                                                    //10.設定幀資料        for(y=0;y<c->height;y++) {            for(x=0;x<c->width;x++) {                frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;            }        }        /* Cb and Cr */        for(y=0;y<c->height/2;y++) {            for(x=0;x<c->width/2;x++) {                frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;                frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;            }        }        frame->pts = i;        /* encode the image */                                      //11.編碼一幀資料到 packet 中                ret = avcodec_encode_video2(c, &pkt, frame, &got_output);        if (ret < 0) {            fprintf(stderr, "Error encoding frame\n");            exit(1);        }        if (got_output) {            printf("Write frame %3d (size=%5d)\n", i, pkt.size);            fwrite(pkt.data, 1, pkt.size, f);            av_free_packet(&pkt);        }    }    /* get the delayed frames */                                    //12.編碼延遲幀,avcodec_encode_video2()中 frame參數置為NULL    for (got_output = 1; got_output; i++) {        fflush(stdout);        ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);            if (ret < 0) {            fprintf(stderr, "Error encoding frame\n");            exit(1);        }        if (got_output) {            printf("Write frame %3d (size=%5d)\n", i, pkt.size);            fwrite(pkt.data, 1, pkt.size, f);            av_free_packet(&pkt);                                   //13.釋放 packet        }    }    /* add sequence end code to have a real mpeg file */        fwrite(endcode, 1, sizeof(endcode), f);                         //14.寫入MPEG檔案尾,close檔案和結構體,釋放指標資料    fclose(f);    avcodec_close(c);    av_free(c);    av_freep(&frame->data[0]);    avcodec_free_frame(&frame);    printf("\n");}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.