zoukankan      html  css  js  c++  java
  • FFMPEG解码过程

    AVFormatContext* m_pFormatCtx;  


    AVCodecContext * m_pCodecCtx;   

    AVCodec* m_pCodec; 

    AVFrame* m_pFrame; 

    AVPacket m_AVPkt;

    // 注册库
     av_register_all();
     avformat_network_init();  

    //打开文件或者是网络串流
    avformat_open_input(&m_pFormatCtx,pcURL,NULL,NULL);
    /***************************************************************************************/
    在函数avformat_open_input函数中,我们解析错误的网络缠流会出现函数长时间不返回的现象

    要解决这个现象,我们需要在AVFromatContext结构体中为nterrupt_callback.callback赋回调函数,来保证打开流超时的情况下函数avformat_open_input能够正确
    返回错误代码
    回调函数示例:
    int CRtpStreamCtlByFFMpeg::interrupt_cb(LPVOID ctx)
    {
     /*AVFormatContext* formatContext =
      reinterpret_cast<AVFormatContext*>(ctx);*/
    CRtpStreamCtlByFFMpeg:解码类
    // 然后判断程序是否已经获得流信息并开始接收流,也就是判断AVFormatContext中start_time参数是否已经有了大于0的值

     CRtpStreamCtlByFFMpeg* p = (CRtpStreamCtlByFFMpeg*)ctx;

     //timeout after 5 seconds of no activity
     if (p->m_pFormatCtx->start_time < 0)
     {
      p->m_pFormatCtx->start_time = 0;
     }
     if (p->m_pFormatCtx->start_time <= 0 && timeGetTime() - p->m_VideoInfoForShow.nLastTime >5000)
     {
      p->m_count = 0;
      return 1;
     }
     return 0;
    }
    /***************************************************************************************/



    // 查找流的信息,从网络串流中找到我们需要的视频音频流
    avformat_find_stream_info(m_pFormatCtx,NULL)

    // 查找解码解码器
    avcodec_find_decoder(m_pCodecCtx->codec_id)

    // 打开解码器
    avcodec_open2(m_pCodecCtx, m_pCodec,NULL)

    // 为帧申请内存
    m_pFrame = avcodec_alloc_frame();

    // 从文件网络串流中读取数据帧
    av_read_frame(pC->m_pFormatCtx, &AvPkt)

    // 解码,got_picture 的值表示解码是否成功,成功为1,失败为0
     avcodec_decode_video2(m_pCodecCtx, m_pFrame, &got_picture, &avPkt)

    /***************************************************************************************/
    至此,使用FFmpeg打开文件网络串流、接收数据,解码的工作已经全部完成,但要注意的是
    FFMpeg默认解码h264数据位YUV420格式,如果需要将YUV420数据转换到RGB24数据,则需要
    使用sws函数组
    /***************************************************************************************/

    // 首先为一个AVFrame申请内存
    pFrameRGB=avcodec_alloc_frame();

    // 获得YUV420格式帧的大小
    nRGBSize = avpicture_get_size(PIX_FMT_RGB24, m_pCodecCtx->width, m_pCodecCtx->height);

    // 填充新申请的RGB数据帧
    avpicture_fill((AVPicture *)pFrameRGB, out_buffer, PIX_FMT_RGB24, m_pCodecCtx->width, m_pCodecCtx->height);

    // 获得swsContext
    img_convert_ctx = sws_getContext(m_pCodecCtx->width, m_pCodecCtx->height, m_pCodecCtx->pix_fmt,
         m_pCodecCtx->width, m_pCodecCtx->height, PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL); 

    // 转码
    sws_scale(img_convert_ctx, (const uint8_t* const*)m_pFrame->data, m_pFrame->linesize, 0, m_pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); 

    //释放swsContext
    sws_freeContext(img_convert_ctx);     //这一步非常重要,如果不将swsContext释放掉,就会造成内存泄露


    日月更迭,时空变换,我只是一只蜗牛,追寻着最后一刻的灿烂
  • 相关阅读:
    nginx配置404
    js修改浏览器url
    mysql DATE_ADD DATE_SUB
    centos6.5 ssh安全优化,修改默认端口名,禁止root远程登录
    关于mysql varchar 类型的最大长度限制
    IIS7多域名绑定同一物理目录,设置不同默认文档的解决方案
    获取某个数据所在数据列表中的行数 mysql
    安全模式不能删除使用SET SQL_SAFE_UPDATES = 0;
    Failed to run the WC DB work queue associated with 错误的解决
    mysql正则匹配解决查询一个字段是否在另一个字段中
  • 原文地址:https://www.cnblogs.com/TheSnailTowardTheSun/p/4650709.html
Copyright © 2011-2022 走看看