IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> ffmpeg c接口 -> 正文阅读

[C++知识库]ffmpeg c接口

ffmpeg新版本很多接口发生了变化,因此在使用时需要确定自己的版本,在这里使用的版本为2.1。?

在此特别感谢雷博提供的相关文章:FFmpeg_雷霄骅的博客-CSDN博客

  • ffmpeg视频解码

#include <iostream>
#include <stdio.h>
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavformat/avio.h"
#include <libavutil/log.h>
#include <libavutil/timestamp.h>
}

#define ERROR_STR_SIZE 1024

int main() {
  
  int ret = -1;
  int err_code;
  char errors[ERROR_STR_SIZE];
  AVFormatContext *ifmt_ctx = NULL;
  AVCodecContext *pCodecCtx;
  const AVOutputFormat *ofmt = NULL;
  AVStream *in_stream1 = NULL;
  int vedio_stream_indes = 0;
  // 文件最大时长,保证音频和视频数据长度一致
  double max_duration = 0;
  AVPacket *pkt;
  int stream1 = 0, stream2 = 0;
  const char* video = "E:\\jiao\\project\\162300.mp4";
  /*//初始化网络,如果要解封装网络数据格式,则可调用该函数。
  avformat_network_init();*/
  //av_register_all();//高版本已弃用
  //打开输入文件(可解析视频参数)
  ifmt_ctx = avformat_alloc_context();
  if ((err_code = avformat_open_input(&ifmt_ctx, video, 0, 0)) != 0) {
    av_strerror(err_code, errors, ERROR_STR_SIZE);
    return -1;
  }
  if (avformat_find_stream_info(ifmt_ctx, NULL) < 0) {
    printf("Couldn't find stream information.\n");
    return -1;
  }

  // 找到视频流下标
  vedio_stream_indes = -1;
  for (int i = 0; i < ifmt_ctx->nb_streams; i++) {
    if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
      vedio_stream_indes = i;
      break;
    }
  }

  if (vedio_stream_indes == -1) {
    printf("Didn't find a video stream");
    return -1;  
  }
  // 获取文件中的视频流
  in_stream1 = ifmt_ctx->streams[vedio_stream_indes];
  int rate = in_stream1->r_frame_rate.num;   //视频帧率
  int w = in_stream1->codecpar->width;   //视频图像宽
  int h = in_stream1->codecpar->height;   //视频图像高
  if (in_stream1->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
    printf("the input is video.\n");
  }
  //软解码,查找解码器
  const AVCodec *pCodec = avcodec_find_decoder(in_stream1->codecpar->codec_id);
  if (pCodec == NULL) {
    printf("Codec not found.\n");
    return -1;
  }

  //获取编解码器上下文
  pCodecCtx = avcodec_alloc_context3(pCodec);
  if (pCodecCtx == NULL)
  {
    printf("get av codec context failed.\n");
    return -1;
  }
  //设置编解码器上下文参数
  if (avcodec_parameters_to_context(pCodecCtx, in_stream1->codecpar) < 0) {
    printf("set param failed!\n");
    return -1;
  }

  //打开编解码器
  if (avcodec_open2(pCodecCtx, pCodec, NULL) != 0) {
    printf("Could not open codec.\n");
    return -1;
  }
  AVFrame *frame;
  //frame 初始化
  frame = av_frame_alloc();
  pkt = av_packet_alloc();
  int frames = 0;
  while (av_read_frame(ifmt_ctx, pkt)>=0) {

    if (pkt->stream_index == vedio_stream_indes) {
      //解封装,将包发送到解码队列中
      ret = avcodec_send_packet(pCodecCtx, pkt);
      
      if (ret < 0) {
        continue;
      }
      if (ret >= 0) {

        ret = avcodec_receive_frame(pCodecCtx, frame);
        int keyfrmae = frame->key_frame;  //是否为I帧
        printf("keyframe:%d\n", keyfrmae);
        if (ret == 0) {
          frames += 1;
          //printf("decodec sucess.\n");
          printf("frames:%d\n",frames);
        } else {
          printf("receive failed.\n");
        }
      }
    }
    av_packet_unref(pkt);    //必须要有,否则每帧解码av_read_frame都会产生堆内存,造成内存泄漏
  }
  av_free(frame->data);
  avcodec_free_context(&pCodecCtx);
  avformat_free_context(ifmt_ctx);
  av_packet_free(&pkt);
  return 1;

}

视频解码方法在rtsp流解码同样适用。?

  • 添加数据获取方式

AVDictionary *options = NULL;
av_dict_set(&options, "rtsp_transport", "tcp", 0);
avformat_open_input(&ifmt_ctx, rtsp, 0, &options)

使用tcp传输方式获取数据?

  • ffmpeg+opencv

ffmpeg解码出来的图像转为opencv可以使用的Mat类数据 (BGR格式)

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

using namespace cv;

SwsContext *swsContext = sws_getContext(w, h, pCodecCtx->pix_fmt, w, h, AV_PIX_FMT_BGR24,
                     SWS_BICUBIC, NULL, NULL, NULL);
AVFrame *pFrameBGR = NULL;
uint8_t *out_bufferBGR = NULL;
pFrameBGR = av_frame_alloc();

//给pFrameBGR帧加上分配的内存;
out_bufferBGR = new uint8_t[w*h*3];
av_image_fill_arrays(pFrameBGR->data, pFrameBGR->linesize,
                     out_bufferBGR, AV_PIX_FMT_BGR24, w, h, 1);
sws_scale(swsContext, frame->data, frame->linesize, 0,
          pCodecCtx->height, pFrameBGR->data, pFrameBGR->linesize);
Mat img(frame->height, frame->width, CV_8UC3, out_bufferBGR);
imshow("show", img);
waitKey(1);
av_free(pFrameBGR->data);
delete [] out_bufferRGB;    //一定要使用delete[],而不是delete
sws_freeContext(swsContext);    //释放内存
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-31 23:45:54  更:2022-03-31 23:46:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:35:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码