音视频处理 ffmpeg中级开发 H264编码

这篇具有很好参考价值的文章主要介绍了音视频处理 ffmpeg中级开发 H264编码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

开发介绍

  • libavcodec/avcodec.h
  • 常用的数据结构
    • AVCodec 编码器结构体
    • AVCodecContext 编码器上下文
    • AVFrame 解码后的帧
  • 结构体内存的分配和释放
    • av_frame_alloc 申请
    • av_frame_free() 释放
    • avcodec_alloc_context3() 创建编码器上下文
    • avcodec_free_context() 释放编码器上下文
  • 解码步骤
    • avcodec_find_decoder 查找解码器
    • avcodec_open2 打开解码器
    • avcodec_decode_video2 解码

FFMpegH264编码

  • avcodec_find_encoder_by_name 查找编码器
  • avcodec_open3  设置编码参数(分辨率、高、宽),并打开编码器,(解码的时候直接拷贝对应参数即可,无需再次设置)
  • avcodec_encode_video2 编码
    • 真正执行编码的由第三方库进行
    • 如libx264 libopenh264
  • 注意
    • 通过ID       查找编/解码器
    • 通过Name 查找编/解码器
  • 参考链接:FFmpeg h264编码 - 简书

代码

#include <cstdio>
#include <cstdlib>
#include <cstring>

extern "C" {
    #include<libavutil/opt.h>
    #include<libavutil/imgutils.h>
    #include<libavcodec/avcodec.h>
}

//对每一帧数据进行编码
static void encode(AVCodecContext *enc_ctx,AVFrame *frame,AVPacket *pkt,FILE *outfile){
    int ret = 0;
    //send the frame to the encoder
    if (frame){
        printf("Send frame %3"PRId64"\n",frame->pts);
    }
    ret = avcodec_send_frame(enc_ctx,frame);
    if (ret < 0){
        fprintf(stderr,"Error sending a frame for encoding\n");
        exit(1);
    }
    while (ret >= 0){
        ret = avcodec_receive_packet(enc_ctx,pkt);
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){
            return;
        } else if (ret < 0){
            fprintf(stderr,"Error during encoding\n");
            exit(1);
        }
        printf("Write packet %3"PRId64" (size=%5d)\n",pkt->pts,pkt->size);
        fwrite(pkt->data,1,pkt->size,outfile);
        av_packet_unref(pkt);
    }
}
int main(int argc,char** argv){
    const char *file_name,*codec_name;//输出文件路径和编码器名字,由运行程序时传入参数(要编码的内容是从摄像头获取的)
    const AVCodec *codec;             //编码器
    AVCodecContext *codec_context = nullptr;//编码上下文环境
    int i,ret,x,y,got_output;         //got_output用于标记一帧是否压缩成功
    FILE *file;
    AVFrame *frame;                   //原始帧(未压缩的数据)
    AVPacket pkt;
    uint8_t endcode[]={0,0,1,0xb7};

    if (argc <= 2){
        fprintf(stderr,"Usage: %s <output file> <codec name>\n",argv[0]);
        exit(0);
    }
    file_name = argv[1];
    codec_name = argv[2];     //h264编码器名字是libx264
    //avcodec_register_all()  //delete
    //通过名字查找编码器
    codec = avcodec_find_encoder_by_name(codec_name);
    if (!codec){
        fprintf(stderr,"Codec not found\n");
        exit(1);
    }
    //生成编码上下文环境
    codec_context = avcodec_alloc_context3(codec);
    if (!codec_context){
        fprintf(stderr,"Could not allocate video codec context\n");
        exit(1);
    }
    // 设置码率
    codec_context->bit_rate = 400000;
    // 设置视频宽高
    codec_context->width = 352;
    codec_context->height = 288;
    // 设置时间基、帧率(时间基根据帧率而变化)
    codec_context->time_base = (AVRational){1,25}; //一秒钟25帧,刻度就是1/25
    codec_context->framerate = (AVRational){25,1}; //时间基根据帧率进行变化
    // 设置多少帧产生一个关键帧,也就是一组帧是多少帧
    // 如果同一个镜头没有变化,只需要设定一个关键帧,一组帧以这个关键帧作为参照,从而降低数据存储
    codec_context->gop_size = 10;
    // 设置b帧(前后参考帧)
    // P帧 向前参考帧
    codec_context->max_b_frames = 1;
    // 要编码的原始数据的YUV格式
    codec_context->pix_fmt = AV_PIX_FMT_YUV420P;
    // 如果编码器id是h264
    if (codec->id == AV_CODEC_ID_H264){
        // preset表示采用一个预先设定好的参数集,级别是slow
        // slow表示压缩速度是慢的,慢的可以保证视频质量,用快的会降低视频质量
        av_opt_set(codec_context->priv_data,"preset","slow",0);
    }
    // 打开编码器
    if (avcodec_open2(codec_context,codec,NULL) < 0){
        fprintf(stderr,"Could not open codec\n");
        exit(1);
    }

    file = fopen(file_name,"wb");
    if (!file){
        fprintf(stderr,"Could not open %s\n",file_name);
        exit(1);
    }
    // 初始化帧并设置帧的YUV格式和分辨率
    frame = av_frame_alloc();
    if (!frame){
        fprintf(stderr,"Could not allocate video frame\n");
        exit(1);
    }
    frame->format = codec_context->pix_fmt;
    frame->width = codec_context->width;
    frame->height = codec_context->height;

    ret = av_frame_get_buffer(frame,32);
    if (ret < 0){
        fprintf(stderr,"Could not allocate the video frame data\n");
        exit(1);
    }
    // 这里是人工添加数据模拟生成1秒钟(25帧)的视频(真实应用中是从摄像头获取的原始数据,摄像头拿到数据后会传给编码器,然后编码器进行编码形成一帧帧数据。)
    for (i = 0; i < 25; i++) {
        av_init_packet(&pkt);//packet data will be allocated by the encoder
        pkt.data = NULL;
        pkt.size = 0;
        // 强制输出写入文件
        fflush(stdout);
        /* make sure the frame data is writable */
        ret = av_frame_make_writable(frame);
        if (ret < 0){
            exit(1);
        }
        // 下面2个循环是人工往frame里面添的数据
        /* Y */
        for (int y = 0; y < codec_context->height; y++) {
            for (int x = 0; x < codec_context->width; x++) {
                frame->data[0][y * frame->linesize[0] + x] = x + y + i*3;
            }
        }
        /* Cb and Cr */
        for (int y = 0; y < codec_context->height/2; y++) {
            for (int x = 0; x < codec_context->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(codec_context,frame,&pkt,file);
    }
    /* flush the encoder */
    encode(codec_context,NULL,&pkt,file);
    /* add sequence end code to have a real MPEG file */
    fwrite(endcode,1,sizeof (endcode),file);
    fclose(file);
    avcodec_free_context(&codec_context);
    av_frame_free(&frame);
    return 0;
}
  • build不出现错误之后,点击run,弹出提示信息,需要输入指定的参数
  • 进入终端页面,进入cmake-build-debug文件夹下
  • 使用如下命令进行数据编码 ./learn_ffmpeg 1.h264 libx264
  • 生成1.h264文件
  • 使用ffplay 1.h264 进行播放
  • 本人使用开源软件 PotPlayer进行视频播放 

音视频处理 ffmpeg中级开发 H264编码

音视频处理 ffmpeg中级开发 H264编码

音视频处理 ffmpeg中级开发 H264编码

  •  ffplay 1.h264进行视频播放,输出数据的相关描述信息
  • Stream #0:0: 流的ID
  • 视频流是 h264 high
  • 数据先前的格式是 yuv420p 分辨率是353x288 帧率是25 时间基是25 流的时间基是1200 编码的时间基是 50

音视频处理 ffmpeg中级开发 H264编码文章来源地址https://www.toymoban.com/news/detail-430369.html

到了这里,关于音视频处理 ffmpeg中级开发 H264编码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 音视频知识:MPEG-4、H264、MP4、AAC之间的关系

    MPEG-4 一种编码标准。是国际标准化组织 (ISO) 主要针对消费类应用,已经针对运动图像压缩定义的标准。MPEG(Moving Picture Experts Group)标准包括 MPEG1、MPEG2与 MPEG4。 MPEG-4标准目前分为27个部分,统称为ISO/IEC14496国际标准。其中第10部分(ISO/IEC 14496-10)就是熟悉的高级视频编码

    2024年02月14日
    浏览(68)
  • 音视频八股文(9)-- flv的h264六层结构和aac六层结构

    FLV(Flash Video)是Adobe公司推出的⼀种流媒体格式,由于其封装后的⾳视频⽂件体积⼩、封装简单等特点,⾮常适合于互联⽹上使⽤。⽬前主流的视频⽹站基本都⽀持FLV。采⽤FLV格式封装的⽂件后缀为.flv。 FLV封装格式是由⼀个⽂件头(file header)和 ⽂件体(file Body)组成。其中,FLV

    2024年02月01日
    浏览(66)
  • Qt/C++音视频开发50-不同ffmpeg版本之间的差异处理

    ffmpeg的版本众多,从2010年开始计算的项目的话,基本上还在使用的有ffmpeg2/3/4/5/6,最近几年版本彪的比较厉害,直接4/5/6,大版本之间接口有一些变化,特别是一些废弃接口被彻底删除了,而网络上的各种文章几乎都是ffmpeg3左右为主的,所以本人在写这个全功能播放组件的时

    2024年02月14日
    浏览(56)
  • 音视频 FFmpeg音视频处理流程

    推荐一个零声学院项目课,个人觉得老师讲得不错,分享给大家: 零声白金学习卡(含基础架构/高性能存储/golang云原生/音视频/Linux内核) https://xxetb.xet.tech/s/VsFMs

    2024年02月12日
    浏览(68)
  • 音视频开发 RTMP协议发送H.264编码及AAC编码的音视频(C++实现)

    RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系Flash Player和RtmpServer,如 FMS , Red5 , crtmpserver 等。RTMP协议可用于实现直播、点播应用,通过 FMLE(Flash Media Live Encoder) 推送音

    2023年04月08日
    浏览(78)
  • ffmpeg系列学习——FFmpeg的音视频处理

    1.音视频的采样率、采样位深度和声道数 音频和视频的采样率、采样位深度和声道数是媒体文件中的重要参数,它们会直接影响到音视频的质量和文件大小。下面对它们进行详细解释: 采样率 采样率指音频每秒钟采样的次数,用赫兹(Hz)表示。采样率越高,音频的还原度越

    2024年02月04日
    浏览(63)
  • Android 音视频开发实践系列-06-初步了解H.264视频编解码技术标准

    本文来自笔者本人的语雀博客,由于语雀升级后不再满足笔者的需求,因此之后笔者会陆续将一些之前已经发布但尚有价值的文章搬家到CSDN。 作为音视频行业从业者,怎么能不理解H.264视频编解码技术标准?本篇文章主要记录笔者学习过程中对众多优秀博客内容的摘抄整理,

    2023年04月09日
    浏览(54)
  • [音视频处理] FFmpeg使用指北1-视频解码

    本文将详细介绍如何使用ffmpeg 4.4在C++中解码多种格式的媒体文件,这些媒体文件可以是视频、视频流、图片,或是桌面截屏或USB摄像头的实时图片。解码文件后,还将每帧图片转换为OpenCV的Mat格式以供后续使用。 目录 1 基于ffmpeg的媒体文件解码 1.1 简介 1.2 详细代码 2 ffmpeg函

    2024年02月07日
    浏览(67)
  • FFmpeg音视频处理工具介绍及应用

    FFmpeg项目由 Fabrice Bellard在2000年创立。到目前为止,FFmpeg项目的开发者仍然与VLC、MPV、dav1d、x264等多媒体开源项目有着广泛的重叠。Ffmpeg(FastForward Mpeg)是一款遵循GPL的开源软件,在音视频处理方面表现十分优秀,几乎囊括了现存所有的视音频格式的编码,解码、转码、混合

    2024年02月08日
    浏览(77)
  • JavaCV与FFmpeg:音视频流处理技巧

    1. JavaCV简介 JavaCV是一个开源的Java接口,为OpenCV、FFmpeg和其他类似工具提供了封装。它允许Java开发者直接在他们的应用程序中使用这些强大的本地库,而无需深入了解复杂的本地代码。JavaCV特别适用于处理图像和视频数据,提供了一系列的功能,如图像捕获、处理和视频编解

    2024年02月04日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包