zoukankan      html  css  js  c++  java
  • Ubuntu 编译 ffmpeg tutorial01.c

    环境搭建参考 Ubuntu 10.10 x64 apt安装 ffmpeg

    需要修改以下几个地方才能编译通过

    • include 头文件的位置
    • undefined reference to 'img_convert'
    • 编译参数

    以下是修改后的代码

    // tutorial01.c
    // Code based on a tutorial by Martin Bohme (boehme@inb.uni-luebeckREMOVETHIS.de)
    // Tested on Gentoo, CVS version 5/01/07 compiled with GCC 4.1.1

    // A small sample program that shows how to use libavformat and libavcodec to
    // read video from a file.
    //
    // Use
    //
    // gcc -o tutorial01 tutorial01.c -lavformat -lavcodec -lavutil -lswscale
    //
    // to build (assuming libavformat and libavcodec are correctly installed
    // your system).
    //
    // Run using
    //
    // tutorial01 sample_100kbit.mp4
    //
    // to write the first five frames from "sample_100kbit.mp4" to disk in PPM
    // format.

    #include
    <libavcodec/avcodec.h>
    #include
    <libavformat/avformat.h>
    #include
    <libswscale/swscale.h>

    #include
    <stdio.h>

    void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
    FILE
    *pFile;
    char szFilename[32];
    int y;

    // Open file
    sprintf(szFilename, "frame%d.ppm", iFrame);
    pFile
    =fopen(szFilename, "wb");
    if(pFile==NULL)
    return;

    // Write header
    fprintf(pFile, "P6\n%d %d\n255\n", width, height);

    // Write pixel data
    for(y=0; y<height; y++)
    fwrite(pFrame
    ->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);

    // Close file
    fclose(pFile);
    }

    int main(int argc, char *argv[]) {
    AVFormatContext
    *pFormatCtx;
    int i, videoStream;
    AVCodecContext
    *pCodecCtx;
    AVCodec
    *pCodec;
    AVFrame
    *pFrame;
    AVFrame
    *pFrameRGB;
    AVPacket packet;
    int frameFinished;
    int numBytes;
    uint8_t
    *buffer;
    struct SwsContext *img_convert_ctx;

    if(argc < 2) {
    printf(
    "Please provide a movie file\n");
    return -1;
    }
    // Register all formats and codecs
    av_register_all();

    // Open video file
    if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0)
    return -1; // Couldn't open file

    // Retrieve stream information
    if(av_find_stream_info(pFormatCtx)<0)
    return -1; // Couldn't find stream information

    // Dump information about file onto standard error
    dump_format(pFormatCtx, 0, argv[1], 0);

    // Find the first video stream
    videoStream=-1;
    for(i=0; i<pFormatCtx->nb_streams; i++)
    if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
    videoStream
    =i;
    break;
    }
    if(videoStream==-1)
    return -1; // Didn't find a video stream

    // Get a pointer to the codec context for the video stream
    pCodecCtx=pFormatCtx->streams[videoStream]->codec;
       img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height,PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);// other codes
        // Find the decoder for the video stream
    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
    if(pCodec==NULL) {
    fprintf(stderr,
    "Unsupported codec!\n");
    return -1; // Codec not found
    }
    // Open codec
    if(avcodec_open(pCodecCtx, pCodec)<0)
    return -1; // Could not open codec

    // Allocate video frame
    pFrame=avcodec_alloc_frame();

    // Allocate an AVFrame structure
    pFrameRGB=avcodec_alloc_frame();
    if(pFrameRGB==NULL)
    return -1;

    // Determine required buffer size and allocate buffer
    numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
    pCodecCtx
    ->height);
    buffer
    =(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));

    // Assign appropriate parts of buffer to image planes in pFrameRGB
    // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
    // of AVPicture
    avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
    pCodecCtx
    ->width, pCodecCtx->height);

    // Read frames and save first five frames to disk
    i=0;
    while(av_read_frame(pFormatCtx, &packet)>=0) {
    // Is this a packet from the video stream?
    if(packet.stream_index==videoStream) {
    // Decode video frame
    avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
    packet.data, packet.size);

    // Did we get a video frame?
    if(frameFinished) {
    // Convert the image from its native format to RGB
    //img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24, (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height)

    // Convert the image from its native format to RGB
    sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize,0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);

    // Save the frame to disk
    if(++i<=5)
    SaveFrame(pFrameRGB, pCodecCtx
    ->width, pCodecCtx->height,
    i);
    }
    }

    // Free the packet that was allocated by av_read_frame
    av_free_packet(&packet);
    }

    // Free the Sws context
    sws_freeContext(img_convert_ctx);

    // Free the RGB image
    av_free(buffer);
    av_free(pFrameRGB);

    // Free the YUV frame
    av_free(pFrame);

    // Close the codec
    avcodec_close(pCodecCtx);

    // Close the video file
    av_close_input_file(pFormatCtx);

    return 0;
    }

    编译命令

    gcc -o tutorial01 tutorial01.c -lavformat -lavcodec -lavutil -lswscale

    参考

  • 相关阅读:
    剑指 Offer 51. 数组中的逆序对
    剑指 Offer 68
    剑指 Offer 68
    JS绑定事件三种方式
    图片懒加载原理及实现
    资源加载过程
    了解JS单线程和任务队列!
    JS函数作用域提升
    JS函数种类详解
    ES6之模版字符串
  • 原文地址:https://www.cnblogs.com/shaobin0604/p/2147870.html
Copyright © 2011-2022 走看看