zoukankan      html  css  js  c++  java
  • ffmpeg打开视频文件

    下载地址:

    https://ffmpeg.zeranoe.com/builds/

    .h文件

    extern "C" {

    #include "libavcodec/avcodec.h"

    #include "libavformat/avformat.h"

    #include "libavutil/avutil.h"

    #include "libavutil/mem.h"

    #include "libavutil/fifo.h"

    #include "libswscale/swscale.h"

    }

    //dll导出lib

    implib -a avcodec.lib avcodec-58.dll

    ....

    .....

    视频解码

    1. 打开输入文件 avformat_open_input
    2. 找到视频流 av_find_best_stream
    3. 找到对应的解码器 avcodec_find_decoder
    4. 初始化一个编解码上下文 avcodec_alloc_context3
    5. 拷贝流参数到编解码上下文中 avcodec_parameters_to_context
    6. 打开解码器 avcodec_open2
    7. 读取视频帧 av_read_frame
    8. 发送等待解码帧 avcodec_send_packet
    9. 接收解码后frame数据 avcodec_receive_frame


    作者:MzDavid
    链接:https://www.jianshu.com/p/3886bc5846c9
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    //打开视频文件

    int ret;
    // const char *out_filename;
    const char *in_filename = "g:\su\test.mp4";
    AVFormatContext *fmt_ctx = NULL;

    const AVCodec *codec;
    AVCodecContext *codeCtx = NULL;

    AVStream *stream = NULL;
    int stream_index;

    AVPacket avpkt;

    int frame_count;
    AVFrame *frame;

    // 1
    if (avformat_open_input(&fmt_ctx, in_filename, NULL, NULL) < 0) {
    printf("Could not open source file %s ", in_filename);
    exit(1);
    }

    if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
    printf("Could not find stream information ");
    exit(1);
    }

    av_dump_format(fmt_ctx, 0, in_filename, 0);

    av_init_packet(&avpkt);
    avpkt.data = NULL;
    avpkt.size = 0;

    // 2
    stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
    if (ret < 0) {
    fprintf(stderr, "Could not find %s stream in input file '%s' ",
    av_get_media_type_string(AVMEDIA_TYPE_VIDEO), in_filename);
    return ;
    }

    stream = fmt_ctx->streams[stream_index];

    // 3
    codec = avcodec_find_decoder(stream->codecpar->codec_id);
    if (codec == NULL) {
    return ;
    }

    // 4
    codeCtx = avcodec_alloc_context3(NULL);
    if (!codeCtx) {
    fprintf(stderr, "Could not allocate video codec context ");
    return;
    }


    // 5
    if ((ret = avcodec_parameters_to_context(codeCtx, stream->codecpar)) < 0) {
    fprintf(stderr, "Failed to copy %s codec parameters to decoder context ",
    av_get_media_type_string(AVMEDIA_TYPE_VIDEO));
    return;
    }

    // 6
    avcodec_open2(codeCtx, codec, NULL);


    //初始化frame,解码后数据
    frame = av_frame_alloc();
    if (!frame) {
    fprintf(stderr, "Could not allocate video frame ");
    exit(1);
    }

    frame_count = 0;
    char buf[1024];
    // 7
    while (av_read_frame(fmt_ctx, &avpkt) >= 0) {
    if (avpkt.stream_index == stream_index) {
    // 8
    int re = avcodec_send_packet(codeCtx, &avpkt);
    if (re < 0) {
    continue;
    }

    // 9 这里必须用while(),因为一次avcodec_receive_frame可能无法接收到所有数据
    while (avcodec_receive_frame(codeCtx, frame) == 0) {

    //

    }

    frame_count++;
    }
    av_packet_unref(&avpkt);
    }

  • 相关阅读:
    npm 插件发布和使用
    git 配置与删除远程地址
    elment 编辑输出行数据后,过滤下拉,值必须全等于下拉值
    后台 接口 传值 不同类型的详细解说
    Vue vscode调试
    vue 标题和输入框分两行,调成一行
    ES6 学习笔记(持续更新中)
    vue开发WebApp 开发笔记(持续更新)
    移动端自适应方案 对应设计图制作
    css 颜色使用预览 码表
  • 原文地址:https://www.cnblogs.com/suhq/p/13275366.html
Copyright © 2011-2022 走看看